blob: 2499625dbf13d024113d282d46d8112016fb48c1 [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 all 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 HATestClusterRestart:
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 """
49 main.log.report( "ONOS HA test: Restart all ONOS nodes - " +
50 "initialization" )
51 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 Hall8f89dda2015-01-22 16:03:33 -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 Hall6aec96b2015-01-19 14:49:31 -0800134 else:
135 main.log.warn( "Did not pull new code so skipping mvn " +
136 "clean install" )
Jon Hall1b8f54a2015-02-04 13:24:20 -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 = "HAClusterRestart"
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 """
Jon Hall6aec96b2015-01-19 14:49:31 -0800391 # FIXME: we must reinstall intents until we have a persistant
392 # datastore!
Jon Hall73cf9cc2014-11-20 22:28:38 -0800393 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800394 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700395 assert numControllers, "numControllers not defined"
396 assert main, "main not defined"
397 assert utilities.assert_equals, "utilities.assert_equals not defined"
398 assert CLIs, "CLIs not defined"
399 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 main.log.report( "Adding host intents" )
401 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800402
Jon Hall390696c2015-05-05 17:13:41 -0700403 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800404 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800405
Jon Hall6aec96b2015-01-19 14:49:31 -0800406 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700407 main.step( "Install reactive forwarding app" )
408 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
409 utilities.assert_equals( expect=main.TRUE, actual=installResults,
410 onpass="Install fwd successful",
411 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700412
Jon Halla9d26da2015-03-30 16:45:32 -0700413 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700414 threads = []
415 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700416 t = main.Thread( target=CLIs[i].appToIDCheck,
417 name="appToIDCheck-" + str( i ),
418 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700419 threads.append( t )
420 t.start()
421
422 for t in threads:
423 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700424 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700425 if appCheck != main.TRUE:
426 main.log.warn( CLIs[0].apps() )
427 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700428 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
429 onpass="App Ids seem to be correct",
430 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800431
Jon Hall6aec96b2015-01-19 14:49:31 -0800432 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800433 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700434 for i in range(2): # Retry if pingall fails first time
435 time1 = time.time()
436 pingResult = main.Mininet1.pingall()
437 utilities.assert_equals(
438 expect=main.TRUE,
439 actual=pingResult,
440 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700441 onfail="Reactive Pingall failed, " +
442 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700443 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700444 main.log.info( "Time for pingall: %2f seconds" %
445 ( time2 - time1 ) )
446 # timeout for fwd flows
447 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800448 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700449 main.step( "Uninstall reactive forwarding app" )
450 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
451 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
452 onpass="Uninstall fwd successful",
453 onfail="Uninstall fwd failed" )
454 main.step( "Check app ids check" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700455 threads = []
456 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700457 t = main.Thread( target=CLIs[i].appToIDCheck,
458 name="appToIDCheck-" + str( i ),
459 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700460 threads.append( t )
461 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800462
Jon Hall5cfd23c2015-03-19 11:40:57 -0700463 for t in threads:
464 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700465 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700466 if appCheck != main.TRUE:
467 main.log.warn( CLIs[0].apps() )
468 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700469 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
470 onpass="App Ids seem to be correct",
471 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700472
473 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800474 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800475 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800476 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800477 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800478 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800479 for i in range( 8, 18 ):
480 main.log.info( "Adding host intent between h" + str( i ) +
481 " and h" + str( i + 10 ) )
482 host1 = "00:00:00:00:00:" + \
483 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
484 host2 = "00:00:00:00:00:" + \
485 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800486 # NOTE: getHost can return None
487 host1Dict = main.ONOScli1.getHost( host1 )
488 host2Dict = main.ONOScli1.getHost( host2 )
489 host1Id = None
490 host2Id = None
491 if host1Dict and host2Dict:
492 host1Id = host1Dict.get( 'id', None )
493 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800494 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700495 nodeNum = ( i % 7 )
496 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800497 if tmpId:
498 main.log.info( "Added intent with id: " + tmpId )
499 intentIds.append( tmpId )
500 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700501 main.log.error( "addHostIntent returned: " +
502 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800503 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700504 main.log.error( "Error, getHost() failed for h" + str( i ) +
505 " and/or h" + str( i + 10 ) )
506 hosts = CLIs[ 0 ].hosts()
507 main.log.warn( "Hosts output: " )
508 try:
509 main.log.warn( json.dumps( json.loads( hosts ),
510 sort_keys=True,
511 indent=4,
512 separators=( ',', ': ' ) ) )
513 except ( ValueError, TypeError ):
514 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800515 hostResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700516 # FIXME: DEBUG
517 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800518 onosIds = main.ONOScli1.getAllIntentsId()
519 main.log.info( "Submitted intents: " + str( intentIds ) )
520 main.log.info( "Intents in ONOS: " + str( onosIds ) )
521 for intent in intentIds:
522 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700523 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800524 else:
525 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700526 # FIXME: DEBUG
527 if intentAddResult:
528 intentStop = time.time()
529 else:
530 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800531 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800532 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800533 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800534 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800535 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
536 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700537 try:
538 for intent in json.loads( intents ):
539 state = intent.get( 'state', None )
540 if "INSTALLED" not in state:
541 installedCheck = False
542 intentId = intent.get( 'id', None )
543 intentStates.append( ( intentId, state ) )
544 except ( ValueError, TypeError ):
545 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800546 # add submitted intents not in the store
547 tmplist = [ i for i, s in intentStates ]
548 missingIntents = False
549 for i in intentIds:
550 if i not in tmplist:
551 intentStates.append( ( i, " - " ) )
552 missingIntents = True
553 intentStates.sort()
554 for i, s in intentStates:
555 count += 1
556 main.log.info( "%-6s%-15s%-15s" %
557 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700558 leaders = main.ONOScli1.leaders()
559 try:
560 if leaders:
561 parsedLeaders = json.loads( leaders )
562 main.log.warn( json.dumps( parsedLeaders,
563 sort_keys=True,
564 indent=4,
565 separators=( ',', ': ' ) ) )
566 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700567 topics = []
568 for i in range( 14 ):
569 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700570 main.log.debug( topics )
571 ONOStopics = [ j['topic'] for j in parsedLeaders ]
572 for topic in topics:
573 if topic not in ONOStopics:
574 main.log.error( "Error: " + topic +
575 " not in leaders" )
576 else:
577 main.log.error( "leaders() returned None" )
578 except ( ValueError, TypeError ):
579 main.log.exception( "Error parsing leaders" )
580 main.log.error( repr( leaders ) )
581 partitions = main.ONOScli1.partitions()
582 try:
583 if partitions :
584 parsedPartitions = json.loads( partitions )
585 main.log.warn( json.dumps( parsedPartitions,
586 sort_keys=True,
587 indent=4,
588 separators=( ',', ': ' ) ) )
589 # TODO check for a leader in all paritions
590 # TODO check for consistency among nodes
591 else:
592 main.log.error( "partitions() returned None" )
593 except ( ValueError, TypeError ):
594 main.log.exception( "Error parsing partitions" )
595 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800596 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700597 try:
598 if pendingMap :
599 parsedPending = json.loads( pendingMap )
600 main.log.warn( json.dumps( parsedPending,
601 sort_keys=True,
602 indent=4,
603 separators=( ',', ': ' ) ) )
604 # TODO check something here?
605 else:
606 main.log.error( "pendingMap() returned None" )
607 except ( ValueError, TypeError ):
608 main.log.exception( "Error parsing pending map" )
609 main.log.error( repr( pendingMap ) )
610
Jon Hall58c76b72015-02-23 11:09:24 -0800611 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800612 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800613 utilities.assert_equals(
614 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800615 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800616 onpass="Pushed host intents to ONOS",
617 onfail="Error in pushing host intents to ONOS" )
Jon Hall390696c2015-05-05 17:13:41 -0700618 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700619 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700620 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700621 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700622 for cli in CLIs:
623 onosIds = []
624 ids = cli.getAllIntentsId()
625 onosIds.append( ids )
626 main.log.debug( "Intents in " + cli.name + ": " +
627 str( sorted( onosIds ) ) )
628 if sorted( ids ) != sorted( intentIds ):
629 correct = False
630 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700631 break
632 else:
633 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700634 if not intentStop:
635 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700636 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700637 gossipTime = intentStop - intentStart
638 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700639 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700640 # FIXME: make this time configurable/calculate based off of number of
641 # nodes and gossip rounds
642 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700643 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700644 onpass="ECM anti-entropy for intents worked within " +
645 "expected time",
646 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700647 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700648 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800649
Jon Hall63604932015-02-26 17:09:50 -0800650 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800651 import time
Jon Hall63604932015-02-26 17:09:50 -0800652 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800653 main.log.info( "Sleeping 60 seconds to see if intents are found" )
654 time.sleep( 60 )
655 onosIds = main.ONOScli1.getAllIntentsId()
656 main.log.info( "Submitted intents: " + str( intentIds ) )
657 main.log.info( "Intents in ONOS: " + str( onosIds ) )
658 # Print the intent states
659 intents = main.ONOScli1.intents()
660 intentStates = []
661 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
662 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700663 try:
664 for intent in json.loads( intents ):
665 # Iter through intents of a node
666 state = intent.get( 'state', None )
667 if "INSTALLED" not in state:
668 installedCheck = False
669 intentId = intent.get( 'id', None )
670 intentStates.append( ( intentId, state ) )
671 except ( ValueError, TypeError ):
672 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800673 # add submitted intents not in the store
674 tmplist = [ i for i, s in intentStates ]
675 for i in intentIds:
676 if i not in tmplist:
677 intentStates.append( ( i, " - " ) )
678 intentStates.sort()
679 for i, s in intentStates:
680 count += 1
681 main.log.info( "%-6s%-15s%-15s" %
682 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700683 leaders = main.ONOScli1.leaders()
684 try:
685 if leaders:
686 parsedLeaders = json.loads( leaders )
687 main.log.warn( json.dumps( parsedLeaders,
688 sort_keys=True,
689 indent=4,
690 separators=( ',', ': ' ) ) )
691 # check for all intent partitions
692 # check for election
693 topics = []
694 for i in range( 14 ):
695 topics.append( "intent-partition-" + str( i ) )
696 # FIXME: this should only be after we start the app
697 topics.append( "org.onosproject.election" )
698 main.log.debug( topics )
699 ONOStopics = [ j['topic'] for j in parsedLeaders ]
700 for topic in topics:
701 if topic not in ONOStopics:
702 main.log.error( "Error: " + topic +
703 " not in leaders" )
704 else:
705 main.log.error( "leaders() returned None" )
706 except ( ValueError, TypeError ):
707 main.log.exception( "Error parsing leaders" )
708 main.log.error( repr( leaders ) )
709 partitions = main.ONOScli1.partitions()
710 try:
711 if partitions :
712 parsedPartitions = json.loads( partitions )
713 main.log.warn( json.dumps( parsedPartitions,
714 sort_keys=True,
715 indent=4,
716 separators=( ',', ': ' ) ) )
717 # TODO check for a leader in all paritions
718 # TODO check for consistency among nodes
719 else:
720 main.log.error( "partitions() returned None" )
721 except ( ValueError, TypeError ):
722 main.log.exception( "Error parsing partitions" )
723 main.log.error( repr( partitions ) )
724 pendingMap = main.ONOScli1.pendingMap()
725 try:
726 if pendingMap :
727 parsedPending = json.loads( pendingMap )
728 main.log.warn( json.dumps( parsedPending,
729 sort_keys=True,
730 indent=4,
731 separators=( ',', ': ' ) ) )
732 # TODO check something here?
733 else:
734 main.log.error( "pendingMap() returned None" )
735 except ( ValueError, TypeError ):
736 main.log.exception( "Error parsing pending map" )
737 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800738
Jon Hall6aec96b2015-01-19 14:49:31 -0800739 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800740 """
741 Ping across added host intents
742 """
Jon Hall58c76b72015-02-23 11:09:24 -0800743 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700744 import time
745 assert numControllers, "numControllers not defined"
746 assert main, "main not defined"
747 assert utilities.assert_equals, "utilities.assert_equals not defined"
748 assert CLIs, "CLIs not defined"
749 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800750 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800751 main.log.report( description )
752 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800753 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800754 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800755 ping = main.Mininet1.pingHost( src="h" + str( i ),
756 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800757 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800758 if ping == main.FALSE:
759 main.log.warn( "Ping failed between h" + str( i ) +
760 " and h" + str( i + 10 ) )
761 elif ping == main.TRUE:
762 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800763 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800764 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800765 main.log.report(
766 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800767 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700768 main.log.warn( "ONOS1 intents: " )
769 try:
770 tmpIntents = main.ONOScli1.intents()
771 main.log.warn( json.dumps( json.loads( tmpIntents ),
772 sort_keys=True,
773 indent=4,
774 separators=( ',', ': ' ) ) )
775 except ( ValueError, TypeError ):
776 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800777 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800778 main.log.report(
779 "Intents have been installed correctly and verified by pings" )
780 utilities.assert_equals(
781 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800782 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800783 onpass="Intents have been installed correctly and pings work",
784 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800785
Jon Hall63604932015-02-26 17:09:50 -0800786 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800787 if PingResult is not main.TRUE:
788 # Print the intent states
789 intents = main.ONOScli1.intents()
790 intentStates = []
791 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
792 count = 0
793 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700794 try:
795 for intent in json.loads( intents ):
796 state = intent.get( 'state', None )
797 if "INSTALLED" not in state:
798 installedCheck = False
799 intentId = intent.get( 'id', None )
800 intentStates.append( ( intentId, state ) )
801 except ( ValueError, TypeError ):
802 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800803 intentStates.sort()
804 for i, s in intentStates:
805 count += 1
806 main.log.info( "%-6s%-15s%-15s" %
807 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700808 leaders = main.ONOScli1.leaders()
809 try:
810 if leaders:
811 parsedLeaders = json.loads( leaders )
812 main.log.warn( json.dumps( parsedLeaders,
813 sort_keys=True,
814 indent=4,
815 separators=( ',', ': ' ) ) )
816 # check for all intent partitions
817 # check for election
818 topics = []
819 for i in range( 14 ):
820 topics.append( "intent-partition-" + str( i ) )
821 # FIXME: this should only be after we start the app
822 topics.append( "org.onosproject.election" )
823 main.log.debug( topics )
824 ONOStopics = [ j['topic'] for j in parsedLeaders ]
825 for topic in topics:
826 if topic not in ONOStopics:
827 main.log.error( "Error: " + topic +
828 " not in leaders" )
829 else:
830 main.log.error( "leaders() returned None" )
831 except ( ValueError, TypeError ):
832 main.log.exception( "Error parsing leaders" )
833 main.log.error( repr( leaders ) )
834 partitions = main.ONOScli1.partitions()
835 try:
836 if partitions :
837 parsedPartitions = json.loads( partitions )
838 main.log.warn( json.dumps( parsedPartitions,
839 sort_keys=True,
840 indent=4,
841 separators=( ',', ': ' ) ) )
842 # TODO check for a leader in all paritions
843 # TODO check for consistency among nodes
844 else:
845 main.log.error( "partitions() returned None" )
846 except ( ValueError, TypeError ):
847 main.log.exception( "Error parsing partitions" )
848 main.log.error( repr( partitions ) )
849 pendingMap = main.ONOScli1.pendingMap()
850 try:
851 if pendingMap :
852 parsedPending = json.loads( pendingMap )
853 main.log.warn( json.dumps( parsedPending,
854 sort_keys=True,
855 indent=4,
856 separators=( ',', ': ' ) ) )
857 # TODO check something here?
858 else:
859 main.log.error( "pendingMap() returned None" )
860 except ( ValueError, TypeError ):
861 main.log.exception( "Error parsing pending map" )
862 main.log.error( repr( pendingMap ) )
863
Jon Hall63604932015-02-26 17:09:50 -0800864 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700865 main.log.info( "Waiting 60 seconds to see if the state of " +
866 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800867 time.sleep( 60 )
868 # Print the intent states
869 intents = main.ONOScli1.intents()
870 intentStates = []
871 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
872 count = 0
873 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700874 try:
875 for intent in json.loads( intents ):
876 state = intent.get( 'state', None )
877 if "INSTALLED" not in state:
878 installedCheck = False
879 intentId = intent.get( 'id', None )
880 intentStates.append( ( intentId, state ) )
881 except ( ValueError, TypeError ):
882 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800883 intentStates.sort()
884 for i, s in intentStates:
885 count += 1
886 main.log.info( "%-6s%-15s%-15s" %
887 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700888 leaders = main.ONOScli1.leaders()
889 try:
890 if leaders:
891 parsedLeaders = json.loads( leaders )
892 main.log.warn( json.dumps( parsedLeaders,
893 sort_keys=True,
894 indent=4,
895 separators=( ',', ': ' ) ) )
896 # check for all intent partitions
897 # check for election
898 topics = []
899 for i in range( 14 ):
900 topics.append( "intent-partition-" + str( i ) )
901 # FIXME: this should only be after we start the app
902 topics.append( "org.onosproject.election" )
903 main.log.debug( topics )
904 ONOStopics = [ j['topic'] for j in parsedLeaders ]
905 for topic in topics:
906 if topic not in ONOStopics:
907 main.log.error( "Error: " + topic +
908 " not in leaders" )
909 else:
910 main.log.error( "leaders() returned None" )
911 except ( ValueError, TypeError ):
912 main.log.exception( "Error parsing leaders" )
913 main.log.error( repr( leaders ) )
914 partitions = main.ONOScli1.partitions()
915 try:
916 if partitions :
917 parsedPartitions = json.loads( partitions )
918 main.log.warn( json.dumps( parsedPartitions,
919 sort_keys=True,
920 indent=4,
921 separators=( ',', ': ' ) ) )
922 # TODO check for a leader in all paritions
923 # TODO check for consistency among nodes
924 else:
925 main.log.error( "partitions() returned None" )
926 except ( ValueError, TypeError ):
927 main.log.exception( "Error parsing partitions" )
928 main.log.error( repr( partitions ) )
929 pendingMap = main.ONOScli1.pendingMap()
930 try:
931 if pendingMap :
932 parsedPending = json.loads( pendingMap )
933 main.log.warn( json.dumps( parsedPending,
934 sort_keys=True,
935 indent=4,
936 separators=( ',', ': ' ) ) )
937 # TODO check something here?
938 else:
939 main.log.error( "pendingMap() returned None" )
940 except ( ValueError, TypeError ):
941 main.log.exception( "Error parsing pending map" )
942 main.log.error( repr( pendingMap ) )
Jon Hall390696c2015-05-05 17:13:41 -0700943 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800944
Jon Hall6aec96b2015-01-19 14:49:31 -0800945 def CASE5( self, main ):
946 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800947 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800948 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800949 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700950 import time
951 assert numControllers, "numControllers not defined"
952 assert main, "main not defined"
953 assert utilities.assert_equals, "utilities.assert_equals not defined"
954 assert CLIs, "CLIs not defined"
955 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800956 # assumes that sts is already in you PYTHONPATH
957 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800958
Jon Hall6aec96b2015-01-19 14:49:31 -0800959 main.log.report( "Setting up and gathering data for current state" )
960 main.case( "Setting up and gathering data for current state" )
961 # The general idea for this test case is to pull the state of
962 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700963 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800964
Jon Hall5cfd23c2015-03-19 11:40:57 -0700965 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800966 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700967 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800968
Jon Hall6aec96b2015-01-19 14:49:31 -0800969 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700970 rolesNotNull = main.TRUE
971 threads = []
972 for i in range( numControllers ):
973 t = main.Thread( target=CLIs[i].rolesNotNull,
974 name="rolesNotNull-" + str( i ),
975 args=[] )
976 threads.append( t )
977 t.start()
978
979 for t in threads:
980 t.join()
981 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800982 utilities.assert_equals(
983 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800984 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800985 onpass="Each device has a master",
986 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800987
Jon Hall5cfd23c2015-03-19 11:40:57 -0700988 main.step( "Get the Mastership of each switch from each controller" )
989 ONOSMastership = []
990 mastershipCheck = main.FALSE
991 consistentMastership = True
992 rolesResults = True
993 threads = []
994 for i in range( numControllers ):
995 t = main.Thread( target=CLIs[i].roles,
996 name="roles-" + str( i ),
997 args=[] )
998 threads.append( t )
999 t.start()
1000
1001 for t in threads:
1002 t.join()
1003 ONOSMastership.append( t.result )
1004
1005 for i in range( numControllers ):
1006 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1007 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1008 " roles" )
1009 main.log.warn(
1010 "ONOS" + str( i + 1 ) + " mastership response: " +
1011 repr( ONOSMastership[i] ) )
1012 rolesResults = False
1013 utilities.assert_equals(
1014 expect=True,
1015 actual=rolesResults,
1016 onpass="No error in reading roles output",
1017 onfail="Error in reading roles from ONOS" )
1018
1019 main.step( "Check for consistency in roles from each controller" )
1020 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001021 main.log.report(
1022 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001023 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001024 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001025 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001026 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001027 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001028 onpass="Switch roles are consistent across all ONOS nodes",
1029 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001030
Jon Hall5cfd23c2015-03-19 11:40:57 -07001031 if rolesResults and not consistentMastership:
1032 for i in range( numControllers ):
1033 try:
1034 main.log.warn(
1035 "ONOS" + str( i + 1 ) + " roles: ",
1036 json.dumps(
1037 json.loads( ONOSMastership[ i ] ),
1038 sort_keys=True,
1039 indent=4,
1040 separators=( ',', ': ' ) ) )
1041 except ( ValueError, TypeError ):
1042 main.log.warn( repr( ONOSMastership[ i ] ) )
1043 elif rolesResults and consistentMastership:
1044 mastershipCheck = main.TRUE
1045 mastershipState = ONOSMastership[ 0 ]
1046
Jon Hall6aec96b2015-01-19 14:49:31 -08001047 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001048 global intentState
1049 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001050 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001051 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001052 consistentIntents = True
1053 intentsResults = True
1054 threads = []
1055 for i in range( numControllers ):
1056 t = main.Thread( target=CLIs[i].intents,
1057 name="intents-" + str( i ),
1058 args=[],
1059 kwargs={ 'jsonFormat': True } )
1060 threads.append( t )
1061 t.start()
1062
1063 for t in threads:
1064 t.join()
1065 ONOSIntents.append( t.result )
1066
1067 for i in range( numControllers ):
1068 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1069 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1070 " intents" )
1071 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1072 repr( ONOSIntents[ i ] ) )
1073 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001074 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001075 expect=True,
1076 actual=intentsResults,
1077 onpass="No error in reading intents output",
1078 onfail="Error in reading intents from ONOS" )
1079
1080 main.step( "Check for consistency in Intents from each controller" )
1081 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1082 main.log.report( "Intents are consistent across all ONOS " +
1083 "nodes" )
1084 else:
1085 consistentIntents = False
1086 main.log.report( "Intents not consistent" )
1087 utilities.assert_equals(
1088 expect=True,
1089 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001090 onpass="Intents are consistent across all ONOS nodes",
1091 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001092
Jon Hall390696c2015-05-05 17:13:41 -07001093 if intentsResults:
1094 # Try to make it easy to figure out what is happening
1095 #
1096 # Intent ONOS1 ONOS2 ...
1097 # 0x01 INSTALLED INSTALLING
1098 # ... ... ...
1099 # ... ... ...
1100 title = " Id"
1101 for n in range( numControllers ):
1102 title += " " * 10 + "ONOS" + str( n + 1 )
1103 main.log.warn( title )
1104 # get all intent keys in the cluster
1105 keys = []
1106 for nodeStr in ONOSIntents:
1107 node = json.loads( nodeStr )
1108 for intent in node:
1109 keys.append( intent.get( 'id' ) )
1110 keys = set( keys )
1111 for key in keys:
1112 row = "%-13s" % key
1113 for nodeStr in ONOSIntents:
1114 node = json.loads( nodeStr )
1115 for intent in node:
1116 if intent.get( 'id', "Error" ) == key:
1117 row += "%-15s" % intent.get( 'state' )
1118 main.log.warn( row )
1119 # End table view
1120
Jon Hall5cfd23c2015-03-19 11:40:57 -07001121 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001122 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001123 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001124 main.log.debug( "ONOS" + str( n ) + " intents: " )
1125 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1126 sort_keys=True,
1127 indent=4,
1128 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001129 for i in range( numControllers ):
1130 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001131 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1132 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1133 sort_keys=True,
1134 indent=4,
1135 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001136 else:
Jon Hall390696c2015-05-05 17:13:41 -07001137 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1138 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001139 elif intentsResults and consistentIntents:
1140 intentCheck = main.TRUE
1141 intentState = ONOSIntents[ 0 ]
1142
Jon Hall6aec96b2015-01-19 14:49:31 -08001143 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001144 global flowState
1145 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001146 ONOSFlows = []
1147 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001148 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001149 consistentFlows = True
1150 flowsResults = True
1151 threads = []
1152 for i in range( numControllers ):
1153 t = main.Thread( target=CLIs[i].flows,
1154 name="flows-" + str( i ),
1155 args=[],
1156 kwargs={ 'jsonFormat': True } )
1157 threads.append( t )
1158 t.start()
1159
Jon Halla9d26da2015-03-30 16:45:32 -07001160 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001161 time.sleep(30)
1162 for t in threads:
1163 t.join()
1164 result = t.result
1165 ONOSFlows.append( result )
1166
1167 for i in range( numControllers ):
1168 num = str( i + 1 )
1169 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1170 main.log.report( "Error in getting ONOS" + num + " flows" )
1171 main.log.warn( "ONOS" + num + " flows response: " +
1172 repr( ONOSFlows[ i ] ) )
1173 flowsResults = False
1174 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001175 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001176 try:
1177 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1178 except ( ValueError, TypeError ):
1179 # FIXME: change this to log.error?
1180 main.log.exception( "Error in parsing ONOS" + num +
1181 " response as json." )
1182 main.log.error( repr( ONOSFlows[ i ] ) )
1183 ONOSFlowsJson.append( None )
1184 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001185 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001186 expect=True,
1187 actual=flowsResults,
1188 onpass="No error in reading flows output",
1189 onfail="Error in reading flows from ONOS" )
1190
1191 main.step( "Check for consistency in Flows from each controller" )
1192 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1193 if all( tmp ):
1194 main.log.report( "Flow count is consistent across all ONOS nodes" )
1195 else:
1196 consistentFlows = False
1197 utilities.assert_equals(
1198 expect=True,
1199 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001200 onpass="The flow count is consistent across all ONOS nodes",
1201 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001202
Jon Hall5cfd23c2015-03-19 11:40:57 -07001203 if flowsResults and not consistentFlows:
1204 for i in range( numControllers ):
1205 try:
1206 main.log.warn(
1207 "ONOS" + str( i + 1 ) + " flows: " +
1208 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1209 indent=4, separators=( ',', ': ' ) ) )
1210 except ( ValueError, TypeError ):
1211 main.log.warn(
1212 "ONOS" + str( i + 1 ) + " flows: " +
1213 repr( ONOSFlows[ i ] ) )
1214 elif flowsResults and consistentFlows:
1215 flowCheck = main.TRUE
1216 flowState = ONOSFlows[ 0 ]
1217
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001219 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001220 flows = []
1221 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001222 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001223 if flowCheck == main.FALSE:
1224 for table in flows:
1225 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001226 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001227
Jon Hall6aec96b2015-01-19 14:49:31 -08001228 main.step( "Start continuous pings" )
1229 main.Mininet2.pingLong(
1230 src=main.params[ 'PING' ][ 'source1' ],
1231 target=main.params[ 'PING' ][ 'target1' ],
1232 pingTime=500 )
1233 main.Mininet2.pingLong(
1234 src=main.params[ 'PING' ][ 'source2' ],
1235 target=main.params[ 'PING' ][ 'target2' ],
1236 pingTime=500 )
1237 main.Mininet2.pingLong(
1238 src=main.params[ 'PING' ][ 'source3' ],
1239 target=main.params[ 'PING' ][ 'target3' ],
1240 pingTime=500 )
1241 main.Mininet2.pingLong(
1242 src=main.params[ 'PING' ][ 'source4' ],
1243 target=main.params[ 'PING' ][ 'target4' ],
1244 pingTime=500 )
1245 main.Mininet2.pingLong(
1246 src=main.params[ 'PING' ][ 'source5' ],
1247 target=main.params[ 'PING' ][ 'target5' ],
1248 pingTime=500 )
1249 main.Mininet2.pingLong(
1250 src=main.params[ 'PING' ][ 'source6' ],
1251 target=main.params[ 'PING' ][ 'target6' ],
1252 pingTime=500 )
1253 main.Mininet2.pingLong(
1254 src=main.params[ 'PING' ][ 'source7' ],
1255 target=main.params[ 'PING' ][ 'target7' ],
1256 pingTime=500 )
1257 main.Mininet2.pingLong(
1258 src=main.params[ 'PING' ][ 'source8' ],
1259 target=main.params[ 'PING' ][ 'target8' ],
1260 pingTime=500 )
1261 main.Mininet2.pingLong(
1262 src=main.params[ 'PING' ][ 'source9' ],
1263 target=main.params[ 'PING' ][ 'target9' ],
1264 pingTime=500 )
1265 main.Mininet2.pingLong(
1266 src=main.params[ 'PING' ][ 'source10' ],
1267 target=main.params[ 'PING' ][ 'target10' ],
1268 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001269
Jon Hall6aec96b2015-01-19 14:49:31 -08001270 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001271 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001272 for node in nodes:
1273 temp = ( node, node.name, node.ip_address, 6633 )
1274 ctrls.append( temp )
1275 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001276
Jon Hall6aec96b2015-01-19 14:49:31 -08001277 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001278 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001279 threads = []
1280 for i in range( numControllers ):
1281 t = main.Thread( target=CLIs[i].devices,
1282 name="devices-" + str( i ),
1283 args=[ ] )
1284 threads.append( t )
1285 t.start()
1286
1287 for t in threads:
1288 t.join()
1289 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001290 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001291 threads = []
1292 for i in range( numControllers ):
1293 t = main.Thread( target=CLIs[i].hosts,
1294 name="hosts-" + str( i ),
1295 args=[ ] )
1296 threads.append( t )
1297 t.start()
1298
1299 for t in threads:
1300 t.join()
1301 try:
1302 hosts.append( json.loads( t.result ) )
1303 except ( ValueError, TypeError ):
1304 # FIXME: better handling of this, print which node
1305 # Maybe use thread name?
1306 main.log.exception( "Error parsing json output of hosts" )
1307 # FIXME: should this be an empty json object instead?
1308 hosts.append( None )
1309
Jon Hall73cf9cc2014-11-20 22:28:38 -08001310 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001311 threads = []
1312 for i in range( numControllers ):
1313 t = main.Thread( target=CLIs[i].ports,
1314 name="ports-" + str( i ),
1315 args=[ ] )
1316 threads.append( t )
1317 t.start()
1318
1319 for t in threads:
1320 t.join()
1321 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001322 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001323 threads = []
1324 for i in range( numControllers ):
1325 t = main.Thread( target=CLIs[i].links,
1326 name="links-" + str( i ),
1327 args=[ ] )
1328 threads.append( t )
1329 t.start()
1330
1331 for t in threads:
1332 t.join()
1333 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001334 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001335 threads = []
1336 for i in range( numControllers ):
1337 t = main.Thread( target=CLIs[i].clusters,
1338 name="clusters-" + str( i ),
1339 args=[ ] )
1340 threads.append( t )
1341 t.start()
1342
1343 for t in threads:
1344 t.join()
1345 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001346 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001347
Jon Hall6aec96b2015-01-19 14:49:31 -08001348 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001349 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001350 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001351 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001352 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001353 if "Error" not in hosts[ controller ]:
1354 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001355 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001356 else: # hosts not consistent
1357 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001358 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001359 " is inconsistent with ONOS1" )
1360 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001361 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001362
1363 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001364 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001365 controllerStr )
1366 consistentHostsResult = main.FALSE
1367 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001368 " hosts response: " +
1369 repr( hosts[ controller ] ) )
1370 utilities.assert_equals(
1371 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001372 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001373 onpass="Hosts view is consistent across all ONOS nodes",
1374 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001375
Jon Hall390696c2015-05-05 17:13:41 -07001376 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001377 ipResult = main.TRUE
1378 for controller in range( 0, len( hosts ) ):
1379 controllerStr = str( controller + 1 )
1380 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001381 if not host.get( 'ips', [ ] ):
1382 main.log.error( "DEBUG:Error with host ips on controller" +
1383 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001384 ipResult = main.FALSE
1385 utilities.assert_equals(
1386 expect=main.TRUE,
1387 actual=ipResult,
1388 onpass="The ips of the hosts aren't empty",
1389 onfail="The ip of at least one host is missing" )
1390
Jon Hall6aec96b2015-01-19 14:49:31 -08001391 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001392 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001393 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001394 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001395 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001396 if "Error" not in clusters[ controller ]:
1397 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001398 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001399 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001400 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001401 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001402 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001403
1404 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001405 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001406 "from ONOS" + controllerStr )
1407 consistentClustersResult = main.FALSE
1408 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001409 " clusters response: " +
1410 repr( clusters[ controller ] ) )
1411 utilities.assert_equals(
1412 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001413 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001414 onpass="Clusters view is consistent across all ONOS nodes",
1415 onfail="ONOS nodes have different views of clusters" )
1416 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001417 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001418 try:
1419 numClusters = len( json.loads( clusters[ 0 ] ) )
1420 except ( ValueError, TypeError ):
1421 main.log.exception( "Error parsing clusters[0]: " +
1422 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001423 clusterResults = main.FALSE
1424 if numClusters == 1:
1425 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001426 utilities.assert_equals(
1427 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001428 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001429 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001430 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001431
Jon Hall6aec96b2015-01-19 14:49:31 -08001432 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001433 devicesResults = main.TRUE
1434 portsResults = main.TRUE
1435 linksResults = main.TRUE
1436 for controller in range( numControllers ):
1437 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001438 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001439 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001440 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001441 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001442 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001443 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001444 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001445 actual=currentDevicesResult,
1446 onpass="ONOS" + controllerStr +
1447 " Switches view is correct",
1448 onfail="ONOS" + controllerStr +
1449 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001450
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001452 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001453 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001454 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001455 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001456 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001457 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001458 actual=currentPortsResult,
1459 onpass="ONOS" + controllerStr +
1460 " ports view is correct",
1461 onfail="ONOS" + controllerStr +
1462 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001463
Jon Hall6aec96b2015-01-19 14:49:31 -08001464 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001465 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001466 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001467 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001468 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001469 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001470 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001471 actual=currentLinksResult,
1472 onpass="ONOS" + controllerStr +
1473 " links view is correct",
1474 onfail="ONOS" + controllerStr +
1475 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001476
Jon Hall8f89dda2015-01-22 16:03:33 -08001477 devicesResults = devicesResults and currentDevicesResult
1478 portsResults = portsResults and currentPortsResult
1479 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001480
Jon Hall5cfd23c2015-03-19 11:40:57 -07001481 topoResult = ( devicesResults and portsResults and linksResults
1482 and consistentHostsResult and consistentClustersResult
1483 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001484 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001485 onpass="Topology Check Test successful",
1486 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001487
Jon Hall6aec96b2015-01-19 14:49:31 -08001488 def CASE6( self, main ):
1489 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001490 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001491 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07001492 assert numControllers, "numControllers not defined"
1493 assert main, "main not defined"
1494 assert utilities.assert_equals, "utilities.assert_equals not defined"
1495 assert CLIs, "CLIs not defined"
1496 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001497
1498 # Reset non-persistent variables
1499 try:
1500 iCounterValue = 0
1501 except NameError:
1502 main.log.error( "iCounterValue not defined, setting to 0" )
1503 iCounterValue = 0
1504
Jon Hall5cfd23c2015-03-19 11:40:57 -07001505 main.case( "Restart entire ONOS cluster" )
1506 main.step( "Killing ONOS nodes" )
1507 killResults = main.TRUE
1508 for node in nodes:
1509 killed = main.ONOSbench.onosKill( node.ip_address )
1510 killResults = killResults and killed
Jon Hall390696c2015-05-05 17:13:41 -07001511 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1512 onpass="ONOS nodes killed",
1513 onfail="ONOS kill unsuccessful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001514
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001516 for i in range( 2 ):
1517 onosIsupResult = main.TRUE
1518 for node in nodes:
1519 started = main.ONOSbench.isup( node.ip_address )
1520 if not started:
1521 main.log.report( node.name + " didn't start!" )
1522 onosIsupResult = onosIsupResult and started
1523 if onosIsupResult == main.TRUE:
1524 break
Jon Hall390696c2015-05-05 17:13:41 -07001525 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1526 onpass="ONOS restarted",
1527 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001528
Jon Hall5cfd23c2015-03-19 11:40:57 -07001529 main.log.step( "Starting ONOS CLI sessions" )
1530 cliResults = main.TRUE
1531 threads = []
1532 for i in range( numControllers ):
1533 t = main.Thread( target=CLIs[i].startOnosCli,
1534 name="startOnosCli-" + str( i ),
1535 args=[nodes[i].ip_address] )
1536 threads.append( t )
1537 t.start()
1538
1539 for t in threads:
1540 t.join()
1541 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -07001542 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1543 onpass="ONOS cli started",
1544 onfail="ONOS clis did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001545
Jon Hall6aec96b2015-01-19 14:49:31 -08001546 def CASE7( self, main ):
1547 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001548 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001549 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001550 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001551 assert numControllers, "numControllers not defined"
1552 assert main, "main not defined"
1553 assert utilities.assert_equals, "utilities.assert_equals not defined"
1554 assert CLIs, "CLIs not defined"
1555 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001557
Jon Hall5cfd23c2015-03-19 11:40:57 -07001558 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001559 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001560 rolesNotNull = main.TRUE
1561 threads = []
1562 for i in range( numControllers ):
1563 t = main.Thread( target=CLIs[i].rolesNotNull,
1564 name="rolesNotNull-" + str( i ),
1565 args=[ ] )
1566 threads.append( t )
1567 t.start()
1568
1569 for t in threads:
1570 t.join()
1571 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001572 utilities.assert_equals(
1573 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001574 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001575 onpass="Each device has a master",
1576 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001577
Jon Hall390696c2015-05-05 17:13:41 -07001578 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001579 ONOSMastership = []
1580 mastershipCheck = main.FALSE
1581 consistentMastership = True
1582 rolesResults = True
1583 threads = []
1584 for i in range( numControllers ):
1585 t = main.Thread( target=CLIs[i].roles,
1586 name="roles-" + str( i ),
1587 args=[] )
1588 threads.append( t )
1589 t.start()
1590
1591 for t in threads:
1592 t.join()
1593 ONOSMastership.append( t.result )
1594
1595 for i in range( numControllers ):
1596 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1597 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1598 " roles" )
1599 main.log.warn(
1600 "ONOS" + str( i + 1 ) + " mastership response: " +
1601 repr( ONOSMastership[i] ) )
1602 rolesResults = False
1603 utilities.assert_equals(
1604 expect=True,
1605 actual=rolesResults,
1606 onpass="No error in reading roles output",
1607 onfail="Error in reading roles from ONOS" )
1608
1609 main.step( "Check for consistency in roles from each controller" )
1610 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001611 main.log.report(
1612 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001613 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001614 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001615 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001616 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001617 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001618 onpass="Switch roles are consistent across all ONOS nodes",
1619 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001620
Jon Hall5cfd23c2015-03-19 11:40:57 -07001621 if rolesResults and not consistentMastership:
1622 for i in range( numControllers ):
1623 main.log.warn(
1624 "ONOS" + str( i + 1 ) + " roles: ",
1625 json.dumps(
1626 json.loads( ONOSMastership[ i ] ),
1627 sort_keys=True,
1628 indent=4,
1629 separators=( ',', ': ' ) ) )
1630 elif rolesResults and not consistentMastership:
1631 mastershipCheck = main.TRUE
1632
Jon Hall73cf9cc2014-11-20 22:28:38 -08001633 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001634 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001635 try:
1636 currentJson = json.loads( ONOSMastership[0] )
1637 oldJson = json.loads( mastershipState )
1638 except ( ValueError, TypeError ):
1639 main.log.exception( "Something is wrong with parsing " +
1640 "ONOSMastership[0] or mastershipState" )
1641 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1642 main.log.error( "mastershipState" + repr( mastershipState ) )
1643 main.cleanup()
1644 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001645 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001646 for i in range( 1, 29 ):
1647 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001648 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001649 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001650 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001651 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001652 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001653 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001654 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001655 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001656 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001657 mastershipCheck = main.FALSE
1658 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001659 main.log.report( "Mastership of Switches was not changed" )
1660 utilities.assert_equals(
1661 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001662 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001663 onpass="Mastership of Switches was not changed",
1664 onfail="Mastership of some switches changed" )
1665 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001666 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001667
Jon Hall6aec96b2015-01-19 14:49:31 -08001668 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001669 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001670 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001671 consistentIntents = True
1672 intentsResults = True
1673 threads = []
1674 for i in range( numControllers ):
1675 t = main.Thread( target=CLIs[i].intents,
1676 name="intents-" + str( i ),
1677 args=[],
1678 kwargs={ 'jsonFormat': True } )
1679 threads.append( t )
1680 t.start()
1681
1682 for t in threads:
1683 t.join()
1684 ONOSIntents.append( t.result )
1685
1686 for i in range( numControllers ):
1687 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1688 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1689 " intents" )
1690 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1691 repr( ONOSIntents[ i ] ) )
1692 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001693 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001694 expect=True,
1695 actual=intentsResults,
1696 onpass="No error in reading intents output",
1697 onfail="Error in reading intents from ONOS" )
1698
1699 main.step( "Check for consistency in Intents from each controller" )
1700 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1701 main.log.report( "Intents are consistent across all ONOS " +
1702 "nodes" )
1703 else:
1704 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001705
1706 # Try to make it easy to figure out what is happening
1707 #
1708 # Intent ONOS1 ONOS2 ...
1709 # 0x01 INSTALLED INSTALLING
1710 # ... ... ...
1711 # ... ... ...
1712 title = " ID"
1713 for n in range( numControllers ):
1714 title += " " * 10 + "ONOS" + str( n + 1 )
1715 main.log.warn( title )
1716 # get all intent keys in the cluster
1717 keys = []
1718 for nodeStr in ONOSIntents:
1719 node = json.loads( nodeStr )
1720 for intent in node:
1721 keys.append( intent.get( 'id' ) )
1722 keys = set( keys )
1723 for key in keys:
1724 row = "%-13s" % key
1725 for nodeStr in ONOSIntents:
1726 node = json.loads( nodeStr )
1727 for intent in node:
1728 if intent.get( 'id' ) == key:
1729 row += "%-15s" % intent.get( 'state' )
1730 main.log.warn( row )
1731 # End table view
1732
Jon Hall5cfd23c2015-03-19 11:40:57 -07001733 utilities.assert_equals(
1734 expect=True,
1735 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001736 onpass="Intents are consistent across all ONOS nodes",
1737 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001738 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001739 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001740 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001741 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001742 try:
1743 for intent in json.loads( node ):
1744 nodeStates.append( intent[ 'state' ] )
1745 except ( ValueError, TypeError ):
1746 main.log.exception( "Error in parsing intents" )
1747 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001748 intentStates.append( nodeStates )
1749 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1750 main.log.info( dict( out ) )
1751
Jon Hall5cfd23c2015-03-19 11:40:57 -07001752 if intentsResults and not consistentIntents:
1753 for i in range( numControllers ):
1754 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1755 main.log.warn( json.dumps(
1756 json.loads( ONOSIntents[ i ] ),
1757 sort_keys=True,
1758 indent=4,
1759 separators=( ',', ': ' ) ) )
1760 elif intentsResults and consistentIntents:
1761 intentCheck = main.TRUE
1762
Jon Hall58c76b72015-02-23 11:09:24 -08001763 # NOTE: Store has no durability, so intents are lost across system
1764 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001765 """
1766 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001767 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001768 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001769 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001770 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001771 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001772 main.log.report( "Intents are consistent with before failure" )
1773 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001774 # what the acceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -08001775 else:
Jon Hall669173b2014-12-17 11:36:30 -08001776 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001777 main.log.warn( "ONOS intents: " )
1778 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1779 sort_keys=True, indent=4,
1780 separators=( ',', ': ' ) ) )
1781 except ( ValueError, TypeError ):
1782 main.log.exception( "Exception printing intents" )
1783 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001784 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001785 utilities.assert_equals(
1786 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001787 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001788 onpass="Intents are consistent with before failure",
1789 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001790 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08001791 """
1792 main.step( "Get the OF Table entries and compare to before " +
1793 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001794 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001795 flows2 = []
1796 for i in range( 28 ):
1797 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001798 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1799 flows2.append( tmpFlows )
1800 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001801 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001802 flow2=tmpFlows )
1803 FlowTables = FlowTables and tempResult
1804 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001805 main.log.info( "Differences in flow table for switch: s" +
1806 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001807 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001808 main.log.report( "No changes were found in the flow tables" )
1809 utilities.assert_equals(
1810 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001811 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001812 onpass="No changes were found in the flow tables",
1813 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001814
Jon Hall6aec96b2015-01-19 14:49:31 -08001815 main.step( "Check the continuous pings to ensure that no packets " +
1816 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001817 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1818 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001819 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001820 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1821 for i in range( 8, 18 ):
1822 main.log.info(
1823 "Checking for a loss in pings along flow from s" +
1824 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001825 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001826 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001827 str( i ) ) or LossInPings
1828 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001829 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001830 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001831 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001832 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001833 main.log.info( "No Loss in the pings" )
1834 main.log.report( "No loss of dataplane connectivity" )
1835 utilities.assert_equals(
1836 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001837 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001838 onpass="No Loss of connectivity",
1839 onfail="Loss of dataplane connectivity detected" )
Jon Hall58c76b72015-02-23 11:09:24 -08001840 # NOTE: Since intents are not persisted with IntnentStore,
1841 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08001842 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001843
Jon Hall390696c2015-05-05 17:13:41 -07001844 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001845 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001846 leaderList = []
1847 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001848 for cli in CLIs:
1849 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001850 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001851 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001852 # error in response
1853 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001854 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001855 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001856 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001857 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001858 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001859 " shows no leader for the election-app was" +
1860 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001861 leaderResult = main.FALSE
1862 if len( set( leaderList ) ) != 1:
1863 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001864 main.log.error(
1865 "Inconsistent view of leader for the election test app" )
1866 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 if leaderResult:
1868 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001869 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001870 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001871 utilities.assert_equals(
1872 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001873 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001874 onpass="Leadership election passed",
1875 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001876
Jon Hall6aec96b2015-01-19 14:49:31 -08001877 def CASE8( self, main ):
1878 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001879 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001880 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001881 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001882 # FIXME add this path to params
1883 sys.path.append( "/home/admin/sts" )
1884 # assumes that sts is already in you PYTHONPATH
1885 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001886 import json
1887 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001888 assert numControllers, "numControllers not defined"
1889 assert main, "main not defined"
1890 assert utilities.assert_equals, "utilities.assert_equals not defined"
1891 assert CLIs, "CLIs not defined"
1892 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001893
Jon Hall6aec96b2015-01-19 14:49:31 -08001894 description = "Compare ONOS Topology view to Mininet topology"
1895 main.case( description )
1896 main.log.report( description )
1897 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001898 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001899 for node in nodes:
1900 temp = ( node, node.name, node.ip_address, 6633 )
1901 ctrls.append( temp )
1902 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001903
Jon Hall8f89dda2015-01-22 16:03:33 -08001904 devicesResults = main.TRUE
1905 portsResults = main.TRUE
1906 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001907 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001908 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001909 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001910 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001911 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001912 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001913 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001914 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001915 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001916 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001917 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001918 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001919 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001920 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001921 threads = []
1922 for i in range( numControllers ):
1923 t = main.Thread( target=CLIs[i].devices,
1924 name="devices-" + str( i ),
1925 args=[ ] )
1926 threads.append( t )
1927 t.start()
1928
1929 for t in threads:
1930 t.join()
1931 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001932 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001933 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001934 threads = []
1935 for i in range( numControllers ):
1936 t = main.Thread( target=CLIs[i].hosts,
1937 name="hosts-" + str( i ),
1938 args=[ ] )
1939 threads.append( t )
1940 t.start()
1941
1942 for t in threads:
1943 t.join()
1944 try:
1945 hosts.append( json.loads( t.result ) )
1946 except ( ValueError, TypeError ):
1947 main.log.exception( "Error parsing hosts results" )
1948 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08001949 for controller in range( 0, len( hosts ) ):
1950 controllerStr = str( controller + 1 )
1951 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001952 if host is None or host.get( 'ips', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08001953 main.log.error(
1954 "DEBUG:Error with host ips on controller" +
1955 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001956 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001957 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001958 threads = []
1959 for i in range( numControllers ):
1960 t = main.Thread( target=CLIs[i].ports,
1961 name="ports-" + str( i ),
1962 args=[ ] )
1963 threads.append( t )
1964 t.start()
1965
1966 for t in threads:
1967 t.join()
1968 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001969 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001970 threads = []
1971 for i in range( numControllers ):
1972 t = main.Thread( target=CLIs[i].links,
1973 name="links-" + str( i ),
1974 args=[ ] )
1975 threads.append( t )
1976 t.start()
1977
1978 for t in threads:
1979 t.join()
1980 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001981 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001982 threads = []
1983 for i in range( numControllers ):
1984 t = main.Thread( target=CLIs[i].clusters,
1985 name="clusters-" + str( i ),
1986 args=[ ] )
1987 threads.append( t )
1988 t.start()
1989
1990 for t in threads:
1991 t.join()
1992 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001993
Jon Hall8f89dda2015-01-22 16:03:33 -08001994 elapsed = time.time() - startTime
1995 cliTime = time.time() - cliStart
1996 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001997
Jon Hall8f89dda2015-01-22 16:03:33 -08001998 for controller in range( numControllers ):
1999 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 if devices[ controller ] or "Error" not in devices[
2001 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002002 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002004 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002005 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002006 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002007 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002008 actual=currentDevicesResult,
2009 onpass="ONOS" + controllerStr +
2010 " Switches view is correct",
2011 onfail="ONOS" + controllerStr +
2012 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002013
Jon Hall6aec96b2015-01-19 14:49:31 -08002014 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002015 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002016 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002017 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002018 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002019 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002020 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002021 actual=currentPortsResult,
2022 onpass="ONOS" + controllerStr +
2023 " ports view is correct",
2024 onfail="ONOS" + controllerStr +
2025 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002026
Jon Hall6aec96b2015-01-19 14:49:31 -08002027 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002028 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002029 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002030 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002031 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002032 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002033 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002034 actual=currentLinksResult,
2035 onpass="ONOS" + controllerStr +
2036 " links view is correct",
2037 onfail="ONOS" + controllerStr +
2038 " links view is incorrect" )
2039
2040 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2041 currentHostsResult = main.Mininet1.compareHosts(
2042 MNTopo, hosts[ controller ] )
2043 else:
2044 currentHostsResult = main.FALSE
2045 utilities.assert_equals( expect=main.TRUE,
2046 actual=currentHostsResult,
2047 onpass="ONOS" + controllerStr +
2048 " hosts exist in Mininet",
2049 onfail="ONOS" + controllerStr +
2050 " hosts don't match Mininet" )
2051
2052 devicesResults = devicesResults and currentDevicesResult
2053 portsResults = portsResults and currentPortsResult
2054 linksResults = linksResults and currentLinksResult
2055 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002056
Jon Hall529a37f2015-01-28 10:02:00 -08002057 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002058
Jon Hall6aec96b2015-01-19 14:49:31 -08002059 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002060 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002061 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002062 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002063 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002064 if "Error" not in hosts[ controller ]:
2065 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002066 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002067 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08002068 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002069 " is inconsistent with ONOS1" )
2070 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002071 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002072
2073 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002074 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002075 controllerStr )
2076 consistentHostsResult = main.FALSE
2077 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002078 " hosts response: " +
2079 repr( hosts[ controller ] ) )
2080 utilities.assert_equals(
2081 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002082 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 onpass="Hosts view is consistent across all ONOS nodes",
2084 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002085
Jon Hall6aec96b2015-01-19 14:49:31 -08002086 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002087 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002088 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002089 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002090 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002091 if "Error" not in clusters[ controller ]:
2092 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002093 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002094 else: # clusters not consistent
2095 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002096 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002097 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002098 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002099
2100 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002101 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002102 "from ONOS" + controllerStr )
2103 consistentClustersResult = main.FALSE
2104 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002105 " clusters response: " +
2106 repr( clusters[ controller ] ) )
2107 utilities.assert_equals(
2108 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002109 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002110 onpass="Clusters view is consistent across all ONOS nodes",
2111 onfail="ONOS nodes have different views of clusters" )
2112 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002113 main.step( "Topology view is correct and consistent across all " +
2114 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002115 try:
2116 numClusters = len( json.loads( clusters[ 0 ] ) )
2117 except ( ValueError, TypeError ):
2118 main.log.exception( "Error parsing clusters[0]: " +
2119 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002120 clusterResults = main.FALSE
2121 if numClusters == 1:
2122 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002123 utilities.assert_equals(
2124 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002125 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002126 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002127 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002128
Jon Hall8f89dda2015-01-22 16:03:33 -08002129 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002130 and hostsResults and consistentHostsResult
2131 and consistentClustersResult and clusterResults
2132 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002133
Jon Hall8f89dda2015-01-22 16:03:33 -08002134 topoResult = topoResult and int( count <= 2 )
2135 note = "note it takes about " + str( int( cliTime ) ) + \
2136 " seconds for the test to make all the cli calls to fetch " +\
2137 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002138 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002139 "Very crass estimate for topology discovery/convergence( " +
2140 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002141 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002142 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002143 onpass="Topology Check Test successful",
2144 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002145 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002146 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002147
Jon Halla9d26da2015-03-30 16:45:32 -07002148 # FIXME: move this to an ONOS state case
2149 main.step( "Checking ONOS nodes" )
2150 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002151 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002152 threads = []
2153 for i in range( numControllers ):
2154 t = main.Thread( target=CLIs[i].nodes,
2155 name="nodes-" + str( i ),
2156 args=[ ] )
2157 threads.append( t )
2158 t.start()
2159
2160 for t in threads:
2161 t.join()
2162 nodesOutput.append( t.result )
2163 ips = [ node.ip_address for node in nodes ]
2164 for i in nodesOutput:
2165 try:
2166 current = json.loads( i )
2167 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002168 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002169 if node['ip'] in ips: # node in nodes() output is in cell
2170 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002171 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002172 else:
2173 main.log.error( "Error in ONOS node availability" )
2174 main.log.error(
2175 json.dumps( current,
2176 sort_keys=True,
2177 indent=4,
2178 separators=( ',', ': ' ) ) )
2179 break
Jon Hall390696c2015-05-05 17:13:41 -07002180 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002181 except ( ValueError, TypeError ):
2182 main.log.error( "Error parsing nodes output" )
2183 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002184 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2185 onpass="Nodes check successful",
2186 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002187
Jon Hall6aec96b2015-01-19 14:49:31 -08002188 def CASE9( self, main ):
2189 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002190 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002191 """
2192 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002193 assert numControllers, "numControllers not defined"
2194 assert main, "main not defined"
2195 assert utilities.assert_equals, "utilities.assert_equals not defined"
2196 assert CLIs, "CLIs not defined"
2197 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002198 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002199
Jon Hall8f89dda2015-01-22 16:03:33 -08002200 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002201
Jon Hall6aec96b2015-01-19 14:49:31 -08002202 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002203 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002204 main.log.report( description )
2205 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002206
Jon Hall6aec96b2015-01-19 14:49:31 -08002207 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002208 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002209 main.log.info( "Waiting " + str( linkSleep ) +
2210 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002211 time.sleep( linkSleep )
2212 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002213 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002214 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002215 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002216
Jon Hall6aec96b2015-01-19 14:49:31 -08002217 def CASE10( self, main ):
2218 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002219 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002220 """
2221 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002222 assert numControllers, "numControllers not defined"
2223 assert main, "main not defined"
2224 assert utilities.assert_equals, "utilities.assert_equals not defined"
2225 assert CLIs, "CLIs not defined"
2226 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002227 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002228
Jon Hall8f89dda2015-01-22 16:03:33 -08002229 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002230
Jon Hall6aec96b2015-01-19 14:49:31 -08002231 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002232 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 main.log.report( description )
2234 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002235
Jon Hall6aec96b2015-01-19 14:49:31 -08002236 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002237 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002238 main.log.info( "Waiting " + str( linkSleep ) +
2239 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002240 time.sleep( linkSleep )
2241 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002242 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002243 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002244 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002245
Jon Hall6aec96b2015-01-19 14:49:31 -08002246 def CASE11( self, main ):
2247 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002248 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002249 """
2250 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002251 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002252 assert numControllers, "numControllers not defined"
2253 assert main, "main not defined"
2254 assert utilities.assert_equals, "utilities.assert_equals not defined"
2255 assert CLIs, "CLIs not defined"
2256 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002257
Jon Hall8f89dda2015-01-22 16:03:33 -08002258 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002259
2260 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002261 main.log.report( description )
2262 main.case( description )
2263 switch = main.params[ 'kill' ][ 'switch' ]
2264 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002265
Jon Hall6aec96b2015-01-19 14:49:31 -08002266 # TODO: Make this switch parameterizable
2267 main.step( "Kill " + switch )
2268 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002269 main.Mininet1.delSwitch( switch )
2270 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002271 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002272 time.sleep( switchSleep )
2273 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002274 # Peek at the deleted switch
2275 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002276 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002277 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002278 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002279 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002280 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002281 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002282
Jon Hall6aec96b2015-01-19 14:49:31 -08002283 def CASE12( self, main ):
2284 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002285 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002286 """
2287 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002288 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002289 assert numControllers, "numControllers not defined"
2290 assert main, "main not defined"
2291 assert utilities.assert_equals, "utilities.assert_equals not defined"
2292 assert CLIs, "CLIs not defined"
2293 assert nodes, "nodes not defined"
2294 assert ONOS1Port, "ONOS1Port not defined"
2295 assert ONOS2Port, "ONOS2Port not defined"
2296 assert ONOS3Port, "ONOS3Port not defined"
2297 assert ONOS4Port, "ONOS4Port not defined"
2298 assert ONOS5Port, "ONOS5Port not defined"
2299 assert ONOS6Port, "ONOS6Port not defined"
2300 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002301
Jon Hall8f89dda2015-01-22 16:03:33 -08002302 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002303 switch = main.params[ 'kill' ][ 'switch' ]
2304 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2305 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002306 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002307 main.log.report( description )
2308 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002309
Jon Hall6aec96b2015-01-19 14:49:31 -08002310 main.step( "Add back " + switch )
2311 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002312 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002313 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002314 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002315 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2316 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002317 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002318 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002319 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002320 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002321 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002322 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002323 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002324 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002325 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002326 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002327 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002328 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002329 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002330 port7=ONOS7Port )
2331 main.log.info( "Waiting " + str( switchSleep ) +
2332 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002333 time.sleep( switchSleep )
2334 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002335 # Peek at the deleted switch
2336 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002337 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002338 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002339 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002340 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002341 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002342 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002343
Jon Hall6aec96b2015-01-19 14:49:31 -08002344 def CASE13( self, main ):
2345 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002346 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002347 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002348 import os
2349 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002350 assert numControllers, "numControllers not defined"
2351 assert main, "main not defined"
2352 assert utilities.assert_equals, "utilities.assert_equals not defined"
2353 assert CLIs, "CLIs not defined"
2354 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002355
2356 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002357 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2358 'blue': '\033[94m', 'green': '\033[92m',
2359 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002360 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002361 main.log.report( description )
2362 main.case( description )
2363 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002364 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002365
Jon Hall6aec96b2015-01-19 14:49:31 -08002366 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002367 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002368 teststationUser = main.params[ 'TESTONUSER' ]
2369 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002370 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002371 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002372 # FIXME: scp
2373 # mn files
2374 # TODO: Load these from params
2375 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002376 logFolder = "/opt/onos/log/"
2377 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002378 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002379 dstDir = "~/packet_captures/"
2380 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002381 for node in nodes:
2382 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2383 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002384 teststationUser + "@" +
2385 teststationIP + ":" +
2386 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002387 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002388 main.ONOSbench.handle.expect( "\$" )
2389
Jon Hall6aec96b2015-01-19 14:49:31 -08002390 # std*.log's
2391 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002392 logFolder = "/opt/onos/var/"
2393 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002394 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002395 dstDir = "~/packet_captures/"
2396 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002397 for node in nodes:
2398 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2399 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002400 teststationUser + "@" +
2401 teststationIP + ":" +
2402 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002403 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002404 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002405 # sleep so scp can finish
2406 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002407
2408 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002409 mnResult = main.Mininet1.stopNet()
2410 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2411 onpass="Mininet stopped",
2412 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002413
2414 main.step( "Checking ONOS Logs for errors" )
2415 for node in nodes:
2416 print colors[ 'purple' ] + "Checking logs for errors on " + \
2417 node.name + ":" + colors[ 'end' ]
2418 print main.ONOSbench.checkLogs( node.ip_address )
2419
Jon Hall6aec96b2015-01-19 14:49:31 -08002420 main.step( "Packing and rotating pcap archives" )
2421 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002422
Jon Hall6aec96b2015-01-19 14:49:31 -08002423 def CASE14( self, main ):
2424 """
Jon Hall669173b2014-12-17 11:36:30 -08002425 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002426 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002427 assert numControllers, "numControllers not defined"
2428 assert main, "main not defined"
2429 assert utilities.assert_equals, "utilities.assert_equals not defined"
2430 assert CLIs, "CLIs not defined"
2431 assert nodes, "nodes not defined"
2432
Jon Hall8f89dda2015-01-22 16:03:33 -08002433 leaderResult = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -07002434 main.case("Start Leadership Election app")
2435 main.step( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002436 main.ONOScli1.activateApp( "org.onosproject.election" )
2437 leaders = []
2438 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002439 cli.electionTestRun()
2440 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002441 leader = cli.electionTestLeader()
2442 if leader is None or leader == main.FALSE:
2443 main.log.report( cli.name + ": Leader for the election app " +
2444 "should be an ONOS node, instead got '" +
2445 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002446 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002447 leaders.append( leader )
2448 if len( set( leaders ) ) != 1:
2449 leaderResult = main.FALSE
2450 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2451 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002452 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002453 main.log.report( "Leadership election tests passed( consistent " +
2454 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002455 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002456 utilities.assert_equals(
2457 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002458 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002459 onpass="Leadership election passed",
2460 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002461
Jon Hall6aec96b2015-01-19 14:49:31 -08002462 def CASE15( self, main ):
2463 """
Jon Hall669173b2014-12-17 11:36:30 -08002464 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002465 """
Jon Hall390696c2015-05-05 17:13:41 -07002466 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002467 assert numControllers, "numControllers not defined"
2468 assert main, "main not defined"
2469 assert utilities.assert_equals, "utilities.assert_equals not defined"
2470 assert CLIs, "CLIs not defined"
2471 assert nodes, "nodes not defined"
2472
Jon Hall8f89dda2015-01-22 16:03:33 -08002473 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002474 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002475 main.log.report( description )
2476 main.case( description )
2477 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002478 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002479 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002480 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002481 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002482 main.log.report(
2483 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002484 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002485 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002486 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002487 for i in range( len( CLIs ) ):
2488 if leader == nodes[ i ].ip_address:
2489 oldLeader = CLIs[ i ]
2490 break
Jon Halla9d26da2015-03-30 16:45:32 -07002491 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002492 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002493 if oldLeader:
2494 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 utilities.assert_equals(
2496 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002497 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 onpass="App was withdrawn from election",
2499 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002500
Jon Hall6aec96b2015-01-19 14:49:31 -08002501 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002502 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002503 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002504 for cli in CLIs:
2505 leaderN = cli.electionTestLeader()
2506 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002507 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002508 main.log.report( cli.name + " still sees " + str( leader ) +
2509 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002510 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002511 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002512 # error in response
2513 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002514 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002515 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002516 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002517 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002518 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002519 elif leaderN is None:
2520 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002521 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002522 leaderN = cli.electionTestLeader()
2523 leaderList.pop()
2524 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002525 consistentLeader = main.FALSE
2526 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002527 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002528 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002529 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002530 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002531 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 main.log.report(
2533 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002534 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002535 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002536 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002537 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002538 if leaderResult:
2539 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002540 "view of leader across listeners and a new " +
2541 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002542 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002543 utilities.assert_equals(
2544 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002545 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002546 onpass="Leadership election passed",
2547 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002548
Jon Hall58c76b72015-02-23 11:09:24 -08002549 main.step( "Run for election on old leader( just so everyone " +
2550 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002551 if oldLeader:
2552 runResult = oldLeader.electionTestRun()
2553 else:
2554 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 utilities.assert_equals(
2556 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002557 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002558 onpass="App re-ran for election",
2559 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002560
2561 afterRun = main.ONOScli1.electionTestLeader()
2562 # verify leader didn't just change
2563 if afterRun == leaderList[ 0 ]:
2564 afterResult = main.TRUE
2565 else:
2566 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002567
Jon Hall6aec96b2015-01-19 14:49:31 -08002568 utilities.assert_equals(
2569 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002570 actual=afterResult,
2571 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002572 onfail="Something went wrong with Leadership election after " +
2573 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002574
2575 case15Result = withdrawResult and leaderResult and runResult and\
2576 afterResult
2577 utilities.assert_equals(
2578 expect=main.TRUE,
2579 actual=case15Result,
2580 onpass="Leadership election is still functional",
2581 onfail="Leadership Election is no longer functional" )
2582
2583 def CASE16( self, main ):
2584 """
2585 Install Distributed Primitives app
2586 """
2587 assert numControllers, "numControllers not defined"
2588 assert main, "main not defined"
2589 assert utilities.assert_equals, "utilities.assert_equals not defined"
2590 assert CLIs, "CLIs not defined"
2591 assert nodes, "nodes not defined"
2592
2593 # Variables for the distributed primitives tests
2594 global pCounterName
2595 global iCounterName
2596 global pCounterValue
2597 global iCounterValue
2598 global onosSet
2599 global onosSetName
2600 pCounterName = "TestON-Partitions"
2601 iCounterName = "TestON-inMemory"
2602 pCounterValue = 0
2603 iCounterValue = 0
2604 onosSet = set([])
2605 onosSetName = "TestON-set"
2606
2607 description = "Install Primitives app"
2608 main.case( description )
2609 main.step( "Install Primitives app" )
2610 appName = "org.onosproject.distributedprimitives"
2611 appResults = CLIs[0].activateApp( appName )
2612 utilities.assert_equals( expect=main.TRUE,
2613 actual=appResults,
2614 onpass="Primitives app activated",
2615 onfail="Primitives app not activated" )
2616
2617 def CASE17( self, main ):
2618 """
2619 Check for basic functionality with distributed primitives
2620 """
2621 # Make sure variables are defined/set
2622 assert numControllers, "numControllers not defined"
2623 assert main, "main not defined"
2624 assert utilities.assert_equals, "utilities.assert_equals not defined"
2625 assert CLIs, "CLIs not defined"
2626 assert nodes, "nodes not defined"
2627 assert pCounterName, "pCounterName not defined"
2628 assert iCounterName, "iCounterName not defined"
2629 assert onosSetName, "onosSetName not defined"
2630 # NOTE: assert fails if value is 0/None/Empty/False
2631 try:
2632 pCounterValue
2633 except NameError:
2634 main.log.error( "pCounterValue not defined, setting to 0" )
2635 pCounterValue = 0
2636 try:
2637 iCounterValue
2638 except NameError:
2639 main.log.error( "iCounterValue not defined, setting to 0" )
2640 iCounterValue = 0
2641 try:
2642 onosSet
2643 except NameError:
2644 main.log.error( "onosSet not defined, setting to empty Set" )
2645 onosSet = set([])
2646 # Variables for the distributed primitives tests. These are local only
2647 addValue = "a"
2648 addAllValue = "a b c d e f"
2649 retainValue = "c d e f"
2650
2651 description = "Check for basic functionality with distributed " +\
2652 "primitives"
2653 main.case( description )
2654 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2655 # DISTRIBUTED ATOMIC COUNTERS
2656 main.step( "Increment and get a default counter on each node" )
2657 pCounters = []
2658 threads = []
2659 for i in range( numControllers ):
2660 t = main.Thread( target=CLIs[i].counterTestIncrement,
2661 name="counterIncrement-" + str( i ),
2662 args=[ pCounterName ] )
2663 pCounterValue += 1
2664 threads.append( t )
2665 t.start()
2666
2667 for t in threads:
2668 t.join()
2669 pCounters.append( t.result )
2670 # Check that counter incremented numController times
2671 pCounterResults = True
2672 for i in range( numControllers ):
2673 pCounterResults and ( i + 1 ) in pCounters
2674 utilities.assert_equals( expect=True,
2675 actual=pCounterResults,
2676 onpass="Default counter incremented",
2677 onfail="Error incrementing default" +
2678 " counter" )
2679
2680 main.step( "Increment and get an in memory counter on each node" )
2681 iCounters = []
2682 threads = []
2683 for i in range( numControllers ):
2684 t = main.Thread( target=CLIs[i].counterTestIncrement,
2685 name="icounterIncrement-" + str( i ),
2686 args=[ iCounterName ],
2687 kwargs={ "inMemory": True } )
2688 iCounterValue += 1
2689 threads.append( t )
2690 t.start()
2691
2692 for t in threads:
2693 t.join()
2694 iCounters.append( t.result )
2695 # Check that counter incremented numController times
2696 iCounterResults = True
2697 for i in range( numControllers ):
2698 iCounterResults and ( i + 1 ) in iCounters
2699 utilities.assert_equals( expect=True,
2700 actual=iCounterResults,
2701 onpass="In memory counter incremented",
2702 onfail="Error incrementing in memory" +
2703 " counter" )
2704
2705 main.step( "Check counters are consistant across nodes" )
2706 onosCounters = []
2707 threads = []
2708 for i in range( numControllers ):
2709 t = main.Thread( target=CLIs[i].counters,
2710 name="counters-" + str( i ) )
2711 threads.append( t )
2712 t.start()
2713 for t in threads:
2714 t.join()
2715 onosCounters.append( t.result )
2716 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2717 if all( tmp ):
2718 main.log.info( "Counters are consistent across all nodes" )
2719 consistentCounterResults = main.TRUE
2720 else:
2721 main.log.error( "Counters are not consistent across all nodes" )
2722 consistentCounterResults = main.FALSE
2723 utilities.assert_equals( expect=main.TRUE,
2724 actual=consistentCounterResults,
2725 onpass="ONOS counters are consistent " +
2726 "across nodes",
2727 onfail="ONOS Counters are inconsistent " +
2728 "across nodes" )
2729
2730 main.step( "Counters we added have the correct values" )
2731 correctResults = main.TRUE
2732 for i in range( numControllers ):
2733 current = onosCounters[i]
2734 try:
2735 pValue = current.get( pCounterName )
2736 iValue = current.get( iCounterName )
2737 if pValue == pCounterValue:
2738 main.log.info( "Partitioned counter value is correct" )
2739 else:
2740 main.log.error( "Partitioned counter value is incorrect," +
2741 " expected value: " + str( pCounterValue )
2742 + " current value: " + str( pValue ) )
2743 correctResults = main.FALSE
2744 if iValue == iCounterValue:
2745 main.log.info( "In memory counter value is correct" )
2746 else:
2747 main.log.error( "In memory counter value is incorrect, " +
2748 "expected value: " + str( iCounterValue ) +
2749 " current value: " + str( iValue ) )
2750 correctResults = main.FALSE
2751 except AttributeError, e:
2752 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2753 "is not as expected" )
2754 correctResults = main.FALSE
2755 utilities.assert_equals( expect=main.TRUE,
2756 actual=correctResults,
2757 onpass="Added counters are correct",
2758 onfail="Added counters are incorrect" )
2759 # DISTRIBUTED SETS
2760 main.step( "Distributed Set get" )
2761 size = len( onosSet )
2762 getResponses = []
2763 threads = []
2764 for i in range( numControllers ):
2765 t = main.Thread( target=CLIs[i].setTestGet,
2766 name="setTestGet-" + str( i ),
2767 args=[ onosSetName ] )
2768 threads.append( t )
2769 t.start()
2770 for t in threads:
2771 t.join()
2772 getResponses.append( t.result )
2773
2774 getResults = main.TRUE
2775 for i in range( numControllers ):
2776 if isinstance( getResponses[ i ], list):
2777 current = set( getResponses[ i ] )
2778 if len( current ) == len( getResponses[ i ] ):
2779 # no repeats
2780 if onosSet != current:
2781 main.log.error( "ONOS" + str( i + 1 ) +
2782 " has incorrect view" +
2783 " of set " + onosSetName + ":\n" +
2784 str( getResponses[ i ] ) )
2785 main.log.debug( "Expected: " + str( onosSet ) )
2786 main.log.debug( "Actual: " + str( current ) )
2787 getResults = main.FALSE
2788 else:
2789 # error, set is not a set
2790 main.log.error( "ONOS" + str( i + 1 ) +
2791 " has repeat elements in" +
2792 " set " + onosSetName + ":\n" +
2793 str( getResponses[ i ] ) )
2794 getResults = main.FALSE
2795 elif getResponses[ i ] == main.ERROR:
2796 getResults = main.FALSE
2797 utilities.assert_equals( expect=main.TRUE,
2798 actual=getResults,
2799 onpass="Set elements are correct",
2800 onfail="Set elements are incorrect" )
2801
2802 main.step( "Distributed Set size" )
2803 sizeResponses = []
2804 threads = []
2805 for i in range( numControllers ):
2806 t = main.Thread( target=CLIs[i].setTestSize,
2807 name="setTestSize-" + str( i ),
2808 args=[ onosSetName ] )
2809 threads.append( t )
2810 t.start()
2811 for t in threads:
2812 t.join()
2813 sizeResponses.append( t.result )
2814
2815 sizeResults = main.TRUE
2816 for i in range( numControllers ):
2817 if size != sizeResponses[ i ]:
2818 sizeResults = main.FALSE
2819 main.log.error( "ONOS" + str( i + 1 ) +
2820 " expected a size of " + str( size ) +
2821 " for set " + onosSetName +
2822 " but got " + str( sizeResponses[ i ] ) )
2823 utilities.assert_equals( expect=main.TRUE,
2824 actual=sizeResults,
2825 onpass="Set sizes are correct",
2826 onfail="Set sizes are incorrect" )
2827
2828 main.step( "Distributed Set add()" )
2829 onosSet.add( addValue )
2830 addResponses = []
2831 threads = []
2832 for i in range( numControllers ):
2833 t = main.Thread( target=CLIs[i].setTestAdd,
2834 name="setTestAdd-" + str( i ),
2835 args=[ onosSetName, addValue ] )
2836 threads.append( t )
2837 t.start()
2838 for t in threads:
2839 t.join()
2840 addResponses.append( t.result )
2841
2842 # main.TRUE = successfully changed the set
2843 # main.FALSE = action resulted in no change in set
2844 # main.ERROR - Some error in executing the function
2845 addResults = main.TRUE
2846 for i in range( numControllers ):
2847 if addResponses[ i ] == main.TRUE:
2848 # All is well
2849 pass
2850 elif addResponses[ i ] == main.FALSE:
2851 # Already in set, probably fine
2852 pass
2853 elif addResponses[ i ] == main.ERROR:
2854 # Error in execution
2855 addResults = main.FALSE
2856 else:
2857 # unexpected result
2858 addResults = main.FALSE
2859 if addResults != main.TRUE:
2860 main.log.error( "Error executing set add" )
2861
2862 # Check if set is still correct
2863 size = len( onosSet )
2864 getResponses = []
2865 threads = []
2866 for i in range( numControllers ):
2867 t = main.Thread( target=CLIs[i].setTestGet,
2868 name="setTestGet-" + str( i ),
2869 args=[ onosSetName ] )
2870 threads.append( t )
2871 t.start()
2872 for t in threads:
2873 t.join()
2874 getResponses.append( t.result )
2875 getResults = main.TRUE
2876 for i in range( numControllers ):
2877 if isinstance( getResponses[ i ], list):
2878 current = set( getResponses[ i ] )
2879 if len( current ) == len( getResponses[ i ] ):
2880 # no repeats
2881 if onosSet != current:
2882 main.log.error( "ONOS" + str( i + 1 ) +
2883 " has incorrect view" +
2884 " of set " + onosSetName + ":\n" +
2885 str( getResponses[ i ] ) )
2886 main.log.debug( "Expected: " + str( onosSet ) )
2887 main.log.debug( "Actual: " + str( current ) )
2888 getResults = main.FALSE
2889 else:
2890 # error, set is not a set
2891 main.log.error( "ONOS" + str( i + 1 ) +
2892 " has repeat elements in" +
2893 " set " + onosSetName + ":\n" +
2894 str( getResponses[ i ] ) )
2895 getResults = main.FALSE
2896 elif getResponses[ i ] == main.ERROR:
2897 getResults = main.FALSE
2898 sizeResponses = []
2899 threads = []
2900 for i in range( numControllers ):
2901 t = main.Thread( target=CLIs[i].setTestSize,
2902 name="setTestSize-" + str( i ),
2903 args=[ onosSetName ] )
2904 threads.append( t )
2905 t.start()
2906 for t in threads:
2907 t.join()
2908 sizeResponses.append( t.result )
2909 sizeResults = main.TRUE
2910 for i in range( numControllers ):
2911 if size != sizeResponses[ i ]:
2912 sizeResults = main.FALSE
2913 main.log.error( "ONOS" + str( i + 1 ) +
2914 " expected a size of " + str( size ) +
2915 " for set " + onosSetName +
2916 " but got " + str( sizeResponses[ i ] ) )
2917 addResults = addResults and getResults and sizeResults
2918 utilities.assert_equals( expect=main.TRUE,
2919 actual=addResults,
2920 onpass="Set add correct",
2921 onfail="Set add was incorrect" )
2922
2923 main.step( "Distributed Set addAll()" )
2924 onosSet.update( addAllValue.split() )
2925 addResponses = []
2926 threads = []
2927 for i in range( numControllers ):
2928 t = main.Thread( target=CLIs[i].setTestAdd,
2929 name="setTestAddAll-" + str( i ),
2930 args=[ onosSetName, addAllValue ] )
2931 threads.append( t )
2932 t.start()
2933 for t in threads:
2934 t.join()
2935 addResponses.append( t.result )
2936
2937 # main.TRUE = successfully changed the set
2938 # main.FALSE = action resulted in no change in set
2939 # main.ERROR - Some error in executing the function
2940 addAllResults = main.TRUE
2941 for i in range( numControllers ):
2942 if addResponses[ i ] == main.TRUE:
2943 # All is well
2944 pass
2945 elif addResponses[ i ] == main.FALSE:
2946 # Already in set, probably fine
2947 pass
2948 elif addResponses[ i ] == main.ERROR:
2949 # Error in execution
2950 addAllResults = main.FALSE
2951 else:
2952 # unexpected result
2953 addAllResults = main.FALSE
2954 if addAllResults != main.TRUE:
2955 main.log.error( "Error executing set addAll" )
2956
2957 # Check if set is still correct
2958 size = len( onosSet )
2959 getResponses = []
2960 threads = []
2961 for i in range( numControllers ):
2962 t = main.Thread( target=CLIs[i].setTestGet,
2963 name="setTestGet-" + str( i ),
2964 args=[ onosSetName ] )
2965 threads.append( t )
2966 t.start()
2967 for t in threads:
2968 t.join()
2969 getResponses.append( t.result )
2970 getResults = main.TRUE
2971 for i in range( numControllers ):
2972 if isinstance( getResponses[ i ], list):
2973 current = set( getResponses[ i ] )
2974 if len( current ) == len( getResponses[ i ] ):
2975 # no repeats
2976 if onosSet != current:
2977 main.log.error( "ONOS" + str( i + 1 ) +
2978 " has incorrect view" +
2979 " of set " + onosSetName + ":\n" +
2980 str( getResponses[ i ] ) )
2981 main.log.debug( "Expected: " + str( onosSet ) )
2982 main.log.debug( "Actual: " + str( current ) )
2983 getResults = main.FALSE
2984 else:
2985 # error, set is not a set
2986 main.log.error( "ONOS" + str( i + 1 ) +
2987 " has repeat elements in" +
2988 " set " + onosSetName + ":\n" +
2989 str( getResponses[ i ] ) )
2990 getResults = main.FALSE
2991 elif getResponses[ i ] == main.ERROR:
2992 getResults = main.FALSE
2993 sizeResponses = []
2994 threads = []
2995 for i in range( numControllers ):
2996 t = main.Thread( target=CLIs[i].setTestSize,
2997 name="setTestSize-" + str( i ),
2998 args=[ onosSetName ] )
2999 threads.append( t )
3000 t.start()
3001 for t in threads:
3002 t.join()
3003 sizeResponses.append( t.result )
3004 sizeResults = main.TRUE
3005 for i in range( numControllers ):
3006 if size != sizeResponses[ i ]:
3007 sizeResults = main.FALSE
3008 main.log.error( "ONOS" + str( i + 1 ) +
3009 " expected a size of " + str( size ) +
3010 " for set " + onosSetName +
3011 " but got " + str( sizeResponses[ i ] ) )
3012 addAllResults = addAllResults and getResults and sizeResults
3013 utilities.assert_equals( expect=main.TRUE,
3014 actual=addAllResults,
3015 onpass="Set addAll correct",
3016 onfail="Set addAll was incorrect" )
3017
3018 main.step( "Distributed Set contains()" )
3019 containsResponses = []
3020 threads = []
3021 for i in range( numControllers ):
3022 t = main.Thread( target=CLIs[i].setTestGet,
3023 name="setContains-" + str( i ),
3024 args=[ onosSetName ],
3025 kwargs={ "values": addValue } )
3026 threads.append( t )
3027 t.start()
3028 for t in threads:
3029 t.join()
3030 # NOTE: This is the tuple
3031 containsResponses.append( t.result )
3032
3033 containsResults = main.TRUE
3034 for i in range( numControllers ):
3035 if containsResponses[ i ] == main.ERROR:
3036 containsResults = main.FALSE
3037 else:
3038 containsResults = containsResults and\
3039 containsResponses[ i ][ 1 ]
3040 utilities.assert_equals( expect=main.TRUE,
3041 actual=containsResults,
3042 onpass="Set contains is functional",
3043 onfail="Set contains failed" )
3044
3045 main.step( "Distributed Set containsAll()" )
3046 containsAllResponses = []
3047 threads = []
3048 for i in range( numControllers ):
3049 t = main.Thread( target=CLIs[i].setTestGet,
3050 name="setContainsAll-" + str( i ),
3051 args=[ onosSetName ],
3052 kwargs={ "values": addAllValue } )
3053 threads.append( t )
3054 t.start()
3055 for t in threads:
3056 t.join()
3057 # NOTE: This is the tuple
3058 containsAllResponses.append( t.result )
3059
3060 containsAllResults = main.TRUE
3061 for i in range( numControllers ):
3062 if containsResponses[ i ] == main.ERROR:
3063 containsResults = main.FALSE
3064 else:
3065 containsResults = containsResults and\
3066 containsResponses[ i ][ 1 ]
3067 utilities.assert_equals( expect=main.TRUE,
3068 actual=containsAllResults,
3069 onpass="Set containsAll is functional",
3070 onfail="Set containsAll failed" )
3071
3072 main.step( "Distributed Set remove()" )
3073 onosSet.remove( addValue )
3074 removeResponses = []
3075 threads = []
3076 for i in range( numControllers ):
3077 t = main.Thread( target=CLIs[i].setTestRemove,
3078 name="setTestRemove-" + str( i ),
3079 args=[ onosSetName, addValue ] )
3080 threads.append( t )
3081 t.start()
3082 for t in threads:
3083 t.join()
3084 removeResponses.append( t.result )
3085
3086 # main.TRUE = successfully changed the set
3087 # main.FALSE = action resulted in no change in set
3088 # main.ERROR - Some error in executing the function
3089 removeResults = main.TRUE
3090 for i in range( numControllers ):
3091 if removeResponses[ i ] == main.TRUE:
3092 # All is well
3093 pass
3094 elif removeResponses[ i ] == main.FALSE:
3095 # not in set, probably fine
3096 pass
3097 elif removeResponses[ i ] == main.ERROR:
3098 # Error in execution
3099 removeResults = main.FALSE
3100 else:
3101 # unexpected result
3102 removeResults = main.FALSE
3103 if removeResults != main.TRUE:
3104 main.log.error( "Error executing set remove" )
3105
3106 # Check if set is still correct
3107 size = len( onosSet )
3108 getResponses = []
3109 threads = []
3110 for i in range( numControllers ):
3111 t = main.Thread( target=CLIs[i].setTestGet,
3112 name="setTestGet-" + str( i ),
3113 args=[ onosSetName ] )
3114 threads.append( t )
3115 t.start()
3116 for t in threads:
3117 t.join()
3118 getResponses.append( t.result )
3119 getResults = main.TRUE
3120 for i in range( numControllers ):
3121 if isinstance( getResponses[ i ], list):
3122 current = set( getResponses[ i ] )
3123 if len( current ) == len( getResponses[ i ] ):
3124 # no repeats
3125 if onosSet != current:
3126 main.log.error( "ONOS" + str( i + 1 ) +
3127 " has incorrect view" +
3128 " of set " + onosSetName + ":\n" +
3129 str( getResponses[ i ] ) )
3130 main.log.debug( "Expected: " + str( onosSet ) )
3131 main.log.debug( "Actual: " + str( current ) )
3132 getResults = main.FALSE
3133 else:
3134 # error, set is not a set
3135 main.log.error( "ONOS" + str( i + 1 ) +
3136 " has repeat elements in" +
3137 " set " + onosSetName + ":\n" +
3138 str( getResponses[ i ] ) )
3139 getResults = main.FALSE
3140 elif getResponses[ i ] == main.ERROR:
3141 getResults = main.FALSE
3142 sizeResponses = []
3143 threads = []
3144 for i in range( numControllers ):
3145 t = main.Thread( target=CLIs[i].setTestSize,
3146 name="setTestSize-" + str( i ),
3147 args=[ onosSetName ] )
3148 threads.append( t )
3149 t.start()
3150 for t in threads:
3151 t.join()
3152 sizeResponses.append( t.result )
3153 sizeResults = main.TRUE
3154 for i in range( numControllers ):
3155 if size != sizeResponses[ i ]:
3156 sizeResults = main.FALSE
3157 main.log.error( "ONOS" + str( i + 1 ) +
3158 " expected a size of " + str( size ) +
3159 " for set " + onosSetName +
3160 " but got " + str( sizeResponses[ i ] ) )
3161 removeResults = removeResults and getResults and sizeResults
3162 utilities.assert_equals( expect=main.TRUE,
3163 actual=removeResults,
3164 onpass="Set remove correct",
3165 onfail="Set remove was incorrect" )
3166
3167 main.step( "Distributed Set removeAll()" )
3168 onosSet.difference_update( addAllValue.split() )
3169 removeAllResponses = []
3170 threads = []
3171 try:
3172 for i in range( numControllers ):
3173 t = main.Thread( target=CLIs[i].setTestRemove,
3174 name="setTestRemoveAll-" + str( i ),
3175 args=[ onosSetName, addAllValue ] )
3176 threads.append( t )
3177 t.start()
3178 for t in threads:
3179 t.join()
3180 removeAllResponses.append( t.result )
3181 except Exception, e:
3182 main.log.exception(e)
3183
3184 # main.TRUE = successfully changed the set
3185 # main.FALSE = action resulted in no change in set
3186 # main.ERROR - Some error in executing the function
3187 removeAllResults = main.TRUE
3188 for i in range( numControllers ):
3189 if removeAllResponses[ i ] == main.TRUE:
3190 # All is well
3191 pass
3192 elif removeAllResponses[ i ] == main.FALSE:
3193 # not in set, probably fine
3194 pass
3195 elif removeAllResponses[ i ] == main.ERROR:
3196 # Error in execution
3197 removeAllResults = main.FALSE
3198 else:
3199 # unexpected result
3200 removeAllResults = main.FALSE
3201 if removeAllResults != main.TRUE:
3202 main.log.error( "Error executing set removeAll" )
3203
3204 # Check if set is still correct
3205 size = len( onosSet )
3206 getResponses = []
3207 threads = []
3208 for i in range( numControllers ):
3209 t = main.Thread( target=CLIs[i].setTestGet,
3210 name="setTestGet-" + str( i ),
3211 args=[ onosSetName ] )
3212 threads.append( t )
3213 t.start()
3214 for t in threads:
3215 t.join()
3216 getResponses.append( t.result )
3217 getResults = main.TRUE
3218 for i in range( numControllers ):
3219 if isinstance( getResponses[ i ], list):
3220 current = set( getResponses[ i ] )
3221 if len( current ) == len( getResponses[ i ] ):
3222 # no repeats
3223 if onosSet != current:
3224 main.log.error( "ONOS" + str( i + 1 ) +
3225 " has incorrect view" +
3226 " of set " + onosSetName + ":\n" +
3227 str( getResponses[ i ] ) )
3228 main.log.debug( "Expected: " + str( onosSet ) )
3229 main.log.debug( "Actual: " + str( current ) )
3230 getResults = main.FALSE
3231 else:
3232 # error, set is not a set
3233 main.log.error( "ONOS" + str( i + 1 ) +
3234 " has repeat elements in" +
3235 " set " + onosSetName + ":\n" +
3236 str( getResponses[ i ] ) )
3237 getResults = main.FALSE
3238 elif getResponses[ i ] == main.ERROR:
3239 getResults = main.FALSE
3240 sizeResponses = []
3241 threads = []
3242 for i in range( numControllers ):
3243 t = main.Thread( target=CLIs[i].setTestSize,
3244 name="setTestSize-" + str( i ),
3245 args=[ onosSetName ] )
3246 threads.append( t )
3247 t.start()
3248 for t in threads:
3249 t.join()
3250 sizeResponses.append( t.result )
3251 sizeResults = main.TRUE
3252 for i in range( numControllers ):
3253 if size != sizeResponses[ i ]:
3254 sizeResults = main.FALSE
3255 main.log.error( "ONOS" + str( i + 1 ) +
3256 " expected a size of " + str( size ) +
3257 " for set " + onosSetName +
3258 " but got " + str( sizeResponses[ i ] ) )
3259 removeAllResults = removeAllResults and getResults and sizeResults
3260 utilities.assert_equals( expect=main.TRUE,
3261 actual=removeAllResults,
3262 onpass="Set removeAll correct",
3263 onfail="Set removeAll was incorrect" )
3264
3265 main.step( "Distributed Set addAll()" )
3266 onosSet.update( addAllValue.split() )
3267 addResponses = []
3268 threads = []
3269 for i in range( numControllers ):
3270 t = main.Thread( target=CLIs[i].setTestAdd,
3271 name="setTestAddAll-" + str( i ),
3272 args=[ onosSetName, addAllValue ] )
3273 threads.append( t )
3274 t.start()
3275 for t in threads:
3276 t.join()
3277 addResponses.append( t.result )
3278
3279 # main.TRUE = successfully changed the set
3280 # main.FALSE = action resulted in no change in set
3281 # main.ERROR - Some error in executing the function
3282 addAllResults = main.TRUE
3283 for i in range( numControllers ):
3284 if addResponses[ i ] == main.TRUE:
3285 # All is well
3286 pass
3287 elif addResponses[ i ] == main.FALSE:
3288 # Already in set, probably fine
3289 pass
3290 elif addResponses[ i ] == main.ERROR:
3291 # Error in execution
3292 addAllResults = main.FALSE
3293 else:
3294 # unexpected result
3295 addAllResults = main.FALSE
3296 if addAllResults != main.TRUE:
3297 main.log.error( "Error executing set addAll" )
3298
3299 # Check if set is still correct
3300 size = len( onosSet )
3301 getResponses = []
3302 threads = []
3303 for i in range( numControllers ):
3304 t = main.Thread( target=CLIs[i].setTestGet,
3305 name="setTestGet-" + str( i ),
3306 args=[ onosSetName ] )
3307 threads.append( t )
3308 t.start()
3309 for t in threads:
3310 t.join()
3311 getResponses.append( t.result )
3312 getResults = main.TRUE
3313 for i in range( numControllers ):
3314 if isinstance( getResponses[ i ], list):
3315 current = set( getResponses[ i ] )
3316 if len( current ) == len( getResponses[ i ] ):
3317 # no repeats
3318 if onosSet != current:
3319 main.log.error( "ONOS" + str( i + 1 ) +
3320 " has incorrect view" +
3321 " of set " + onosSetName + ":\n" +
3322 str( getResponses[ i ] ) )
3323 main.log.debug( "Expected: " + str( onosSet ) )
3324 main.log.debug( "Actual: " + str( current ) )
3325 getResults = main.FALSE
3326 else:
3327 # error, set is not a set
3328 main.log.error( "ONOS" + str( i + 1 ) +
3329 " has repeat elements in" +
3330 " set " + onosSetName + ":\n" +
3331 str( getResponses[ i ] ) )
3332 getResults = main.FALSE
3333 elif getResponses[ i ] == main.ERROR:
3334 getResults = main.FALSE
3335 sizeResponses = []
3336 threads = []
3337 for i in range( numControllers ):
3338 t = main.Thread( target=CLIs[i].setTestSize,
3339 name="setTestSize-" + str( i ),
3340 args=[ onosSetName ] )
3341 threads.append( t )
3342 t.start()
3343 for t in threads:
3344 t.join()
3345 sizeResponses.append( t.result )
3346 sizeResults = main.TRUE
3347 for i in range( numControllers ):
3348 if size != sizeResponses[ i ]:
3349 sizeResults = main.FALSE
3350 main.log.error( "ONOS" + str( i + 1 ) +
3351 " expected a size of " + str( size ) +
3352 " for set " + onosSetName +
3353 " but got " + str( sizeResponses[ i ] ) )
3354 addAllResults = addAllResults and getResults and sizeResults
3355 utilities.assert_equals( expect=main.TRUE,
3356 actual=addAllResults,
3357 onpass="Set addAll correct",
3358 onfail="Set addAll was incorrect" )
3359
3360 main.step( "Distributed Set clear()" )
3361 onosSet.clear()
3362 clearResponses = []
3363 threads = []
3364 for i in range( numControllers ):
3365 t = main.Thread( target=CLIs[i].setTestRemove,
3366 name="setTestClear-" + str( i ),
3367 args=[ onosSetName, " "], # Values doesn't matter
3368 kwargs={ "clear": True } )
3369 threads.append( t )
3370 t.start()
3371 for t in threads:
3372 t.join()
3373 clearResponses.append( t.result )
3374
3375 # main.TRUE = successfully changed the set
3376 # main.FALSE = action resulted in no change in set
3377 # main.ERROR - Some error in executing the function
3378 clearResults = main.TRUE
3379 for i in range( numControllers ):
3380 if clearResponses[ i ] == main.TRUE:
3381 # All is well
3382 pass
3383 elif clearResponses[ i ] == main.FALSE:
3384 # Nothing set, probably fine
3385 pass
3386 elif clearResponses[ i ] == main.ERROR:
3387 # Error in execution
3388 clearResults = main.FALSE
3389 else:
3390 # unexpected result
3391 clearResults = main.FALSE
3392 if clearResults != main.TRUE:
3393 main.log.error( "Error executing set clear" )
3394
3395 # Check if set is still correct
3396 size = len( onosSet )
3397 getResponses = []
3398 threads = []
3399 for i in range( numControllers ):
3400 t = main.Thread( target=CLIs[i].setTestGet,
3401 name="setTestGet-" + str( i ),
3402 args=[ onosSetName ] )
3403 threads.append( t )
3404 t.start()
3405 for t in threads:
3406 t.join()
3407 getResponses.append( t.result )
3408 getResults = main.TRUE
3409 for i in range( numControllers ):
3410 if isinstance( getResponses[ i ], list):
3411 current = set( getResponses[ i ] )
3412 if len( current ) == len( getResponses[ i ] ):
3413 # no repeats
3414 if onosSet != current:
3415 main.log.error( "ONOS" + str( i + 1 ) +
3416 " has incorrect view" +
3417 " of set " + onosSetName + ":\n" +
3418 str( getResponses[ i ] ) )
3419 main.log.debug( "Expected: " + str( onosSet ) )
3420 main.log.debug( "Actual: " + str( current ) )
3421 getResults = main.FALSE
3422 else:
3423 # error, set is not a set
3424 main.log.error( "ONOS" + str( i + 1 ) +
3425 " has repeat elements in" +
3426 " set " + onosSetName + ":\n" +
3427 str( getResponses[ i ] ) )
3428 getResults = main.FALSE
3429 elif getResponses[ i ] == main.ERROR:
3430 getResults = main.FALSE
3431 sizeResponses = []
3432 threads = []
3433 for i in range( numControllers ):
3434 t = main.Thread( target=CLIs[i].setTestSize,
3435 name="setTestSize-" + str( i ),
3436 args=[ onosSetName ] )
3437 threads.append( t )
3438 t.start()
3439 for t in threads:
3440 t.join()
3441 sizeResponses.append( t.result )
3442 sizeResults = main.TRUE
3443 for i in range( numControllers ):
3444 if size != sizeResponses[ i ]:
3445 sizeResults = main.FALSE
3446 main.log.error( "ONOS" + str( i + 1 ) +
3447 " expected a size of " + str( size ) +
3448 " for set " + onosSetName +
3449 " but got " + str( sizeResponses[ i ] ) )
3450 clearResults = clearResults and getResults and sizeResults
3451 utilities.assert_equals( expect=main.TRUE,
3452 actual=clearResults,
3453 onpass="Set clear correct",
3454 onfail="Set clear was incorrect" )
3455
3456 main.step( "Distributed Set addAll()" )
3457 onosSet.update( addAllValue.split() )
3458 addResponses = []
3459 threads = []
3460 for i in range( numControllers ):
3461 t = main.Thread( target=CLIs[i].setTestAdd,
3462 name="setTestAddAll-" + str( i ),
3463 args=[ onosSetName, addAllValue ] )
3464 threads.append( t )
3465 t.start()
3466 for t in threads:
3467 t.join()
3468 addResponses.append( t.result )
3469
3470 # main.TRUE = successfully changed the set
3471 # main.FALSE = action resulted in no change in set
3472 # main.ERROR - Some error in executing the function
3473 addAllResults = main.TRUE
3474 for i in range( numControllers ):
3475 if addResponses[ i ] == main.TRUE:
3476 # All is well
3477 pass
3478 elif addResponses[ i ] == main.FALSE:
3479 # Already in set, probably fine
3480 pass
3481 elif addResponses[ i ] == main.ERROR:
3482 # Error in execution
3483 addAllResults = main.FALSE
3484 else:
3485 # unexpected result
3486 addAllResults = main.FALSE
3487 if addAllResults != main.TRUE:
3488 main.log.error( "Error executing set addAll" )
3489
3490 # Check if set is still correct
3491 size = len( onosSet )
3492 getResponses = []
3493 threads = []
3494 for i in range( numControllers ):
3495 t = main.Thread( target=CLIs[i].setTestGet,
3496 name="setTestGet-" + str( i ),
3497 args=[ onosSetName ] )
3498 threads.append( t )
3499 t.start()
3500 for t in threads:
3501 t.join()
3502 getResponses.append( t.result )
3503 getResults = main.TRUE
3504 for i in range( numControllers ):
3505 if isinstance( getResponses[ i ], list):
3506 current = set( getResponses[ i ] )
3507 if len( current ) == len( getResponses[ i ] ):
3508 # no repeats
3509 if onosSet != current:
3510 main.log.error( "ONOS" + str( i + 1 ) +
3511 " has incorrect view" +
3512 " of set " + onosSetName + ":\n" +
3513 str( getResponses[ i ] ) )
3514 main.log.debug( "Expected: " + str( onosSet ) )
3515 main.log.debug( "Actual: " + str( current ) )
3516 getResults = main.FALSE
3517 else:
3518 # error, set is not a set
3519 main.log.error( "ONOS" + str( i + 1 ) +
3520 " has repeat elements in" +
3521 " set " + onosSetName + ":\n" +
3522 str( getResponses[ i ] ) )
3523 getResults = main.FALSE
3524 elif getResponses[ i ] == main.ERROR:
3525 getResults = main.FALSE
3526 sizeResponses = []
3527 threads = []
3528 for i in range( numControllers ):
3529 t = main.Thread( target=CLIs[i].setTestSize,
3530 name="setTestSize-" + str( i ),
3531 args=[ onosSetName ] )
3532 threads.append( t )
3533 t.start()
3534 for t in threads:
3535 t.join()
3536 sizeResponses.append( t.result )
3537 sizeResults = main.TRUE
3538 for i in range( numControllers ):
3539 if size != sizeResponses[ i ]:
3540 sizeResults = main.FALSE
3541 main.log.error( "ONOS" + str( i + 1 ) +
3542 " expected a size of " + str( size ) +
3543 " for set " + onosSetName +
3544 " but got " + str( sizeResponses[ i ] ) )
3545 addAllResults = addAllResults and getResults and sizeResults
3546 utilities.assert_equals( expect=main.TRUE,
3547 actual=addAllResults,
3548 onpass="Set addAll correct",
3549 onfail="Set addAll was incorrect" )
3550
3551 main.step( "Distributed Set retain()" )
3552 onosSet.intersection_update( retainValue.split() )
3553 retainResponses = []
3554 threads = []
3555 for i in range( numControllers ):
3556 t = main.Thread( target=CLIs[i].setTestRemove,
3557 name="setTestRetain-" + str( i ),
3558 args=[ onosSetName, retainValue ],
3559 kwargs={ "retain": True } )
3560 threads.append( t )
3561 t.start()
3562 for t in threads:
3563 t.join()
3564 retainResponses.append( t.result )
3565
3566 # main.TRUE = successfully changed the set
3567 # main.FALSE = action resulted in no change in set
3568 # main.ERROR - Some error in executing the function
3569 retainResults = main.TRUE
3570 for i in range( numControllers ):
3571 if retainResponses[ i ] == main.TRUE:
3572 # All is well
3573 pass
3574 elif retainResponses[ i ] == main.FALSE:
3575 # Already in set, probably fine
3576 pass
3577 elif retainResponses[ i ] == main.ERROR:
3578 # Error in execution
3579 retainResults = main.FALSE
3580 else:
3581 # unexpected result
3582 retainResults = main.FALSE
3583 if retainResults != main.TRUE:
3584 main.log.error( "Error executing set retain" )
3585
3586 # Check if set is still correct
3587 size = len( onosSet )
3588 getResponses = []
3589 threads = []
3590 for i in range( numControllers ):
3591 t = main.Thread( target=CLIs[i].setTestGet,
3592 name="setTestGet-" + str( i ),
3593 args=[ onosSetName ] )
3594 threads.append( t )
3595 t.start()
3596 for t in threads:
3597 t.join()
3598 getResponses.append( t.result )
3599 getResults = main.TRUE
3600 for i in range( numControllers ):
3601 if isinstance( getResponses[ i ], list):
3602 current = set( getResponses[ i ] )
3603 if len( current ) == len( getResponses[ i ] ):
3604 # no repeats
3605 if onosSet != current:
3606 main.log.error( "ONOS" + str( i + 1 ) +
3607 " has incorrect view" +
3608 " of set " + onosSetName + ":\n" +
3609 str( getResponses[ i ] ) )
3610 main.log.debug( "Expected: " + str( onosSet ) )
3611 main.log.debug( "Actual: " + str( current ) )
3612 getResults = main.FALSE
3613 else:
3614 # error, set is not a set
3615 main.log.error( "ONOS" + str( i + 1 ) +
3616 " has repeat elements in" +
3617 " set " + onosSetName + ":\n" +
3618 str( getResponses[ i ] ) )
3619 getResults = main.FALSE
3620 elif getResponses[ i ] == main.ERROR:
3621 getResults = main.FALSE
3622 sizeResponses = []
3623 threads = []
3624 for i in range( numControllers ):
3625 t = main.Thread( target=CLIs[i].setTestSize,
3626 name="setTestSize-" + str( i ),
3627 args=[ onosSetName ] )
3628 threads.append( t )
3629 t.start()
3630 for t in threads:
3631 t.join()
3632 sizeResponses.append( t.result )
3633 sizeResults = main.TRUE
3634 for i in range( numControllers ):
3635 if size != sizeResponses[ i ]:
3636 sizeResults = main.FALSE
3637 main.log.error( "ONOS" + str( i + 1 ) +
3638 " expected a size of " +
3639 str( size ) + " for set " + onosSetName +
3640 " but got " + str( sizeResponses[ i ] ) )
3641 retainResults = retainResults and getResults and sizeResults
3642 utilities.assert_equals( expect=main.TRUE,
3643 actual=retainResults,
3644 onpass="Set retain correct",
3645 onfail="Set retain was incorrect" )
3646