blob: 256561a47908b6fdcbe4d96438271edc24846673 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070021CASE16: Install Distributed Primitives app
22CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080023"""
Jon Hall8f89dda2015-01-22 16:03:33 -080024
25
Jon Hall73cf9cc2014-11-20 22:28:38 -080026class HATestMinorityRestart:
27
Jon Hall6aec96b2015-01-19 14:49:31 -080028 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080029 self.default = ''
30
Jon Hall6aec96b2015-01-19 14:49:31 -080031 def CASE1( self, main ):
32 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080033 CASE1 is to compile ONOS and push it to the test machines
34
35 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080036 cell <name>
37 onos-verify-cell
38 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080039 onos-uninstall
40 start mininet
41 git pull
42 mvn clean install
43 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080044 onos-install -f
45 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080046 start cli sessions
47 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080048 """
Jon Hall390696c2015-05-05 17:13:41 -070049 main.log.report( "ONOS HA test: Restart minority of ONOS nodes - " +
50 "initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080051 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070052 main.caseExplaination = "Setup the test environment including " +\
53 "installing ONOS, starting Mininet and ONOS" +\
54 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080055 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080056
Jon Hall5cfd23c2015-03-19 11:40:57 -070057 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080058 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080059 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080060 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080061 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080062 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080063
64 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS7Port
72 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080073 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080074
Jon Hall5cfd23c2015-03-19 11:40:57 -070075 # FIXME: just get controller port from params?
76 # TODO: do we really need all these?
77 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
78 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
79 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
80 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
81 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
82 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
83 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
84
85 global CLIs
86 CLIs = []
87 global nodes
88 nodes = []
89 for i in range( 1, numControllers + 1 ):
90 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
91 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
92
Jon Hall6aec96b2015-01-19 14:49:31 -080093 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080094 cellResult = main.ONOSbench.setCell( cellName )
95 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080096
Jon Hall6aec96b2015-01-19 14:49:31 -080097 # FIXME:this is short term fix
98 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080099 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700100
Jon Hall6aec96b2015-01-19 14:49:31 -0800101 main.log.report( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700102 for node in nodes:
103 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800104
Jon Hall390696c2015-05-05 17:13:41 -0700105 # Make sure ONOS is DEAD
106 main.log.report( "Killing any ONOS processes" )
107 killResults = main.TRUE
108 for node in nodes:
109 killed = main.ONOSbench.onosKill( node.ip_address )
110 killResults = killResults and killed
111
Jon Hall8f89dda2015-01-22 16:03:33 -0800112 cleanInstallResult = main.TRUE
113 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800114
Jon Hall97f31752015-02-04 12:01:04 -0800115 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700116 mnResult = main.Mininet1.startNet( )
117 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
118 onpass="Mininet Started",
119 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800120
Jon Hallfeff3082015-05-19 10:23:26 -0700121 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800123 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800124 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700125 # values of 1 or 3 are good
126 utilities.assert_lesser( expect=0, actual=gitPullResult,
127 onpass="Git pull successful",
128 onfail="Git pull failed" )
Jon Hall529a37f2015-01-28 10:02:00 -0800129 else:
130 main.log.warn( "Did not pull new code so skipping mvn " +
131 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800132 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700133
134 main.step( "Using mvn clean install" )
135 cleanInstallResult = main.TRUE
136 if gitPullResult == main.TRUE:
137 cleanInstallResult = main.ONOSbench.cleanInstall()
138 utilities.assert_equals( expect=main.TRUE,
139 actual=cleanInstallResult,
140 onpass="MCI successful",
141 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700142 # GRAPHS
143 # NOTE: important params here:
144 # job = name of Jenkins job
145 # Plot Name = Plot-HA, only can be used if multiple plots
146 # index = The number of the graph under plot name
147 job = "HAMinorityRestart"
148 graphs = '<ac:structured-macro ac:name="html">\n'
149 graphs += '<ac:plain-text-body><![CDATA[\n'
150 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
151 '/plot/getPlot?index=0&width=500&height=300"' +\
152 'noborder="0" width="500" height="300" scrolling="yes" ' +\
153 'seamless="seamless"></iframe>\n'
154 graphs += ']]></ac:plain-text-body>\n'
155 graphs += '</ac:structured-macro>\n'
156 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800157
Jon Hall6aec96b2015-01-19 14:49:31 -0800158 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800159 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700160 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
161 onpass="ONOS package successful",
162 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800163
Jon Hall6aec96b2015-01-19 14:49:31 -0800164 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700165 onosInstallResult = main.TRUE
166 for node in nodes:
167 tmpResult = main.ONOSbench.onosInstall( options="-f",
168 node=node.ip_address )
169 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700170 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
171 onpass="ONOS install successful",
172 onfail="ONOS install failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800173
Jon Hall6aec96b2015-01-19 14:49:31 -0800174 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800175 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700176 onosIsupResult = main.TRUE
177 for node in nodes:
178 started = main.ONOSbench.isup( node.ip_address )
179 if not started:
180 main.log.report( node.name + " didn't start!" )
181 main.ONOSbench.onosStop( node.ip_address )
182 main.ONOSbench.onosStart( node.ip_address )
183 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800184 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800185 break
Jon Hall390696c2015-05-05 17:13:41 -0700186 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
187 onpass="ONOS startup successful",
188 onfail="ONOS startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800189
Jon Hall5cfd23c2015-03-19 11:40:57 -0700190 main.log.step( "Starting ONOS CLI sessions" )
191 cliResults = main.TRUE
192 threads = []
193 for i in range( numControllers ):
194 t = main.Thread( target=CLIs[i].startOnosCli,
195 name="startOnosCli-" + str( i ),
196 args=[nodes[i].ip_address] )
197 threads.append( t )
198 t.start()
199
200 for t in threads:
201 t.join()
202 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700203 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
204 onpass="ONOS cli startup successful",
205 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800206
Jon Hall6aec96b2015-01-19 14:49:31 -0800207 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800208 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800209 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
210 + "-MN.pcap",
211 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
212 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800213
Jon Hall390696c2015-05-05 17:13:41 -0700214 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700215 appCheck = main.TRUE
216 threads = []
217 for i in range( numControllers ):
218 t = main.Thread( target=CLIs[i].appToIDCheck,
219 name="appToIDCheck-" + str( i ),
220 args=[] )
221 threads.append( t )
222 t.start()
223
224 for t in threads:
225 t.join()
226 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700227 if appCheck != main.TRUE:
228 main.log.warn( CLIs[0].apps() )
229 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700230 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
231 onpass="App Ids seem to be correct",
232 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700233
Jon Hallfeff3082015-05-19 10:23:26 -0700234 if cliResults == main.FALSE:
235 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hall94fd0472014-12-08 11:52:42 -0800236 main.cleanup()
237 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800238
Jon Hall6aec96b2015-01-19 14:49:31 -0800239 def CASE2( self, main ):
240 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800241 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800242 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800243 import re
Jon Hall390696c2015-05-05 17:13:41 -0700244 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700245 assert numControllers, "numControllers not defined"
246 assert main, "main not defined"
247 assert utilities.assert_equals, "utilities.assert_equals not defined"
248 assert CLIs, "CLIs not defined"
249 assert nodes, "nodes not defined"
250 assert ONOS1Port, "ONOS1Port not defined"
251 assert ONOS2Port, "ONOS2Port not defined"
252 assert ONOS3Port, "ONOS3Port not defined"
253 assert ONOS4Port, "ONOS4Port not defined"
254 assert ONOS5Port, "ONOS5Port not defined"
255 assert ONOS6Port, "ONOS6Port not defined"
256 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800257
Jon Hall6aec96b2015-01-19 14:49:31 -0800258 main.case( "Assigning Controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700259 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
260 "and check that an ONOS node becomes the " +\
261 "master of the device. Then manually assign" +\
262 " mastership to specific ONOS nodes using" +\
263 " 'device-role'"
Jon Hall6aec96b2015-01-19 14:49:31 -0800264 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800265
Jon Hall5cfd23c2015-03-19 11:40:57 -0700266 # TODO: rewrite this function to take lists of ips and ports?
267 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800268 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800269 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800270 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800271 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700272 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
273 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
274 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
275 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
276 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
277 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
278 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800279
Jon Hall8f89dda2015-01-22 16:03:33 -0800280 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800281 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800282 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800283 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800284 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800285 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800286 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700287 for node in nodes:
288 if re.search( "tcp:" + node.ip_address, response ):
289 mastershipCheck = mastershipCheck and main.TRUE
290 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700291 main.log.error( "Error, node " + node.ip_address + " is " +
292 "not in the list of controllers s" +
293 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700294 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800295 utilities.assert_equals(
296 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800297 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800298 onpass="Switch mastership assigned correctly",
299 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700300
301 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800302 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800303 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700304
305 ipList = [ ]
306 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800307 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700308 for i in range( 1, 29 ): # switches 1 through 28
309 # set up correct variables:
310 if i == 1:
311 ip = nodes[ 0 ].ip_address # ONOS1
312 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
313 elif i == 2:
314 ip = nodes[ 1 ].ip_address # ONOS2
315 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
316 elif i == 3:
317 ip = nodes[ 1 ].ip_address # ONOS2
318 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
319 elif i == 4:
320 ip = nodes[ 3 ].ip_address # ONOS4
321 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
322 elif i == 5:
323 ip = nodes[ 2 ].ip_address # ONOS3
324 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
325 elif i == 6:
326 ip = nodes[ 2 ].ip_address # ONOS3
327 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
328 elif i == 7:
329 ip = nodes[ 5 ].ip_address # ONOS6
330 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
331 elif i >= 8 and i <= 17:
332 ip = nodes[ 4 ].ip_address # ONOS5
333 dpid = '3' + str( i ).zfill( 3 )
334 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
335 elif i >= 18 and i <= 27:
336 ip = nodes[ 6 ].ip_address # ONOS7
337 dpid = '6' + str( i ).zfill( 3 )
338 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
339 elif i == 28:
340 ip = nodes[ 0 ].ip_address # ONOS1
341 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
342 else:
343 main.log.error( "You didn't write an else statement for " +
344 "switch s" + str( i ) )
345 # Assign switch
346 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
347 # TODO: make this controller dynamic
348 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
349 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700350 ipList.append( ip )
351 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800352 except ( AttributeError, AssertionError ):
353 main.log.exception( "Something is wrong with ONOS device view" )
354 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800355 utilities.assert_equals(
356 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800357 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800358 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800359 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800360
Jon Hall390696c2015-05-05 17:13:41 -0700361 main.step( "Check mastership was correctly assigned" )
362 roleCheck = main.TRUE
363 # NOTE: This is due to the fact that device mastership change is not
364 # atomic and is actually a multi step process
365 time.sleep( 5 )
366 for i in range( len( ipList ) ):
367 ip = ipList[i]
368 deviceId = deviceList[i]
369 # Check assignment
370 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
371 if ip in master:
372 roleCheck = roleCheck and main.TRUE
373 else:
374 roleCheck = roleCheck and main.FALSE
375 main.log.error( "Error, controller " + ip + " is not" +
376 " master " + "of device " +
377 str( deviceId ) + ". Master is " +
378 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800379 utilities.assert_equals(
380 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800381 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800382 onpass="Switches were successfully reassigned to designated " +
383 "controller",
384 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800385 mastershipCheck = mastershipCheck and roleCall and roleCheck
386 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800387 onpass="Switch mastership correctly assigned",
388 onfail="Error in (re)assigning switch" +
389 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800390
Jon Hall6aec96b2015-01-19 14:49:31 -0800391 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800392 """
393 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800394 """
395 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800396 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700397 assert numControllers, "numControllers not defined"
398 assert main, "main not defined"
399 assert utilities.assert_equals, "utilities.assert_equals not defined"
400 assert CLIs, "CLIs not defined"
401 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800402 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700403 main.caseExplaination = "Discover hosts by using pingall then " +\
404 "assign predetermined host-to-host intents." +\
405 " After installation, check that the intent" +\
406 " is distributed to all nodes and the state" +\
407 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800408
Jon Hall6aec96b2015-01-19 14:49:31 -0800409 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700410 main.step( "Install reactive forwarding app" )
411 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
412 utilities.assert_equals( expect=main.TRUE, actual=installResults,
413 onpass="Install fwd successful",
414 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700415
Jon Hallfeff3082015-05-19 10:23:26 -0700416 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700417 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700418 threads = []
419 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700420 t = main.Thread( target=CLIs[i].appToIDCheck,
421 name="appToIDCheck-" + str( i ),
422 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700423 threads.append( t )
424 t.start()
425
426 for t in threads:
427 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700428 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700429 if appCheck != main.TRUE:
430 main.log.warn( CLIs[0].apps() )
431 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700432 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
433 onpass="App Ids seem to be correct",
434 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800435
Jon Hallfeff3082015-05-19 10:23:26 -0700436 main.step( "Discovering Hosts( Via pingall for now )" )
437 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800438 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800439 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700440 for i in range(2): # Retry if pingall fails first time
441 time1 = time.time()
442 pingResult = main.Mininet1.pingall()
443 utilities.assert_equals(
444 expect=main.TRUE,
445 actual=pingResult,
446 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700447 onfail="Reactive Pingall failed, " +
448 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700449 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700450 main.log.info( "Time for pingall: %2f seconds" %
451 ( time2 - time1 ) )
452 # timeout for fwd flows
453 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800454 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700455 main.step( "Uninstall reactive forwarding app" )
456 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
457 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
458 onpass="Uninstall fwd successful",
459 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700460
461 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700462 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700463 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700464 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700465 t = main.Thread( target=CLIs[i].appToIDCheck,
466 name="appToIDCheck-" + str( i ),
467 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700468 threads.append( t )
469 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800470
Jon Hall5cfd23c2015-03-19 11:40:57 -0700471 for t in threads:
472 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700473 appCheck2 = appCheck2 and t.result
474 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700475 main.log.warn( CLIs[0].apps() )
476 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700477 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700478 onpass="App Ids seem to be correct",
479 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700480
Jon Hallfeff3082015-05-19 10:23:26 -0700481 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800482 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800483 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800484 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800485 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800486 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800487 for i in range( 8, 18 ):
488 main.log.info( "Adding host intent between h" + str( i ) +
489 " and h" + str( i + 10 ) )
490 host1 = "00:00:00:00:00:" + \
491 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
492 host2 = "00:00:00:00:00:" + \
493 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800494 # NOTE: getHost can return None
495 host1Dict = main.ONOScli1.getHost( host1 )
496 host2Dict = main.ONOScli1.getHost( host2 )
497 host1Id = None
498 host2Id = None
499 if host1Dict and host2Dict:
500 host1Id = host1Dict.get( 'id', None )
501 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800502 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700503 nodeNum = ( i % 7 )
504 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800505 if tmpId:
506 main.log.info( "Added intent with id: " + tmpId )
507 intentIds.append( tmpId )
508 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700509 main.log.error( "addHostIntent returned: " +
510 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800511 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700512 main.log.error( "Error, getHost() failed for h" + str( i ) +
513 " and/or h" + str( i + 10 ) )
514 hosts = CLIs[ 0 ].hosts()
515 main.log.warn( "Hosts output: " )
516 try:
517 main.log.warn( json.dumps( json.loads( hosts ),
518 sort_keys=True,
519 indent=4,
520 separators=( ',', ': ' ) ) )
521 except ( ValueError, TypeError ):
522 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800523 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700524 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
525 onpass="Found a host id for each host",
526 onfail="Error looking up host ids" )
527
Jon Halla9d26da2015-03-30 16:45:32 -0700528 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800529 onosIds = main.ONOScli1.getAllIntentsId()
530 main.log.info( "Submitted intents: " + str( intentIds ) )
531 main.log.info( "Intents in ONOS: " + str( onosIds ) )
532 for intent in intentIds:
533 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700534 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800535 else:
536 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700537 # FIXME: DEBUG
538 if intentAddResult:
539 intentStop = time.time()
540 else:
541 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800542 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800543 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800544 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700545 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800546 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
547 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700548 try:
549 for intent in json.loads( intents ):
550 state = intent.get( 'state', None )
551 if "INSTALLED" not in state:
552 installedCheck = False
553 intentId = intent.get( 'id', None )
554 intentStates.append( ( intentId, state ) )
555 except ( ValueError, TypeError ):
556 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800557 # add submitted intents not in the store
558 tmplist = [ i for i, s in intentStates ]
559 missingIntents = False
560 for i in intentIds:
561 if i not in tmplist:
562 intentStates.append( ( i, " - " ) )
563 missingIntents = True
564 intentStates.sort()
565 for i, s in intentStates:
566 count += 1
567 main.log.info( "%-6s%-15s%-15s" %
568 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700569 leaders = main.ONOScli1.leaders()
570 try:
571 if leaders:
572 parsedLeaders = json.loads( leaders )
573 main.log.warn( json.dumps( parsedLeaders,
574 sort_keys=True,
575 indent=4,
576 separators=( ',', ': ' ) ) )
577 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700578 topics = []
579 for i in range( 14 ):
580 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700581 main.log.debug( topics )
582 ONOStopics = [ j['topic'] for j in parsedLeaders ]
583 for topic in topics:
584 if topic not in ONOStopics:
585 main.log.error( "Error: " + topic +
586 " not in leaders" )
587 else:
588 main.log.error( "leaders() returned None" )
589 except ( ValueError, TypeError ):
590 main.log.exception( "Error parsing leaders" )
591 main.log.error( repr( leaders ) )
592 partitions = main.ONOScli1.partitions()
593 try:
594 if partitions :
595 parsedPartitions = json.loads( partitions )
596 main.log.warn( json.dumps( parsedPartitions,
597 sort_keys=True,
598 indent=4,
599 separators=( ',', ': ' ) ) )
600 # TODO check for a leader in all paritions
601 # TODO check for consistency among nodes
602 else:
603 main.log.error( "partitions() returned None" )
604 except ( ValueError, TypeError ):
605 main.log.exception( "Error parsing partitions" )
606 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800607 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700608 try:
609 if pendingMap :
610 parsedPending = json.loads( pendingMap )
611 main.log.warn( json.dumps( parsedPending,
612 sort_keys=True,
613 indent=4,
614 separators=( ',', ': ' ) ) )
615 # TODO check something here?
616 else:
617 main.log.error( "pendingMap() returned None" )
618 except ( ValueError, TypeError ):
619 main.log.exception( "Error parsing pending map" )
620 main.log.error( repr( pendingMap ) )
621
Jon Hallfeff3082015-05-19 10:23:26 -0700622 intentAddResult = bool( intentAddResult and not missingIntents and
623 installedCheck )
624 if not intentAddResult:
625 main.log.error( "Error in pushing host intents to ONOS" )
626
Jon Hall390696c2015-05-05 17:13:41 -0700627 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700628 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700629 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700630 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700631 for cli in CLIs:
632 onosIds = []
633 ids = cli.getAllIntentsId()
634 onosIds.append( ids )
635 main.log.debug( "Intents in " + cli.name + ": " +
636 str( sorted( onosIds ) ) )
637 if sorted( ids ) != sorted( intentIds ):
638 correct = False
639 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700640 break
641 else:
642 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700643 if not intentStop:
644 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700645 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700646 gossipTime = intentStop - intentStart
647 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700648 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700649 # FIXME: make this time configurable/calculate based off of number of
650 # nodes and gossip rounds
651 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700652 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700653 onpass="ECM anti-entropy for intents worked within " +
654 "expected time",
655 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700656 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700657 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800658
Jon Hall63604932015-02-26 17:09:50 -0800659 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800660 import time
Jon Hall63604932015-02-26 17:09:50 -0800661 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800662 main.log.info( "Sleeping 60 seconds to see if intents are found" )
663 time.sleep( 60 )
664 onosIds = main.ONOScli1.getAllIntentsId()
665 main.log.info( "Submitted intents: " + str( intentIds ) )
666 main.log.info( "Intents in ONOS: " + str( onosIds ) )
667 # Print the intent states
668 intents = main.ONOScli1.intents()
669 intentStates = []
670 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
671 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700672 try:
673 for intent in json.loads( intents ):
674 # Iter through intents of a node
675 state = intent.get( 'state', None )
676 if "INSTALLED" not in state:
677 installedCheck = False
678 intentId = intent.get( 'id', None )
679 intentStates.append( ( intentId, state ) )
680 except ( ValueError, TypeError ):
681 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800682 # add submitted intents not in the store
683 tmplist = [ i for i, s in intentStates ]
684 for i in intentIds:
685 if i not in tmplist:
686 intentStates.append( ( i, " - " ) )
687 intentStates.sort()
688 for i, s in intentStates:
689 count += 1
690 main.log.info( "%-6s%-15s%-15s" %
691 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700692 leaders = main.ONOScli1.leaders()
693 try:
694 if leaders:
695 parsedLeaders = json.loads( leaders )
696 main.log.warn( json.dumps( parsedLeaders,
697 sort_keys=True,
698 indent=4,
699 separators=( ',', ': ' ) ) )
700 # check for all intent partitions
701 # check for election
702 topics = []
703 for i in range( 14 ):
704 topics.append( "intent-partition-" + str( i ) )
705 # FIXME: this should only be after we start the app
706 topics.append( "org.onosproject.election" )
707 main.log.debug( topics )
708 ONOStopics = [ j['topic'] for j in parsedLeaders ]
709 for topic in topics:
710 if topic not in ONOStopics:
711 main.log.error( "Error: " + topic +
712 " not in leaders" )
713 else:
714 main.log.error( "leaders() returned None" )
715 except ( ValueError, TypeError ):
716 main.log.exception( "Error parsing leaders" )
717 main.log.error( repr( leaders ) )
718 partitions = main.ONOScli1.partitions()
719 try:
720 if partitions :
721 parsedPartitions = json.loads( partitions )
722 main.log.warn( json.dumps( parsedPartitions,
723 sort_keys=True,
724 indent=4,
725 separators=( ',', ': ' ) ) )
726 # TODO check for a leader in all paritions
727 # TODO check for consistency among nodes
728 else:
729 main.log.error( "partitions() returned None" )
730 except ( ValueError, TypeError ):
731 main.log.exception( "Error parsing partitions" )
732 main.log.error( repr( partitions ) )
733 pendingMap = main.ONOScli1.pendingMap()
734 try:
735 if pendingMap :
736 parsedPending = json.loads( pendingMap )
737 main.log.warn( json.dumps( parsedPending,
738 sort_keys=True,
739 indent=4,
740 separators=( ',', ': ' ) ) )
741 # TODO check something here?
742 else:
743 main.log.error( "pendingMap() returned None" )
744 except ( ValueError, TypeError ):
745 main.log.exception( "Error parsing pending map" )
746 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800747
Jon Hall6aec96b2015-01-19 14:49:31 -0800748 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800749 """
750 Ping across added host intents
751 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800752 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700753 import time
754 assert numControllers, "numControllers not defined"
755 assert main, "main not defined"
756 assert utilities.assert_equals, "utilities.assert_equals not defined"
757 assert CLIs, "CLIs not defined"
758 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700759 main.case( "Verify connectivity by sendind traffic across Intents" )
760 main.caseExplaination = "Ping across added host intents to check " +\
761 "functionality and check the state of " +\
762 "the intent"
763 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800764 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800765 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800766 ping = main.Mininet1.pingHost( src="h" + str( i ),
767 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800768 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800769 if ping == main.FALSE:
770 main.log.warn( "Ping failed between h" + str( i ) +
771 " and h" + str( i + 10 ) )
772 elif ping == main.TRUE:
773 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800774 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800775 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800776 main.log.report(
777 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800778 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700779 main.log.warn( "ONOS1 intents: " )
780 try:
781 tmpIntents = main.ONOScli1.intents()
782 main.log.warn( json.dumps( json.loads( tmpIntents ),
783 sort_keys=True,
784 indent=4,
785 separators=( ',', ': ' ) ) )
786 except ( ValueError, TypeError ):
787 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800788 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800789 main.log.report(
790 "Intents have been installed correctly and verified by pings" )
791 utilities.assert_equals(
792 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800793 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800794 onpass="Intents have been installed correctly and pings work",
795 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800796
Jon Hallfeff3082015-05-19 10:23:26 -0700797 main.step( "Check Intent state" )
Jon Hall63604932015-02-26 17:09:50 -0800798 installedCheck = True
Jon Hallfeff3082015-05-19 10:23:26 -0700799 # Print the intent states
800 intents = main.ONOScli1.intents()
801 intentStates = []
802 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
803 count = 0
804 # Iter through intents of a node
805 try:
806 for intent in json.loads( intents ):
807 state = intent.get( 'state', None )
808 if "INSTALLED" not in state:
809 installedCheck = False
810 intentId = intent.get( 'id', None )
811 intentStates.append( ( intentId, state ) )
812 except ( ValueError, TypeError ):
813 main.log.exception( "Error parsing intents." )
814 # Print states
815 intentStates.sort()
816 for i, s in intentStates:
817 count += 1
818 main.log.info( "%-6s%-15s%-15s" %
819 ( str( count ), str( i ), str( s ) ) )
820 utilities.assert_equals( expect=True, actual=installedCheck,
821 onpass="Intents are all INSTALLED",
822 onfail="Intents are not all in " +\
823 "INSTALLED state" )
824
825 main.step( "Check leadership of topics" )
826 leaders = main.ONOScli1.leaders()
827 topicCheck = main.TRUE
828 try:
829 if leaders:
830 parsedLeaders = json.loads( leaders )
831 main.log.warn( json.dumps( parsedLeaders,
832 sort_keys=True,
833 indent=4,
834 separators=( ',', ': ' ) ) )
835 # check for all intent partitions
836 # check for election
837 # TODO: Look at Devices as topics now that it uses this system
838 topics = []
839 for i in range( 14 ):
840 topics.append( "intent-partition-" + str( i ) )
841 # FIXME: this should only be after we start the app
842 # FIXME: topics.append( "org.onosproject.election" )
843 # Print leaders output
844 main.log.debug( topics )
845 ONOStopics = [ j['topic'] for j in parsedLeaders ]
846 for topic in topics:
847 if topic not in ONOStopics:
848 main.log.error( "Error: " + topic +
849 " not in leaders" )
850 topicCheck = main.FALSE
851 else:
852 main.log.error( "leaders() returned None" )
853 topicCheck = main.FALSE
854 except ( ValueError, TypeError ):
855 topicCheck = main.FALSE
856 main.log.exception( "Error parsing leaders" )
857 main.log.error( repr( leaders ) )
858 # TODO: Check for a leader of these topics
859 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
860 onpass="intent Partitions is in leaders",
861 onfail="Some topics were lost " )
862 # Print partitions
863 partitions = main.ONOScli1.partitions()
864 try:
865 if partitions :
866 parsedPartitions = json.loads( partitions )
867 main.log.warn( json.dumps( parsedPartitions,
868 sort_keys=True,
869 indent=4,
870 separators=( ',', ': ' ) ) )
871 # TODO check for a leader in all paritions
872 # TODO check for consistency among nodes
873 else:
874 main.log.error( "partitions() returned None" )
875 except ( ValueError, TypeError ):
876 main.log.exception( "Error parsing partitions" )
877 main.log.error( repr( partitions ) )
878 # Print Pending Map
879 pendingMap = main.ONOScli1.pendingMap()
880 try:
881 if pendingMap :
882 parsedPending = json.loads( pendingMap )
883 main.log.warn( json.dumps( parsedPending,
884 sort_keys=True,
885 indent=4,
886 separators=( ',', ': ' ) ) )
887 # TODO check something here?
888 else:
889 main.log.error( "pendingMap() returned None" )
890 except ( ValueError, TypeError ):
891 main.log.exception( "Error parsing pending map" )
892 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700893
Jon Hall63604932015-02-26 17:09:50 -0800894 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700895 main.log.info( "Waiting 60 seconds to see if the state of " +
896 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800897 time.sleep( 60 )
898 # Print the intent states
899 intents = main.ONOScli1.intents()
900 intentStates = []
901 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
902 count = 0
903 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700904 try:
905 for intent in json.loads( intents ):
906 state = intent.get( 'state', None )
907 if "INSTALLED" not in state:
908 installedCheck = False
909 intentId = intent.get( 'id', None )
910 intentStates.append( ( intentId, state ) )
911 except ( ValueError, TypeError ):
912 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800913 intentStates.sort()
914 for i, s in intentStates:
915 count += 1
916 main.log.info( "%-6s%-15s%-15s" %
917 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700918 leaders = main.ONOScli1.leaders()
919 try:
920 if leaders:
921 parsedLeaders = json.loads( leaders )
922 main.log.warn( json.dumps( parsedLeaders,
923 sort_keys=True,
924 indent=4,
925 separators=( ',', ': ' ) ) )
926 # check for all intent partitions
927 # check for election
928 topics = []
929 for i in range( 14 ):
930 topics.append( "intent-partition-" + str( i ) )
931 # FIXME: this should only be after we start the app
932 topics.append( "org.onosproject.election" )
933 main.log.debug( topics )
934 ONOStopics = [ j['topic'] for j in parsedLeaders ]
935 for topic in topics:
936 if topic not in ONOStopics:
937 main.log.error( "Error: " + topic +
938 " not in leaders" )
939 else:
940 main.log.error( "leaders() returned None" )
941 except ( ValueError, TypeError ):
942 main.log.exception( "Error parsing leaders" )
943 main.log.error( repr( leaders ) )
944 partitions = main.ONOScli1.partitions()
945 try:
946 if partitions :
947 parsedPartitions = json.loads( partitions )
948 main.log.warn( json.dumps( parsedPartitions,
949 sort_keys=True,
950 indent=4,
951 separators=( ',', ': ' ) ) )
952 # TODO check for a leader in all paritions
953 # TODO check for consistency among nodes
954 else:
955 main.log.error( "partitions() returned None" )
956 except ( ValueError, TypeError ):
957 main.log.exception( "Error parsing partitions" )
958 main.log.error( repr( partitions ) )
959 pendingMap = main.ONOScli1.pendingMap()
960 try:
961 if pendingMap :
962 parsedPending = json.loads( pendingMap )
963 main.log.warn( json.dumps( parsedPending,
964 sort_keys=True,
965 indent=4,
966 separators=( ',', ': ' ) ) )
967 # TODO check something here?
968 else:
969 main.log.error( "pendingMap() returned None" )
970 except ( ValueError, TypeError ):
971 main.log.exception( "Error parsing pending map" )
972 main.log.error( repr( pendingMap ) )
Jon Hall390696c2015-05-05 17:13:41 -0700973 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800974
Jon Hallfeff3082015-05-19 10:23:26 -0700975 main.step( "Wait a minute then ping again" )
976 PingResult = main.TRUE
977 for i in range( 8, 18 ):
978 ping = main.Mininet1.pingHost( src="h" + str( i ),
979 target="h" + str( i + 10 ) )
980 PingResult = PingResult and ping
981 if ping == main.FALSE:
982 main.log.warn( "Ping failed between h" + str( i ) +
983 " and h" + str( i + 10 ) )
984 elif ping == main.TRUE:
985 main.log.info( "Ping test passed!" )
986 # Don't set PingResult or you'd override failures
987 if PingResult == main.FALSE:
988 main.log.report(
989 "Intents have not been installed correctly, pings failed." )
990 # TODO: pretty print
991 main.log.warn( "ONOS1 intents: " )
992 try:
993 tmpIntents = main.ONOScli1.intents()
994 main.log.warn( json.dumps( json.loads( tmpIntents ),
995 sort_keys=True,
996 indent=4,
997 separators=( ',', ': ' ) ) )
998 except ( ValueError, TypeError ):
999 main.log.warn( repr( tmpIntents ) )
1000 utilities.assert_equals(
1001 expect=main.TRUE,
1002 actual=PingResult,
1003 onpass="Intents have been installed correctly and pings work",
1004 onfail="Intents have not been installed correctly, pings failed." )
1005
Jon Hall6aec96b2015-01-19 14:49:31 -08001006 def CASE5( self, main ):
1007 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001008 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001009 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001010 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001011 import time
1012 assert numControllers, "numControllers not defined"
1013 assert main, "main not defined"
1014 assert utilities.assert_equals, "utilities.assert_equals not defined"
1015 assert CLIs, "CLIs not defined"
1016 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001017 # assumes that sts is already in you PYTHONPATH
1018 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001019
Jon Hall6aec96b2015-01-19 14:49:31 -08001020 main.case( "Setting up and gathering data for current state" )
1021 # The general idea for this test case is to pull the state of
1022 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001023 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001024
Jon Hall5cfd23c2015-03-19 11:40:57 -07001025 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001026 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001027 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001028
Jon Hall6aec96b2015-01-19 14:49:31 -08001029 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001030 rolesNotNull = main.TRUE
1031 threads = []
1032 for i in range( numControllers ):
1033 t = main.Thread( target=CLIs[i].rolesNotNull,
1034 name="rolesNotNull-" + str( i ),
1035 args=[] )
1036 threads.append( t )
1037 t.start()
1038
1039 for t in threads:
1040 t.join()
1041 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001042 utilities.assert_equals(
1043 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001044 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001045 onpass="Each device has a master",
1046 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001047
Jon Hall5cfd23c2015-03-19 11:40:57 -07001048 main.step( "Get the Mastership of each switch from each controller" )
1049 ONOSMastership = []
1050 mastershipCheck = main.FALSE
1051 consistentMastership = True
1052 rolesResults = True
1053 threads = []
1054 for i in range( numControllers ):
1055 t = main.Thread( target=CLIs[i].roles,
1056 name="roles-" + str( i ),
1057 args=[] )
1058 threads.append( t )
1059 t.start()
1060
1061 for t in threads:
1062 t.join()
1063 ONOSMastership.append( t.result )
1064
1065 for i in range( numControllers ):
1066 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1067 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1068 " roles" )
1069 main.log.warn(
1070 "ONOS" + str( i + 1 ) + " mastership response: " +
1071 repr( ONOSMastership[i] ) )
1072 rolesResults = False
1073 utilities.assert_equals(
1074 expect=True,
1075 actual=rolesResults,
1076 onpass="No error in reading roles output",
1077 onfail="Error in reading roles from ONOS" )
1078
1079 main.step( "Check for consistency in roles from each controller" )
1080 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001081 main.log.report(
1082 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001083 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001084 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001085 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001086 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001087 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001088 onpass="Switch roles are consistent across all ONOS nodes",
1089 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001090
Jon Hall5cfd23c2015-03-19 11:40:57 -07001091 if rolesResults and not consistentMastership:
1092 for i in range( numControllers ):
1093 try:
1094 main.log.warn(
1095 "ONOS" + str( i + 1 ) + " roles: ",
1096 json.dumps(
1097 json.loads( ONOSMastership[ i ] ),
1098 sort_keys=True,
1099 indent=4,
1100 separators=( ',', ': ' ) ) )
1101 except ( ValueError, TypeError ):
1102 main.log.warn( repr( ONOSMastership[ i ] ) )
1103 elif rolesResults and consistentMastership:
1104 mastershipCheck = main.TRUE
1105 mastershipState = ONOSMastership[ 0 ]
1106
Jon Hall6aec96b2015-01-19 14:49:31 -08001107 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001108 global intentState
1109 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001110 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001111 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001112 consistentIntents = True
1113 intentsResults = True
1114 threads = []
1115 for i in range( numControllers ):
1116 t = main.Thread( target=CLIs[i].intents,
1117 name="intents-" + str( i ),
1118 args=[],
1119 kwargs={ 'jsonFormat': True } )
1120 threads.append( t )
1121 t.start()
1122
1123 for t in threads:
1124 t.join()
1125 ONOSIntents.append( t.result )
1126
1127 for i in range( numControllers ):
1128 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1129 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1130 " intents" )
1131 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1132 repr( ONOSIntents[ i ] ) )
1133 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001134 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001135 expect=True,
1136 actual=intentsResults,
1137 onpass="No error in reading intents output",
1138 onfail="Error in reading intents from ONOS" )
1139
1140 main.step( "Check for consistency in Intents from each controller" )
1141 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1142 main.log.report( "Intents are consistent across all ONOS " +
1143 "nodes" )
1144 else:
1145 consistentIntents = False
1146 main.log.report( "Intents not consistent" )
1147 utilities.assert_equals(
1148 expect=True,
1149 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001150 onpass="Intents are consistent across all ONOS nodes",
1151 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001152
Jon Hall390696c2015-05-05 17:13:41 -07001153 if intentsResults:
1154 # Try to make it easy to figure out what is happening
1155 #
1156 # Intent ONOS1 ONOS2 ...
1157 # 0x01 INSTALLED INSTALLING
1158 # ... ... ...
1159 # ... ... ...
1160 title = " Id"
1161 for n in range( numControllers ):
1162 title += " " * 10 + "ONOS" + str( n + 1 )
1163 main.log.warn( title )
1164 # get all intent keys in the cluster
1165 keys = []
1166 for nodeStr in ONOSIntents:
1167 node = json.loads( nodeStr )
1168 for intent in node:
1169 keys.append( intent.get( 'id' ) )
1170 keys = set( keys )
1171 for key in keys:
1172 row = "%-13s" % key
1173 for nodeStr in ONOSIntents:
1174 node = json.loads( nodeStr )
1175 for intent in node:
1176 if intent.get( 'id', "Error" ) == key:
1177 row += "%-15s" % intent.get( 'state' )
1178 main.log.warn( row )
1179 # End table view
1180
Jon Hall5cfd23c2015-03-19 11:40:57 -07001181 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001182 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001183 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001184 main.log.debug( "ONOS" + str( n ) + " intents: " )
1185 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1186 sort_keys=True,
1187 indent=4,
1188 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001189 for i in range( numControllers ):
1190 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001191 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1192 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1193 sort_keys=True,
1194 indent=4,
1195 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001196 else:
Jon Hall390696c2015-05-05 17:13:41 -07001197 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1198 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001199 elif intentsResults and consistentIntents:
1200 intentCheck = main.TRUE
1201 intentState = ONOSIntents[ 0 ]
1202
Jon Hall6aec96b2015-01-19 14:49:31 -08001203 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001204 global flowState
1205 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001206 ONOSFlows = []
1207 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001208 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001209 consistentFlows = True
1210 flowsResults = True
1211 threads = []
1212 for i in range( numControllers ):
1213 t = main.Thread( target=CLIs[i].flows,
1214 name="flows-" + str( i ),
1215 args=[],
1216 kwargs={ 'jsonFormat': True } )
1217 threads.append( t )
1218 t.start()
1219
Jon Halla9d26da2015-03-30 16:45:32 -07001220 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001221 time.sleep(30)
1222 for t in threads:
1223 t.join()
1224 result = t.result
1225 ONOSFlows.append( result )
1226
1227 for i in range( numControllers ):
1228 num = str( i + 1 )
1229 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1230 main.log.report( "Error in getting ONOS" + num + " flows" )
1231 main.log.warn( "ONOS" + num + " flows response: " +
1232 repr( ONOSFlows[ i ] ) )
1233 flowsResults = False
1234 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001235 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001236 try:
1237 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1238 except ( ValueError, TypeError ):
1239 # FIXME: change this to log.error?
1240 main.log.exception( "Error in parsing ONOS" + num +
1241 " response as json." )
1242 main.log.error( repr( ONOSFlows[ i ] ) )
1243 ONOSFlowsJson.append( None )
1244 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001245 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001246 expect=True,
1247 actual=flowsResults,
1248 onpass="No error in reading flows output",
1249 onfail="Error in reading flows from ONOS" )
1250
1251 main.step( "Check for consistency in Flows from each controller" )
1252 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1253 if all( tmp ):
1254 main.log.report( "Flow count is consistent across all ONOS nodes" )
1255 else:
1256 consistentFlows = False
1257 utilities.assert_equals(
1258 expect=True,
1259 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001260 onpass="The flow count is consistent across all ONOS nodes",
1261 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001262
Jon Hall5cfd23c2015-03-19 11:40:57 -07001263 if flowsResults and not consistentFlows:
1264 for i in range( numControllers ):
1265 try:
1266 main.log.warn(
1267 "ONOS" + str( i + 1 ) + " flows: " +
1268 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1269 indent=4, separators=( ',', ': ' ) ) )
1270 except ( ValueError, TypeError ):
1271 main.log.warn(
1272 "ONOS" + str( i + 1 ) + " flows: " +
1273 repr( ONOSFlows[ i ] ) )
1274 elif flowsResults and consistentFlows:
1275 flowCheck = main.TRUE
1276 flowState = ONOSFlows[ 0 ]
1277
Jon Hall6aec96b2015-01-19 14:49:31 -08001278 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001279 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001280 flows = []
1281 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001282 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001283 if flowCheck == main.FALSE:
1284 for table in flows:
1285 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001286 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001287
Jon Hall6aec96b2015-01-19 14:49:31 -08001288 main.step( "Start continuous pings" )
1289 main.Mininet2.pingLong(
1290 src=main.params[ 'PING' ][ 'source1' ],
1291 target=main.params[ 'PING' ][ 'target1' ],
1292 pingTime=500 )
1293 main.Mininet2.pingLong(
1294 src=main.params[ 'PING' ][ 'source2' ],
1295 target=main.params[ 'PING' ][ 'target2' ],
1296 pingTime=500 )
1297 main.Mininet2.pingLong(
1298 src=main.params[ 'PING' ][ 'source3' ],
1299 target=main.params[ 'PING' ][ 'target3' ],
1300 pingTime=500 )
1301 main.Mininet2.pingLong(
1302 src=main.params[ 'PING' ][ 'source4' ],
1303 target=main.params[ 'PING' ][ 'target4' ],
1304 pingTime=500 )
1305 main.Mininet2.pingLong(
1306 src=main.params[ 'PING' ][ 'source5' ],
1307 target=main.params[ 'PING' ][ 'target5' ],
1308 pingTime=500 )
1309 main.Mininet2.pingLong(
1310 src=main.params[ 'PING' ][ 'source6' ],
1311 target=main.params[ 'PING' ][ 'target6' ],
1312 pingTime=500 )
1313 main.Mininet2.pingLong(
1314 src=main.params[ 'PING' ][ 'source7' ],
1315 target=main.params[ 'PING' ][ 'target7' ],
1316 pingTime=500 )
1317 main.Mininet2.pingLong(
1318 src=main.params[ 'PING' ][ 'source8' ],
1319 target=main.params[ 'PING' ][ 'target8' ],
1320 pingTime=500 )
1321 main.Mininet2.pingLong(
1322 src=main.params[ 'PING' ][ 'source9' ],
1323 target=main.params[ 'PING' ][ 'target9' ],
1324 pingTime=500 )
1325 main.Mininet2.pingLong(
1326 src=main.params[ 'PING' ][ 'source10' ],
1327 target=main.params[ 'PING' ][ 'target10' ],
1328 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001329
Jon Hall6aec96b2015-01-19 14:49:31 -08001330 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001331 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001332 for node in nodes:
1333 temp = ( node, node.name, node.ip_address, 6633 )
1334 ctrls.append( temp )
1335 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001336
Jon Hall6aec96b2015-01-19 14:49:31 -08001337 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001338 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001339 threads = []
1340 for i in range( numControllers ):
1341 t = main.Thread( target=CLIs[i].devices,
1342 name="devices-" + str( i ),
1343 args=[ ] )
1344 threads.append( t )
1345 t.start()
1346
1347 for t in threads:
1348 t.join()
1349 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001350 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001351 threads = []
1352 for i in range( numControllers ):
1353 t = main.Thread( target=CLIs[i].hosts,
1354 name="hosts-" + str( i ),
1355 args=[ ] )
1356 threads.append( t )
1357 t.start()
1358
1359 for t in threads:
1360 t.join()
1361 try:
1362 hosts.append( json.loads( t.result ) )
1363 except ( ValueError, TypeError ):
1364 # FIXME: better handling of this, print which node
1365 # Maybe use thread name?
1366 main.log.exception( "Error parsing json output of hosts" )
1367 # FIXME: should this be an empty json object instead?
1368 hosts.append( None )
1369
Jon Hall73cf9cc2014-11-20 22:28:38 -08001370 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001371 threads = []
1372 for i in range( numControllers ):
1373 t = main.Thread( target=CLIs[i].ports,
1374 name="ports-" + str( i ),
1375 args=[ ] )
1376 threads.append( t )
1377 t.start()
1378
1379 for t in threads:
1380 t.join()
1381 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001382 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001383 threads = []
1384 for i in range( numControllers ):
1385 t = main.Thread( target=CLIs[i].links,
1386 name="links-" + str( i ),
1387 args=[ ] )
1388 threads.append( t )
1389 t.start()
1390
1391 for t in threads:
1392 t.join()
1393 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001394 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001395 threads = []
1396 for i in range( numControllers ):
1397 t = main.Thread( target=CLIs[i].clusters,
1398 name="clusters-" + str( i ),
1399 args=[ ] )
1400 threads.append( t )
1401 t.start()
1402
1403 for t in threads:
1404 t.join()
1405 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001406 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001407
Jon Hall6aec96b2015-01-19 14:49:31 -08001408 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001409 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001410 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001411 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001412 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001413 if "Error" not in hosts[ controller ]:
1414 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001415 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001416 else: # hosts not consistent
1417 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001418 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001419 " is inconsistent with ONOS1" )
1420 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001421 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001422
1423 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001424 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001425 controllerStr )
1426 consistentHostsResult = main.FALSE
1427 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001428 " hosts response: " +
1429 repr( hosts[ controller ] ) )
1430 utilities.assert_equals(
1431 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001432 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001433 onpass="Hosts view is consistent across all ONOS nodes",
1434 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001435
Jon Hall390696c2015-05-05 17:13:41 -07001436 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001437 ipResult = main.TRUE
1438 for controller in range( 0, len( hosts ) ):
1439 controllerStr = str( controller + 1 )
1440 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001441 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001442 main.log.error( "DEBUG:Error with host ips on controller" +
1443 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001444 ipResult = main.FALSE
1445 utilities.assert_equals(
1446 expect=main.TRUE,
1447 actual=ipResult,
1448 onpass="The ips of the hosts aren't empty",
1449 onfail="The ip of at least one host is missing" )
1450
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001452 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001453 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001454 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001455 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001456 if "Error" not in clusters[ controller ]:
1457 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001458 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001459 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001460 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001461 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001462 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001463
1464 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001465 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001466 "from ONOS" + controllerStr )
1467 consistentClustersResult = main.FALSE
1468 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001469 " clusters response: " +
1470 repr( clusters[ controller ] ) )
1471 utilities.assert_equals(
1472 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001473 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001474 onpass="Clusters view is consistent across all ONOS nodes",
1475 onfail="ONOS nodes have different views of clusters" )
1476 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001477 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001478 try:
1479 numClusters = len( json.loads( clusters[ 0 ] ) )
1480 except ( ValueError, TypeError ):
1481 main.log.exception( "Error parsing clusters[0]: " +
1482 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001483 clusterResults = main.FALSE
1484 if numClusters == 1:
1485 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001486 utilities.assert_equals(
1487 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001488 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001490 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001491
Jon Hall6aec96b2015-01-19 14:49:31 -08001492 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001493 devicesResults = main.TRUE
1494 portsResults = main.TRUE
1495 linksResults = main.TRUE
1496 for controller in range( numControllers ):
1497 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001498 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001499 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001500 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001501 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001502 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001503 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001504 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001505 actual=currentDevicesResult,
1506 onpass="ONOS" + controllerStr +
1507 " Switches view is correct",
1508 onfail="ONOS" + controllerStr +
1509 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001510
Jon Hall6aec96b2015-01-19 14:49:31 -08001511 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001512 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001513 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001514 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001515 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001516 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001517 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001518 actual=currentPortsResult,
1519 onpass="ONOS" + controllerStr +
1520 " ports view is correct",
1521 onfail="ONOS" + controllerStr +
1522 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001523
Jon Hall6aec96b2015-01-19 14:49:31 -08001524 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001525 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001526 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001527 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001528 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001529 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001530 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001531 actual=currentLinksResult,
1532 onpass="ONOS" + controllerStr +
1533 " links view is correct",
1534 onfail="ONOS" + controllerStr +
1535 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001536
Jon Hall8f89dda2015-01-22 16:03:33 -08001537 devicesResults = devicesResults and currentDevicesResult
1538 portsResults = portsResults and currentPortsResult
1539 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001540
Jon Hall5cfd23c2015-03-19 11:40:57 -07001541 topoResult = ( devicesResults and portsResults and linksResults
1542 and consistentHostsResult and consistentClustersResult
1543 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001544 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001545 onpass="Topology Check Test successful",
1546 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001547
Jon Hall6aec96b2015-01-19 14:49:31 -08001548 def CASE6( self, main ):
1549 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001550 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 """
Jon Hall94fd0472014-12-08 11:52:42 -08001552 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001553 assert numControllers, "numControllers not defined"
1554 assert main, "main not defined"
1555 assert utilities.assert_equals, "utilities.assert_equals not defined"
1556 assert CLIs, "CLIs not defined"
1557 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001558 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001559 main.step( "Killing 3 ONOS nodes" )
Jon Hallfeff3082015-05-19 10:23:26 -07001560 killTime = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001561 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001562 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001563 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001564 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001565 killResults = killResults and\
1566 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001567 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001568 killResults = killResults and\
1569 main.ONOSbench.onosKill( nodes[2].ip_address )
1570 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1571 onpass="ONOS Killed successfully",
1572 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001573
Jon Hall6aec96b2015-01-19 14:49:31 -08001574 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001575 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001576 onosIsupResult = main.FALSE
1577 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001578 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1579 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1580 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001581 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001582 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001583 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001584 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1585 onpass="ONOS restarted successfully",
1586 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001587
Jon Hall390696c2015-05-05 17:13:41 -07001588 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001589 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1590 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1591 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001592 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001593 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1594 onpass="ONOS cli restarted",
1595 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001596
Jon Hall21270ac2015-02-16 17:59:55 -08001597 # Grab the time of restart so we chan check how long the gossip
1598 # protocol has had time to work
Jon Hallfeff3082015-05-19 10:23:26 -07001599 main.restartTime = time.time() - killTime
1600 main.log.debug( "Restart time: " + str( main.restartTime ) )
1601 '''
1602 # FIXME: revisit test plan for election with madan
1603 # Rerun for election on restarted nodes
1604 run1 = CLIs[0].electionTestRun()
1605 run2 = CLIs[1].electionTestRun()
1606 run3 = CLIs[2].electionTestRun()
1607 runResults = run1 and run2 and run3
1608 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1609 onpass="Reran for election",
1610 onfail="Failed to rerun for election" )
1611 '''
1612 # TODO: MAke this configurable. Also, we are breaking the above timer
1613 time.sleep( 60 )
1614 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1615 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1616 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
1617 time.sleep( 200 )
1618 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1619 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1620 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001621
Jon Hall6aec96b2015-01-19 14:49:31 -08001622 def CASE7( self, main ):
1623 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001624 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001625 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001626 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001627 assert numControllers, "numControllers not defined"
1628 assert main, "main not defined"
1629 assert utilities.assert_equals, "utilities.assert_equals not defined"
1630 assert CLIs, "CLIs not defined"
1631 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001633
Jon Hall5cfd23c2015-03-19 11:40:57 -07001634 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001635 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001636 rolesNotNull = main.TRUE
1637 threads = []
1638 for i in range( numControllers ):
1639 t = main.Thread( target=CLIs[i].rolesNotNull,
1640 name="rolesNotNull-" + str( i ),
1641 args=[ ] )
1642 threads.append( t )
1643 t.start()
1644
1645 for t in threads:
1646 t.join()
1647 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001648 utilities.assert_equals(
1649 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001650 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001651 onpass="Each device has a master",
1652 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001653
Jon Hall390696c2015-05-05 17:13:41 -07001654 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001655 ONOSMastership = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001656 consistentMastership = True
1657 rolesResults = True
1658 threads = []
1659 for i in range( numControllers ):
1660 t = main.Thread( target=CLIs[i].roles,
1661 name="roles-" + str( i ),
1662 args=[] )
1663 threads.append( t )
1664 t.start()
1665
1666 for t in threads:
1667 t.join()
1668 ONOSMastership.append( t.result )
1669
1670 for i in range( numControllers ):
1671 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1672 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1673 " roles" )
1674 main.log.warn(
1675 "ONOS" + str( i + 1 ) + " mastership response: " +
1676 repr( ONOSMastership[i] ) )
1677 rolesResults = False
1678 utilities.assert_equals(
1679 expect=True,
1680 actual=rolesResults,
1681 onpass="No error in reading roles output",
1682 onfail="Error in reading roles from ONOS" )
1683
1684 main.step( "Check for consistency in roles from each controller" )
1685 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001686 main.log.report(
1687 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001688 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001689 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001690 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001691 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001692 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001693 onpass="Switch roles are consistent across all ONOS nodes",
1694 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001695
Jon Hall5cfd23c2015-03-19 11:40:57 -07001696 if rolesResults and not consistentMastership:
1697 for i in range( numControllers ):
1698 main.log.warn(
1699 "ONOS" + str( i + 1 ) + " roles: ",
1700 json.dumps(
1701 json.loads( ONOSMastership[ i ] ),
1702 sort_keys=True,
1703 indent=4,
1704 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001705
Jon Hallfeff3082015-05-19 10:23:26 -07001706 # NOTE: we expect mastership to change on controller failure
1707 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001708 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001710 try:
1711 currentJson = json.loads( ONOSMastership[0] )
1712 oldJson = json.loads( mastershipState )
1713 except ( ValueError, TypeError ):
1714 main.log.exception( "Something is wrong with parsing " +
1715 "ONOSMastership[0] or mastershipState" )
1716 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1717 main.log.error( "mastershipState" + repr( mastershipState ) )
1718 main.cleanup()
1719 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001720 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001721 for i in range( 1, 29 ):
1722 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001723 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001724 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001725 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001726 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001727 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001728 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001729 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001730 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001731 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001732 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001733 utilities.assert_equals(
1734 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001735 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001736 onpass="Mastership of Switches was not changed",
1737 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001738 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001739
Jon Hall58c76b72015-02-23 11:09:24 -08001740 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001741 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001742 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001743 consistentIntents = True
1744 intentsResults = True
1745 threads = []
1746 for i in range( numControllers ):
1747 t = main.Thread( target=CLIs[i].intents,
1748 name="intents-" + str( i ),
1749 args=[],
1750 kwargs={ 'jsonFormat': True } )
1751 threads.append( t )
1752 t.start()
1753
1754 for t in threads:
1755 t.join()
1756 ONOSIntents.append( t.result )
1757
1758 for i in range( numControllers ):
1759 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1760 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1761 " intents" )
1762 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1763 repr( ONOSIntents[ i ] ) )
1764 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001765 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001766 expect=True,
1767 actual=intentsResults,
1768 onpass="No error in reading intents output",
1769 onfail="Error in reading intents from ONOS" )
1770
1771 main.step( "Check for consistency in Intents from each controller" )
1772 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1773 main.log.report( "Intents are consistent across all ONOS " +
1774 "nodes" )
1775 else:
1776 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001777
1778 # Try to make it easy to figure out what is happening
1779 #
1780 # Intent ONOS1 ONOS2 ...
1781 # 0x01 INSTALLED INSTALLING
1782 # ... ... ...
1783 # ... ... ...
1784 title = " ID"
1785 for n in range( numControllers ):
1786 title += " " * 10 + "ONOS" + str( n + 1 )
1787 main.log.warn( title )
1788 # get all intent keys in the cluster
1789 keys = []
1790 for nodeStr in ONOSIntents:
1791 node = json.loads( nodeStr )
1792 for intent in node:
1793 keys.append( intent.get( 'id' ) )
1794 keys = set( keys )
1795 for key in keys:
1796 row = "%-13s" % key
1797 for nodeStr in ONOSIntents:
1798 node = json.loads( nodeStr )
1799 for intent in node:
1800 if intent.get( 'id' ) == key:
1801 row += "%-15s" % intent.get( 'state' )
1802 main.log.warn( row )
1803 # End table view
1804
Jon Hall5cfd23c2015-03-19 11:40:57 -07001805 utilities.assert_equals(
1806 expect=True,
1807 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001808 onpass="Intents are consistent across all ONOS nodes",
1809 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001810 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001811 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001812 nodeStates = []
1813 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001814 try:
1815 for intent in json.loads( node ):
1816 nodeStates.append( intent[ 'state' ] )
1817 except ( ValueError, TypeError ):
1818 main.log.exception( "Error in parsing intents" )
1819 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001820 intentStates.append( nodeStates )
1821 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1822 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001823
Jon Hall5cfd23c2015-03-19 11:40:57 -07001824 if intentsResults and not consistentIntents:
1825 for i in range( numControllers ):
1826 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1827 main.log.warn( json.dumps(
1828 json.loads( ONOSIntents[ i ] ),
1829 sort_keys=True,
1830 indent=4,
1831 separators=( ',', ': ' ) ) )
1832 elif intentsResults and consistentIntents:
1833 intentCheck = main.TRUE
1834
Jon Hall58c76b72015-02-23 11:09:24 -08001835 # NOTE: Store has no durability, so intents are lost across system
1836 # restarts
1837 main.step( "Compare current intents with intents before the failure" )
1838 # NOTE: this requires case 5 to pass for intentState to be set.
1839 # maybe we should stop the test if that fails?
1840 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001841 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001842 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001843 main.log.info( "Intents are consistent with before failure" )
Jon Hall58c76b72015-02-23 11:09:24 -08001844 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001845 # what the acceptable states are
Jon Hall58c76b72015-02-23 11:09:24 -08001846 else:
1847 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001848 main.log.warn( "ONOS intents: " )
1849 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1850 sort_keys=True, indent=4,
1851 separators=( ',', ': ' ) ) )
1852 except ( ValueError, TypeError ):
1853 main.log.exception( "Exception printing intents" )
1854 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001855 sameIntents = main.FALSE
1856 utilities.assert_equals(
1857 expect=main.TRUE,
1858 actual=sameIntents,
1859 onpass="Intents are consistent with before failure",
1860 onfail="The Intents changed during failure" )
1861 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001862
Jon Hall58c76b72015-02-23 11:09:24 -08001863 main.step( "Get the OF Table entries and compare to before " +
1864 "component failure" )
1865 FlowTables = main.TRUE
1866 flows2 = []
1867 for i in range( 28 ):
1868 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1869 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1870 flows2.append( tmpFlows )
1871 tempResult = main.Mininet2.flowComp(
1872 flow1=flows[ i ],
1873 flow2=tmpFlows )
1874 FlowTables = FlowTables and tempResult
1875 if FlowTables == main.FALSE:
1876 main.log.info( "Differences in flow table for switch: s" +
1877 str( i + 1 ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001878 utilities.assert_equals(
1879 expect=main.TRUE,
1880 actual=FlowTables,
1881 onpass="No changes were found in the flow tables",
1882 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001883
Jon Hall6aec96b2015-01-19 14:49:31 -08001884 main.step( "Check the continuous pings to ensure that no packets " +
1885 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001886 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1887 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001888 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1890 for i in range( 8, 18 ):
1891 main.log.info(
1892 "Checking for a loss in pings along flow from s" +
1893 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001894 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001895 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001896 str( i ) ) or LossInPings
1897 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001898 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001899 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001900 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001902 main.log.info( "No Loss in the pings" )
1903 main.log.report( "No loss of dataplane connectivity" )
1904 utilities.assert_equals(
1905 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001906 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001907 onpass="No Loss of connectivity",
1908 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001909
Jon Hall390696c2015-05-05 17:13:41 -07001910 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001911 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001912 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001913 # FIXME: make sure this matches nodes that were restarted
1914 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1915 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07001916
Jon Hall8f89dda2015-01-22 16:03:33 -08001917 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001918 for cli in CLIs:
1919 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001920 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001921 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07001922 # error in response
Jon Hall6aec96b2015-01-19 14:49:31 -08001923 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001924 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001925 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001926 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001927 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001928 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001929 " shows no leader for the election-app was" +
1930 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001931 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001932 elif leaderN in restarted:
1933 main.log.report( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001934 " as leader for the election-app, but it " +
1935 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001936 leaderResult = main.FALSE
1937 if len( set( leaderList ) ) != 1:
1938 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 main.log.error(
1940 "Inconsistent view of leader for the election test app" )
1941 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08001942 utilities.assert_equals(
1943 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001944 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001945 onpass="Leadership election passed",
1946 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001947
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 def CASE8( self, main ):
1949 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001950 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001951 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001952 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001953 # FIXME add this path to params
1954 sys.path.append( "/home/admin/sts" )
1955 # assumes that sts is already in you PYTHONPATH
1956 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001957 import json
1958 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001959 assert numControllers, "numControllers not defined"
1960 assert main, "main not defined"
1961 assert utilities.assert_equals, "utilities.assert_equals not defined"
1962 assert CLIs, "CLIs not defined"
1963 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001964
Jon Hallfeff3082015-05-19 10:23:26 -07001965 main.case( "Compare ONOS Topology view to Mininet topology" )
1966 main.caseExplaination = "Compare topology objects between Mininet" +\
1967 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07001969 try:
1970 ctrls = []
1971 for node in nodes:
1972 temp = ( node, node.name, node.ip_address, 6633 )
1973 ctrls.append( temp )
1974 MNTopo = TestONTopology( main.Mininet1, ctrls )
1975 except Exception:
1976 objResult = main.FALSE
1977 else:
1978 objResult = main.TRUE
1979 utilities.assert_equals( expect=main.TRUE, actual=objResult,
1980 onpass="Created TestONTopology object",
1981 onfail="Exception while creating " +
1982 "TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001983
Jon Hallfeff3082015-05-19 10:23:26 -07001984 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001985 devicesResults = main.TRUE
1986 portsResults = main.TRUE
1987 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001988 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001989 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001990 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001991 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001992 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001993 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001994 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001995 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001996 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001997 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001998 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001999 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002000 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002001 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002002 threads = []
2003 for i in range( numControllers ):
2004 t = main.Thread( target=CLIs[i].devices,
2005 name="devices-" + str( i ),
2006 args=[ ] )
2007 threads.append( t )
2008 t.start()
2009
2010 for t in threads:
2011 t.join()
2012 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002013 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002014 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002015 threads = []
2016 for i in range( numControllers ):
2017 t = main.Thread( target=CLIs[i].hosts,
2018 name="hosts-" + str( i ),
2019 args=[ ] )
2020 threads.append( t )
2021 t.start()
2022
2023 for t in threads:
2024 t.join()
2025 try:
2026 hosts.append( json.loads( t.result ) )
2027 except ( ValueError, TypeError ):
2028 main.log.exception( "Error parsing hosts results" )
2029 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002030 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002031 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002032 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002033 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08002034 main.log.error(
2035 "DEBUG:Error with host ips on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002036 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002037 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002038 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002039 threads = []
2040 for i in range( numControllers ):
2041 t = main.Thread( target=CLIs[i].ports,
2042 name="ports-" + str( i ),
2043 args=[ ] )
2044 threads.append( t )
2045 t.start()
2046
2047 for t in threads:
2048 t.join()
2049 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002050 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002051 threads = []
2052 for i in range( numControllers ):
2053 t = main.Thread( target=CLIs[i].links,
2054 name="links-" + str( i ),
2055 args=[ ] )
2056 threads.append( t )
2057 t.start()
2058
2059 for t in threads:
2060 t.join()
2061 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002062 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002063 threads = []
2064 for i in range( numControllers ):
2065 t = main.Thread( target=CLIs[i].clusters,
2066 name="clusters-" + str( i ),
2067 args=[ ] )
2068 threads.append( t )
2069 t.start()
2070
2071 for t in threads:
2072 t.join()
2073 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002074
Jon Hall8f89dda2015-01-22 16:03:33 -08002075 elapsed = time.time() - startTime
2076 cliTime = time.time() - cliStart
2077 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002078
Jon Hall8f89dda2015-01-22 16:03:33 -08002079 for controller in range( numControllers ):
2080 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002081 if devices[ controller ] or "Error" not in devices[
2082 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002083 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002084 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002085 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002086 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002087 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002088 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002089 actual=currentDevicesResult,
2090 onpass="ONOS" + controllerStr +
2091 " Switches view is correct",
2092 onfail="ONOS" + controllerStr +
2093 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002094
Jon Hall6aec96b2015-01-19 14:49:31 -08002095 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002096 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002097 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002098 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002099 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002100 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002101 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002102 actual=currentPortsResult,
2103 onpass="ONOS" + controllerStr +
2104 " ports view is correct",
2105 onfail="ONOS" + controllerStr +
2106 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002107
Jon Hall6aec96b2015-01-19 14:49:31 -08002108 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002109 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002110 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002111 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002112 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002113 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002114 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002115 actual=currentLinksResult,
2116 onpass="ONOS" + controllerStr +
2117 " links view is correct",
2118 onfail="ONOS" + controllerStr +
2119 " links view is incorrect" )
2120
2121 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2122 currentHostsResult = main.Mininet1.compareHosts(
2123 MNTopo, hosts[ controller ] )
2124 else:
2125 currentHostsResult = main.FALSE
2126 utilities.assert_equals( expect=main.TRUE,
2127 actual=currentHostsResult,
2128 onpass="ONOS" + controllerStr +
2129 " hosts exist in Mininet",
2130 onfail="ONOS" + controllerStr +
2131 " hosts don't match Mininet" )
2132
2133 devicesResults = devicesResults and currentDevicesResult
2134 portsResults = portsResults and currentPortsResult
2135 linksResults = linksResults and currentLinksResult
2136 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002137
Jon Hall529a37f2015-01-28 10:02:00 -08002138 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002139
Jon Hall6aec96b2015-01-19 14:49:31 -08002140 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002141 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002142 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002143 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002144 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002145 if "Error" not in hosts[ controller ]:
2146 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002147 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002148 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08002149 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002150 " is inconsistent with ONOS1" )
2151 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002152 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002153
2154 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002155 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002156 controllerStr )
2157 consistentHostsResult = main.FALSE
2158 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002159 " hosts response: " +
2160 repr( hosts[ controller ] ) )
2161 utilities.assert_equals(
2162 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002163 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002164 onpass="Hosts view is consistent across all ONOS nodes",
2165 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002166
Jon Hall6aec96b2015-01-19 14:49:31 -08002167 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002168 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002169 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002170 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002171 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002172 if "Error" not in clusters[ controller ]:
2173 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002174 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002175 else: # clusters not consistent
2176 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002177 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002178 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002179 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002180
2181 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002182 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002183 "from ONOS" + controllerStr )
2184 consistentClustersResult = main.FALSE
2185 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002186 " clusters response: " +
2187 repr( clusters[ controller ] ) )
2188 utilities.assert_equals(
2189 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002190 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002191 onpass="Clusters view is consistent across all ONOS nodes",
2192 onfail="ONOS nodes have different views of clusters" )
2193 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002194 main.step( "Topology view is correct and consistent across all " +
2195 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002196 try:
2197 numClusters = len( json.loads( clusters[ 0 ] ) )
2198 except ( ValueError, TypeError ):
2199 main.log.exception( "Error parsing clusters[0]: " +
2200 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002201 clusterResults = main.FALSE
2202 if numClusters == 1:
2203 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002204 utilities.assert_equals(
2205 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002206 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002207 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002208 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002209
Jon Hall8f89dda2015-01-22 16:03:33 -08002210 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002211 and hostsResults and consistentHostsResult
2212 and consistentClustersResult and clusterResults
2213 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002214
Jon Hall8f89dda2015-01-22 16:03:33 -08002215 topoResult = topoResult and int( count <= 2 )
2216 note = "note it takes about " + str( int( cliTime ) ) + \
2217 " seconds for the test to make all the cli calls to fetch " +\
2218 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002219 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002220 "Very crass estimate for topology discovery/convergence( " +
2221 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002222 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002223 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002224 onpass="Topology Check Test successful",
2225 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002226
Jon Halla9d26da2015-03-30 16:45:32 -07002227 # FIXME: move this to an ONOS state case
2228 main.step( "Checking ONOS nodes" )
2229 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002230 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002231 threads = []
2232 for i in range( numControllers ):
2233 t = main.Thread( target=CLIs[i].nodes,
2234 name="nodes-" + str( i ),
2235 args=[ ] )
2236 threads.append( t )
2237 t.start()
2238
2239 for t in threads:
2240 t.join()
2241 nodesOutput.append( t.result )
2242 ips = [ node.ip_address for node in nodes ]
2243 for i in nodesOutput:
2244 try:
2245 current = json.loads( i )
2246 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002247 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002248 if node['ip'] in ips: # node in nodes() output is in cell
2249 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002250 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002251 else:
2252 main.log.error( "Error in ONOS node availability" )
2253 main.log.error(
2254 json.dumps( current,
2255 sort_keys=True,
2256 indent=4,
2257 separators=( ',', ': ' ) ) )
2258 break
Jon Hall390696c2015-05-05 17:13:41 -07002259 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002260 except ( ValueError, TypeError ):
2261 main.log.error( "Error parsing nodes output" )
2262 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002263 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2264 onpass="Nodes check successful",
2265 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002266
Jon Hall6aec96b2015-01-19 14:49:31 -08002267 def CASE9( self, main ):
2268 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002269 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002270 """
2271 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002272 assert numControllers, "numControllers not defined"
2273 assert main, "main not defined"
2274 assert utilities.assert_equals, "utilities.assert_equals not defined"
2275 assert CLIs, "CLIs not defined"
2276 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002277 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002278
Jon Hall8f89dda2015-01-22 16:03:33 -08002279 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002280
Jon Hall6aec96b2015-01-19 14:49:31 -08002281 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002282 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002283 main.log.report( description )
2284 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002285
Jon Hall6aec96b2015-01-19 14:49:31 -08002286 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002287 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002288 main.log.info( "Waiting " + str( linkSleep ) +
2289 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002290 time.sleep( linkSleep )
2291 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002292 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002293 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002294 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002295
Jon Hall6aec96b2015-01-19 14:49:31 -08002296 def CASE10( self, main ):
2297 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002298 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002299 """
2300 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002301 assert numControllers, "numControllers not defined"
2302 assert main, "main not defined"
2303 assert utilities.assert_equals, "utilities.assert_equals not defined"
2304 assert CLIs, "CLIs not defined"
2305 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002306 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002307
Jon Hall8f89dda2015-01-22 16:03:33 -08002308 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002309
Jon Hall6aec96b2015-01-19 14:49:31 -08002310 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002311 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002312 main.log.report( description )
2313 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002314
Jon Hall6aec96b2015-01-19 14:49:31 -08002315 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002316 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002317 main.log.info( "Waiting " + str( linkSleep ) +
2318 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002319 time.sleep( linkSleep )
2320 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002321 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002322 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002323 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002324
Jon Hall6aec96b2015-01-19 14:49:31 -08002325 def CASE11( self, main ):
2326 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002327 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002328 """
2329 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002330 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002331 assert numControllers, "numControllers not defined"
2332 assert main, "main not defined"
2333 assert utilities.assert_equals, "utilities.assert_equals not defined"
2334 assert CLIs, "CLIs not defined"
2335 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002336
Jon Hall8f89dda2015-01-22 16:03:33 -08002337 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002338
2339 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002340 main.log.report( description )
2341 main.case( description )
2342 switch = main.params[ 'kill' ][ 'switch' ]
2343 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002344
Jon Hall6aec96b2015-01-19 14:49:31 -08002345 # TODO: Make this switch parameterizable
2346 main.step( "Kill " + switch )
2347 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002348 main.Mininet1.delSwitch( switch )
2349 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002350 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002351 time.sleep( switchSleep )
2352 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002353 # Peek at the deleted switch
2354 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002355 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002356 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002357 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002358 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002359 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002360 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002361
Jon Hall6aec96b2015-01-19 14:49:31 -08002362 def CASE12( self, main ):
2363 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002364 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002365 """
2366 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002367 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002368 assert numControllers, "numControllers not defined"
2369 assert main, "main not defined"
2370 assert utilities.assert_equals, "utilities.assert_equals not defined"
2371 assert CLIs, "CLIs not defined"
2372 assert nodes, "nodes not defined"
2373 assert ONOS1Port, "ONOS1Port not defined"
2374 assert ONOS2Port, "ONOS2Port not defined"
2375 assert ONOS3Port, "ONOS3Port not defined"
2376 assert ONOS4Port, "ONOS4Port not defined"
2377 assert ONOS5Port, "ONOS5Port not defined"
2378 assert ONOS6Port, "ONOS6Port not defined"
2379 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002380
Jon Hall8f89dda2015-01-22 16:03:33 -08002381 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002382 switch = main.params[ 'kill' ][ 'switch' ]
2383 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2384 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002385 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002386 main.log.report( description )
2387 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002388
Jon Hall6aec96b2015-01-19 14:49:31 -08002389 main.step( "Add back " + switch )
2390 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002391 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002392 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002393 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002394 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2395 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002396 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002397 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002398 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002399 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002400 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002401 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002402 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002403 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002404 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002405 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002406 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002407 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002408 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002409 port7=ONOS7Port )
2410 main.log.info( "Waiting " + str( switchSleep ) +
2411 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002412 time.sleep( switchSleep )
2413 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002414 # Peek at the deleted switch
2415 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002416 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002417 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002418 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002420 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002421 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002422
Jon Hall6aec96b2015-01-19 14:49:31 -08002423 def CASE13( self, main ):
2424 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002425 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002426 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002427 import os
2428 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002429 assert numControllers, "numControllers not defined"
2430 assert main, "main not defined"
2431 assert utilities.assert_equals, "utilities.assert_equals not defined"
2432 assert CLIs, "CLIs not defined"
2433 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002434
2435 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002436 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2437 'blue': '\033[94m', 'green': '\033[92m',
2438 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002439 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002440 main.log.report( description )
2441 main.case( description )
2442 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002443 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002444
Jon Hall6aec96b2015-01-19 14:49:31 -08002445 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002446 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002447 teststationUser = main.params[ 'TESTONUSER' ]
2448 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002449 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002450 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002451 # FIXME: scp
2452 # mn files
2453 # TODO: Load these from params
2454 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002455 logFolder = "/opt/onos/log/"
2456 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002457 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002458 dstDir = "~/packet_captures/"
2459 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002460 for node in nodes:
2461 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2462 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002463 teststationUser + "@" +
2464 teststationIP + ":" +
2465 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002466 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002467 main.ONOSbench.handle.expect( "\$" )
2468
Jon Hall6aec96b2015-01-19 14:49:31 -08002469 # std*.log's
2470 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002471 logFolder = "/opt/onos/var/"
2472 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002473 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002474 dstDir = "~/packet_captures/"
2475 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002476 for node in nodes:
2477 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2478 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002479 teststationUser + "@" +
2480 teststationIP + ":" +
2481 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002482 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002483 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002484 # sleep so scp can finish
2485 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002486
2487 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002488 mnResult = main.Mininet1.stopNet()
2489 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2490 onpass="Mininet stopped",
2491 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002492
2493 main.step( "Checking ONOS Logs for errors" )
2494 for node in nodes:
2495 print colors[ 'purple' ] + "Checking logs for errors on " + \
2496 node.name + ":" + colors[ 'end' ]
2497 print main.ONOSbench.checkLogs( node.ip_address )
2498
Jon Hall6aec96b2015-01-19 14:49:31 -08002499 main.step( "Packing and rotating pcap archives" )
2500 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002501
Jon Hallfeff3082015-05-19 10:23:26 -07002502 try:
2503 timerLog = open( main.logdir + "/Timers.csv", 'w')
2504 # Overwrite with empty line and close
2505 timerLog.write( "Restart\n" )
2506 timerLog.write( str( main.restartTime ) )
2507 timerLog.close()
2508 except NameError, e:
2509 main.log.exception(e)
2510
Jon Hall6aec96b2015-01-19 14:49:31 -08002511 def CASE14( self, main ):
2512 """
Jon Hall669173b2014-12-17 11:36:30 -08002513 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002514 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002515 assert numControllers, "numControllers not defined"
2516 assert main, "main not defined"
2517 assert utilities.assert_equals, "utilities.assert_equals not defined"
2518 assert CLIs, "CLIs not defined"
2519 assert nodes, "nodes not defined"
2520
Jon Hall390696c2015-05-05 17:13:41 -07002521 main.case("Start Leadership Election app")
2522 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002523 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2524 utilities.assert_equals(
2525 expect=main.TRUE,
2526 actual=appResult,
2527 onpass="Election app installed",
2528 onfail="Something went wrong with installing Leadership election" )
2529
2530 main.step( "Run for election on each node" )
2531 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002532 leaders = []
2533 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002534 cli.electionTestRun()
2535 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002536 leader = cli.electionTestLeader()
2537 if leader is None or leader == main.FALSE:
2538 main.log.report( cli.name + ": Leader for the election app " +
2539 "should be an ONOS node, instead got '" +
2540 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002541 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002542 leaders.append( leader )
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 Hallfeff3082015-05-19 10:23:26 -07002546 onpass="Successfully ran for leadership",
2547 onfail="Failed to run for leadership" )
2548
2549 main.step( "Check that each node shows the same leader" )
2550 sameLeader = main.TRUE
2551 if len( set( leaders ) ) != 1:
2552 sameLeader = main.FALSE
2553 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2554 str( leaders ) )
2555 utilities.assert_equals(
2556 expect=main.TRUE,
2557 actual=sameLeader,
2558 onpass="Leadership is consistent for the election topic",
2559 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002560
Jon Hall6aec96b2015-01-19 14:49:31 -08002561 def CASE15( self, main ):
2562 """
Jon Hall669173b2014-12-17 11:36:30 -08002563 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002564 """
Jon Hall390696c2015-05-05 17:13:41 -07002565 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002566 assert numControllers, "numControllers not defined"
2567 assert main, "main not defined"
2568 assert utilities.assert_equals, "utilities.assert_equals not defined"
2569 assert CLIs, "CLIs not defined"
2570 assert nodes, "nodes not defined"
2571
Jon Hall8f89dda2015-01-22 16:03:33 -08002572 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002573 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002574 main.log.report( description )
2575 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002576
2577 main.step( "Check that each node shows the same leader" )
2578 sameLeader = main.TRUE
2579 leaders = []
2580 for cli in CLIs:
2581 leader = cli.electionTestLeader()
2582 leaders.append( leader )
2583 if len( set( leaders ) ) != 1:
2584 sameLeader = main.FALSE
2585 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2586 str( leaders ) )
2587 utilities.assert_equals(
2588 expect=main.TRUE,
2589 actual=sameLeader,
2590 onpass="Leadership is consistent for the election topic",
2591 onfail="Nodes have different leaders" )
2592
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002594 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002595 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002596 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002597 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002598 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002599 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002600 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002601 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002602 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002603 for i in range( len( CLIs ) ):
2604 if leader == nodes[ i ].ip_address:
2605 oldLeader = CLIs[ i ]
2606 break
Jon Halla9d26da2015-03-30 16:45:32 -07002607 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002608 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002609 if oldLeader:
2610 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002611 utilities.assert_equals(
2612 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002613 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002614 onpass="Node was withdrawn from election",
2615 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002616
Jon Hall6aec96b2015-01-19 14:49:31 -08002617 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002618 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002619 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002620 for cli in CLIs:
2621 leaderN = cli.electionTestLeader()
2622 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002623 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002624 main.log.report( cli.name + " still sees " + str( leader ) +
2625 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002626 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002627 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002628 # error in response
2629 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002630 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002631 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002632 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002633 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002634 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002635 elif leaderN is None:
2636 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002637 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002638 leaderN = cli.electionTestLeader()
2639 leaderList.pop()
2640 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002641 consistentLeader = main.FALSE
2642 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002643 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002644 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002645 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002646 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002647 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002648 main.log.report(
2649 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002650 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002651 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002652 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002653 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002654 utilities.assert_equals(
2655 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002656 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002657 onpass="Leadership election passed",
2658 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002659
Jon Hall58c76b72015-02-23 11:09:24 -08002660 main.step( "Run for election on old leader( just so everyone " +
2661 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002662 if oldLeader:
2663 runResult = oldLeader.electionTestRun()
2664 else:
2665 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002666 utilities.assert_equals(
2667 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002668 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002669 onpass="App re-ran for election",
2670 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002671
Jon Hallfeff3082015-05-19 10:23:26 -07002672 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002673 afterRun = main.ONOScli1.electionTestLeader()
2674 # verify leader didn't just change
2675 if afterRun == leaderList[ 0 ]:
2676 afterResult = main.TRUE
2677 else:
2678 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002679
Jon Hall6aec96b2015-01-19 14:49:31 -08002680 utilities.assert_equals(
2681 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002682 actual=afterResult,
2683 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002684 onfail="Something went wrong with Leadership election after " +
2685 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002686
Jon Hall390696c2015-05-05 17:13:41 -07002687 def CASE16( self, main ):
2688 """
2689 Install Distributed Primitives app
2690 """
2691 assert numControllers, "numControllers not defined"
2692 assert main, "main not defined"
2693 assert utilities.assert_equals, "utilities.assert_equals not defined"
2694 assert CLIs, "CLIs not defined"
2695 assert nodes, "nodes not defined"
2696
2697 # Variables for the distributed primitives tests
2698 global pCounterName
2699 global iCounterName
2700 global pCounterValue
2701 global iCounterValue
2702 global onosSet
2703 global onosSetName
2704 pCounterName = "TestON-Partitions"
2705 iCounterName = "TestON-inMemory"
2706 pCounterValue = 0
2707 iCounterValue = 0
2708 onosSet = set([])
2709 onosSetName = "TestON-set"
2710
2711 description = "Install Primitives app"
2712 main.case( description )
2713 main.step( "Install Primitives app" )
2714 appName = "org.onosproject.distributedprimitives"
2715 appResults = CLIs[0].activateApp( appName )
2716 utilities.assert_equals( expect=main.TRUE,
2717 actual=appResults,
2718 onpass="Primitives app activated",
2719 onfail="Primitives app not activated" )
Jon Hallfeff3082015-05-19 10:23:26 -07002720 time.sleep (5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002721
2722 def CASE17( self, main ):
2723 """
2724 Check for basic functionality with distributed primitives
2725 """
2726 # Make sure variables are defined/set
2727 assert numControllers, "numControllers not defined"
2728 assert main, "main not defined"
2729 assert utilities.assert_equals, "utilities.assert_equals not defined"
2730 assert CLIs, "CLIs not defined"
2731 assert nodes, "nodes not defined"
2732 assert pCounterName, "pCounterName not defined"
2733 assert iCounterName, "iCounterName not defined"
2734 assert onosSetName, "onosSetName not defined"
2735 # NOTE: assert fails if value is 0/None/Empty/False
2736 try:
2737 pCounterValue
2738 except NameError:
2739 main.log.error( "pCounterValue not defined, setting to 0" )
2740 pCounterValue = 0
2741 try:
2742 iCounterValue
2743 except NameError:
2744 main.log.error( "iCounterValue not defined, setting to 0" )
2745 iCounterValue = 0
2746 try:
2747 onosSet
2748 except NameError:
2749 main.log.error( "onosSet not defined, setting to empty Set" )
2750 onosSet = set([])
2751 # Variables for the distributed primitives tests. These are local only
2752 addValue = "a"
2753 addAllValue = "a b c d e f"
2754 retainValue = "c d e f"
2755
2756 description = "Check for basic functionality with distributed " +\
2757 "primitives"
2758 main.case( description )
2759 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2760 # DISTRIBUTED ATOMIC COUNTERS
2761 main.step( "Increment and get a default counter on each node" )
2762 pCounters = []
2763 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002764 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002765 for i in range( numControllers ):
2766 t = main.Thread( target=CLIs[i].counterTestIncrement,
2767 name="counterIncrement-" + str( i ),
2768 args=[ pCounterName ] )
2769 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002770 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002771 threads.append( t )
2772 t.start()
2773
2774 for t in threads:
2775 t.join()
2776 pCounters.append( t.result )
2777 # Check that counter incremented numController times
2778 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002779 for i in addedPValues:
2780 tmpResult = i in pCounters
2781 pCounterResults = pCounterResults and tmpResult
2782 if not tmpResult:
2783 main.log.error( str( i ) + " is not in partitioned "
2784 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002785 utilities.assert_equals( expect=True,
2786 actual=pCounterResults,
2787 onpass="Default counter incremented",
2788 onfail="Error incrementing default" +
2789 " counter" )
2790
2791 main.step( "Increment and get an in memory counter on each node" )
2792 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002793 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002794 threads = []
2795 for i in range( numControllers ):
2796 t = main.Thread( target=CLIs[i].counterTestIncrement,
2797 name="icounterIncrement-" + str( i ),
2798 args=[ iCounterName ],
2799 kwargs={ "inMemory": True } )
2800 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002801 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002802 threads.append( t )
2803 t.start()
2804
2805 for t in threads:
2806 t.join()
2807 iCounters.append( t.result )
2808 # Check that counter incremented numController times
2809 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002810 for i in addedIValues:
2811 tmpResult = i in iCounters
2812 iCounterResults = iCounterResults and tmpResult
2813 if not tmpResult:
2814 main.log.error( str( i ) + " is not in the in-memory "
2815 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002816 utilities.assert_equals( expect=True,
2817 actual=iCounterResults,
2818 onpass="In memory counter incremented",
2819 onfail="Error incrementing in memory" +
2820 " counter" )
2821
2822 main.step( "Check counters are consistant across nodes" )
2823 onosCounters = []
2824 threads = []
2825 for i in range( numControllers ):
2826 t = main.Thread( target=CLIs[i].counters,
2827 name="counters-" + str( i ) )
2828 threads.append( t )
2829 t.start()
2830 for t in threads:
2831 t.join()
2832 onosCounters.append( t.result )
2833 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2834 if all( tmp ):
2835 main.log.info( "Counters are consistent across all nodes" )
2836 consistentCounterResults = main.TRUE
2837 else:
2838 main.log.error( "Counters are not consistent across all nodes" )
2839 consistentCounterResults = main.FALSE
2840 utilities.assert_equals( expect=main.TRUE,
2841 actual=consistentCounterResults,
2842 onpass="ONOS counters are consistent " +
2843 "across nodes",
2844 onfail="ONOS Counters are inconsistent " +
2845 "across nodes" )
2846
2847 main.step( "Counters we added have the correct values" )
2848 correctResults = main.TRUE
2849 for i in range( numControllers ):
2850 current = onosCounters[i]
2851 try:
2852 pValue = current.get( pCounterName )
2853 iValue = current.get( iCounterName )
2854 if pValue == pCounterValue:
2855 main.log.info( "Partitioned counter value is correct" )
2856 else:
2857 main.log.error( "Partitioned counter value is incorrect," +
2858 " expected value: " + str( pCounterValue )
2859 + " current value: " + str( pValue ) )
2860 correctResults = main.FALSE
2861 if iValue == iCounterValue:
2862 main.log.info( "In memory counter value is correct" )
2863 else:
2864 main.log.error( "In memory counter value is incorrect, " +
2865 "expected value: " + str( iCounterValue ) +
2866 " current value: " + str( iValue ) )
2867 correctResults = main.FALSE
2868 except AttributeError, e:
2869 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2870 "is not as expected" )
2871 correctResults = main.FALSE
2872 utilities.assert_equals( expect=main.TRUE,
2873 actual=correctResults,
2874 onpass="Added counters are correct",
2875 onfail="Added counters are incorrect" )
2876 # DISTRIBUTED SETS
2877 main.step( "Distributed Set get" )
2878 size = len( onosSet )
2879 getResponses = []
2880 threads = []
2881 for i in range( numControllers ):
2882 t = main.Thread( target=CLIs[i].setTestGet,
2883 name="setTestGet-" + str( i ),
2884 args=[ onosSetName ] )
2885 threads.append( t )
2886 t.start()
2887 for t in threads:
2888 t.join()
2889 getResponses.append( t.result )
2890
2891 getResults = main.TRUE
2892 for i in range( numControllers ):
2893 if isinstance( getResponses[ i ], list):
2894 current = set( getResponses[ i ] )
2895 if len( current ) == len( getResponses[ i ] ):
2896 # no repeats
2897 if onosSet != current:
2898 main.log.error( "ONOS" + str( i + 1 ) +
2899 " has incorrect view" +
2900 " of set " + onosSetName + ":\n" +
2901 str( getResponses[ i ] ) )
2902 main.log.debug( "Expected: " + str( onosSet ) )
2903 main.log.debug( "Actual: " + str( current ) )
2904 getResults = main.FALSE
2905 else:
2906 # error, set is not a set
2907 main.log.error( "ONOS" + str( i + 1 ) +
2908 " has repeat elements in" +
2909 " set " + onosSetName + ":\n" +
2910 str( getResponses[ i ] ) )
2911 getResults = main.FALSE
2912 elif getResponses[ i ] == main.ERROR:
2913 getResults = main.FALSE
2914 utilities.assert_equals( expect=main.TRUE,
2915 actual=getResults,
2916 onpass="Set elements are correct",
2917 onfail="Set elements are incorrect" )
2918
2919 main.step( "Distributed Set size" )
2920 sizeResponses = []
2921 threads = []
2922 for i in range( numControllers ):
2923 t = main.Thread( target=CLIs[i].setTestSize,
2924 name="setTestSize-" + str( i ),
2925 args=[ onosSetName ] )
2926 threads.append( t )
2927 t.start()
2928 for t in threads:
2929 t.join()
2930 sizeResponses.append( t.result )
2931
2932 sizeResults = main.TRUE
2933 for i in range( numControllers ):
2934 if size != sizeResponses[ i ]:
2935 sizeResults = main.FALSE
2936 main.log.error( "ONOS" + str( i + 1 ) +
2937 " expected a size of " + str( size ) +
2938 " for set " + onosSetName +
2939 " but got " + str( sizeResponses[ i ] ) )
2940 utilities.assert_equals( expect=main.TRUE,
2941 actual=sizeResults,
2942 onpass="Set sizes are correct",
2943 onfail="Set sizes are incorrect" )
2944
2945 main.step( "Distributed Set add()" )
2946 onosSet.add( addValue )
2947 addResponses = []
2948 threads = []
2949 for i in range( numControllers ):
2950 t = main.Thread( target=CLIs[i].setTestAdd,
2951 name="setTestAdd-" + str( i ),
2952 args=[ onosSetName, addValue ] )
2953 threads.append( t )
2954 t.start()
2955 for t in threads:
2956 t.join()
2957 addResponses.append( t.result )
2958
2959 # main.TRUE = successfully changed the set
2960 # main.FALSE = action resulted in no change in set
2961 # main.ERROR - Some error in executing the function
2962 addResults = main.TRUE
2963 for i in range( numControllers ):
2964 if addResponses[ i ] == main.TRUE:
2965 # All is well
2966 pass
2967 elif addResponses[ i ] == main.FALSE:
2968 # Already in set, probably fine
2969 pass
2970 elif addResponses[ i ] == main.ERROR:
2971 # Error in execution
2972 addResults = main.FALSE
2973 else:
2974 # unexpected result
2975 addResults = main.FALSE
2976 if addResults != main.TRUE:
2977 main.log.error( "Error executing set add" )
2978
2979 # Check if set is still correct
2980 size = len( onosSet )
2981 getResponses = []
2982 threads = []
2983 for i in range( numControllers ):
2984 t = main.Thread( target=CLIs[i].setTestGet,
2985 name="setTestGet-" + str( i ),
2986 args=[ onosSetName ] )
2987 threads.append( t )
2988 t.start()
2989 for t in threads:
2990 t.join()
2991 getResponses.append( t.result )
2992 getResults = main.TRUE
2993 for i in range( numControllers ):
2994 if isinstance( getResponses[ i ], list):
2995 current = set( getResponses[ i ] )
2996 if len( current ) == len( getResponses[ i ] ):
2997 # no repeats
2998 if onosSet != current:
2999 main.log.error( "ONOS" + str( i + 1 ) +
3000 " has incorrect view" +
3001 " of set " + onosSetName + ":\n" +
3002 str( getResponses[ i ] ) )
3003 main.log.debug( "Expected: " + str( onosSet ) )
3004 main.log.debug( "Actual: " + str( current ) )
3005 getResults = main.FALSE
3006 else:
3007 # error, set is not a set
3008 main.log.error( "ONOS" + str( i + 1 ) +
3009 " has repeat elements in" +
3010 " set " + onosSetName + ":\n" +
3011 str( getResponses[ i ] ) )
3012 getResults = main.FALSE
3013 elif getResponses[ i ] == main.ERROR:
3014 getResults = main.FALSE
3015 sizeResponses = []
3016 threads = []
3017 for i in range( numControllers ):
3018 t = main.Thread( target=CLIs[i].setTestSize,
3019 name="setTestSize-" + str( i ),
3020 args=[ onosSetName ] )
3021 threads.append( t )
3022 t.start()
3023 for t in threads:
3024 t.join()
3025 sizeResponses.append( t.result )
3026 sizeResults = main.TRUE
3027 for i in range( numControllers ):
3028 if size != sizeResponses[ i ]:
3029 sizeResults = main.FALSE
3030 main.log.error( "ONOS" + str( i + 1 ) +
3031 " expected a size of " + str( size ) +
3032 " for set " + onosSetName +
3033 " but got " + str( sizeResponses[ i ] ) )
3034 addResults = addResults and getResults and sizeResults
3035 utilities.assert_equals( expect=main.TRUE,
3036 actual=addResults,
3037 onpass="Set add correct",
3038 onfail="Set add was incorrect" )
3039
3040 main.step( "Distributed Set addAll()" )
3041 onosSet.update( addAllValue.split() )
3042 addResponses = []
3043 threads = []
3044 for i in range( numControllers ):
3045 t = main.Thread( target=CLIs[i].setTestAdd,
3046 name="setTestAddAll-" + str( i ),
3047 args=[ onosSetName, addAllValue ] )
3048 threads.append( t )
3049 t.start()
3050 for t in threads:
3051 t.join()
3052 addResponses.append( t.result )
3053
3054 # main.TRUE = successfully changed the set
3055 # main.FALSE = action resulted in no change in set
3056 # main.ERROR - Some error in executing the function
3057 addAllResults = main.TRUE
3058 for i in range( numControllers ):
3059 if addResponses[ i ] == main.TRUE:
3060 # All is well
3061 pass
3062 elif addResponses[ i ] == main.FALSE:
3063 # Already in set, probably fine
3064 pass
3065 elif addResponses[ i ] == main.ERROR:
3066 # Error in execution
3067 addAllResults = main.FALSE
3068 else:
3069 # unexpected result
3070 addAllResults = main.FALSE
3071 if addAllResults != main.TRUE:
3072 main.log.error( "Error executing set addAll" )
3073
3074 # Check if set is still correct
3075 size = len( onosSet )
3076 getResponses = []
3077 threads = []
3078 for i in range( numControllers ):
3079 t = main.Thread( target=CLIs[i].setTestGet,
3080 name="setTestGet-" + str( i ),
3081 args=[ onosSetName ] )
3082 threads.append( t )
3083 t.start()
3084 for t in threads:
3085 t.join()
3086 getResponses.append( t.result )
3087 getResults = main.TRUE
3088 for i in range( numControllers ):
3089 if isinstance( getResponses[ i ], list):
3090 current = set( getResponses[ i ] )
3091 if len( current ) == len( getResponses[ i ] ):
3092 # no repeats
3093 if onosSet != current:
3094 main.log.error( "ONOS" + str( i + 1 ) +
3095 " has incorrect view" +
3096 " of set " + onosSetName + ":\n" +
3097 str( getResponses[ i ] ) )
3098 main.log.debug( "Expected: " + str( onosSet ) )
3099 main.log.debug( "Actual: " + str( current ) )
3100 getResults = main.FALSE
3101 else:
3102 # error, set is not a set
3103 main.log.error( "ONOS" + str( i + 1 ) +
3104 " has repeat elements in" +
3105 " set " + onosSetName + ":\n" +
3106 str( getResponses[ i ] ) )
3107 getResults = main.FALSE
3108 elif getResponses[ i ] == main.ERROR:
3109 getResults = main.FALSE
3110 sizeResponses = []
3111 threads = []
3112 for i in range( numControllers ):
3113 t = main.Thread( target=CLIs[i].setTestSize,
3114 name="setTestSize-" + str( i ),
3115 args=[ onosSetName ] )
3116 threads.append( t )
3117 t.start()
3118 for t in threads:
3119 t.join()
3120 sizeResponses.append( t.result )
3121 sizeResults = main.TRUE
3122 for i in range( numControllers ):
3123 if size != sizeResponses[ i ]:
3124 sizeResults = main.FALSE
3125 main.log.error( "ONOS" + str( i + 1 ) +
3126 " expected a size of " + str( size ) +
3127 " for set " + onosSetName +
3128 " but got " + str( sizeResponses[ i ] ) )
3129 addAllResults = addAllResults and getResults and sizeResults
3130 utilities.assert_equals( expect=main.TRUE,
3131 actual=addAllResults,
3132 onpass="Set addAll correct",
3133 onfail="Set addAll was incorrect" )
3134
3135 main.step( "Distributed Set contains()" )
3136 containsResponses = []
3137 threads = []
3138 for i in range( numControllers ):
3139 t = main.Thread( target=CLIs[i].setTestGet,
3140 name="setContains-" + str( i ),
3141 args=[ onosSetName ],
3142 kwargs={ "values": addValue } )
3143 threads.append( t )
3144 t.start()
3145 for t in threads:
3146 t.join()
3147 # NOTE: This is the tuple
3148 containsResponses.append( t.result )
3149
3150 containsResults = main.TRUE
3151 for i in range( numControllers ):
3152 if containsResponses[ i ] == main.ERROR:
3153 containsResults = main.FALSE
3154 else:
3155 containsResults = containsResults and\
3156 containsResponses[ i ][ 1 ]
3157 utilities.assert_equals( expect=main.TRUE,
3158 actual=containsResults,
3159 onpass="Set contains is functional",
3160 onfail="Set contains failed" )
3161
3162 main.step( "Distributed Set containsAll()" )
3163 containsAllResponses = []
3164 threads = []
3165 for i in range( numControllers ):
3166 t = main.Thread( target=CLIs[i].setTestGet,
3167 name="setContainsAll-" + str( i ),
3168 args=[ onosSetName ],
3169 kwargs={ "values": addAllValue } )
3170 threads.append( t )
3171 t.start()
3172 for t in threads:
3173 t.join()
3174 # NOTE: This is the tuple
3175 containsAllResponses.append( t.result )
3176
3177 containsAllResults = main.TRUE
3178 for i in range( numControllers ):
3179 if containsResponses[ i ] == main.ERROR:
3180 containsResults = main.FALSE
3181 else:
3182 containsResults = containsResults and\
3183 containsResponses[ i ][ 1 ]
3184 utilities.assert_equals( expect=main.TRUE,
3185 actual=containsAllResults,
3186 onpass="Set containsAll is functional",
3187 onfail="Set containsAll failed" )
3188
3189 main.step( "Distributed Set remove()" )
3190 onosSet.remove( addValue )
3191 removeResponses = []
3192 threads = []
3193 for i in range( numControllers ):
3194 t = main.Thread( target=CLIs[i].setTestRemove,
3195 name="setTestRemove-" + str( i ),
3196 args=[ onosSetName, addValue ] )
3197 threads.append( t )
3198 t.start()
3199 for t in threads:
3200 t.join()
3201 removeResponses.append( t.result )
3202
3203 # main.TRUE = successfully changed the set
3204 # main.FALSE = action resulted in no change in set
3205 # main.ERROR - Some error in executing the function
3206 removeResults = main.TRUE
3207 for i in range( numControllers ):
3208 if removeResponses[ i ] == main.TRUE:
3209 # All is well
3210 pass
3211 elif removeResponses[ i ] == main.FALSE:
3212 # not in set, probably fine
3213 pass
3214 elif removeResponses[ i ] == main.ERROR:
3215 # Error in execution
3216 removeResults = main.FALSE
3217 else:
3218 # unexpected result
3219 removeResults = main.FALSE
3220 if removeResults != main.TRUE:
3221 main.log.error( "Error executing set remove" )
3222
3223 # Check if set is still correct
3224 size = len( onosSet )
3225 getResponses = []
3226 threads = []
3227 for i in range( numControllers ):
3228 t = main.Thread( target=CLIs[i].setTestGet,
3229 name="setTestGet-" + str( i ),
3230 args=[ onosSetName ] )
3231 threads.append( t )
3232 t.start()
3233 for t in threads:
3234 t.join()
3235 getResponses.append( t.result )
3236 getResults = main.TRUE
3237 for i in range( numControllers ):
3238 if isinstance( getResponses[ i ], list):
3239 current = set( getResponses[ i ] )
3240 if len( current ) == len( getResponses[ i ] ):
3241 # no repeats
3242 if onosSet != current:
3243 main.log.error( "ONOS" + str( i + 1 ) +
3244 " has incorrect view" +
3245 " of set " + onosSetName + ":\n" +
3246 str( getResponses[ i ] ) )
3247 main.log.debug( "Expected: " + str( onosSet ) )
3248 main.log.debug( "Actual: " + str( current ) )
3249 getResults = main.FALSE
3250 else:
3251 # error, set is not a set
3252 main.log.error( "ONOS" + str( i + 1 ) +
3253 " has repeat elements in" +
3254 " set " + onosSetName + ":\n" +
3255 str( getResponses[ i ] ) )
3256 getResults = main.FALSE
3257 elif getResponses[ i ] == main.ERROR:
3258 getResults = main.FALSE
3259 sizeResponses = []
3260 threads = []
3261 for i in range( numControllers ):
3262 t = main.Thread( target=CLIs[i].setTestSize,
3263 name="setTestSize-" + str( i ),
3264 args=[ onosSetName ] )
3265 threads.append( t )
3266 t.start()
3267 for t in threads:
3268 t.join()
3269 sizeResponses.append( t.result )
3270 sizeResults = main.TRUE
3271 for i in range( numControllers ):
3272 if size != sizeResponses[ i ]:
3273 sizeResults = main.FALSE
3274 main.log.error( "ONOS" + str( i + 1 ) +
3275 " expected a size of " + str( size ) +
3276 " for set " + onosSetName +
3277 " but got " + str( sizeResponses[ i ] ) )
3278 removeResults = removeResults and getResults and sizeResults
3279 utilities.assert_equals( expect=main.TRUE,
3280 actual=removeResults,
3281 onpass="Set remove correct",
3282 onfail="Set remove was incorrect" )
3283
3284 main.step( "Distributed Set removeAll()" )
3285 onosSet.difference_update( addAllValue.split() )
3286 removeAllResponses = []
3287 threads = []
3288 try:
3289 for i in range( numControllers ):
3290 t = main.Thread( target=CLIs[i].setTestRemove,
3291 name="setTestRemoveAll-" + str( i ),
3292 args=[ onosSetName, addAllValue ] )
3293 threads.append( t )
3294 t.start()
3295 for t in threads:
3296 t.join()
3297 removeAllResponses.append( t.result )
3298 except Exception, e:
3299 main.log.exception(e)
3300
3301 # main.TRUE = successfully changed the set
3302 # main.FALSE = action resulted in no change in set
3303 # main.ERROR - Some error in executing the function
3304 removeAllResults = main.TRUE
3305 for i in range( numControllers ):
3306 if removeAllResponses[ i ] == main.TRUE:
3307 # All is well
3308 pass
3309 elif removeAllResponses[ i ] == main.FALSE:
3310 # not in set, probably fine
3311 pass
3312 elif removeAllResponses[ i ] == main.ERROR:
3313 # Error in execution
3314 removeAllResults = main.FALSE
3315 else:
3316 # unexpected result
3317 removeAllResults = main.FALSE
3318 if removeAllResults != main.TRUE:
3319 main.log.error( "Error executing set removeAll" )
3320
3321 # Check if set is still correct
3322 size = len( onosSet )
3323 getResponses = []
3324 threads = []
3325 for i in range( numControllers ):
3326 t = main.Thread( target=CLIs[i].setTestGet,
3327 name="setTestGet-" + str( i ),
3328 args=[ onosSetName ] )
3329 threads.append( t )
3330 t.start()
3331 for t in threads:
3332 t.join()
3333 getResponses.append( t.result )
3334 getResults = main.TRUE
3335 for i in range( numControllers ):
3336 if isinstance( getResponses[ i ], list):
3337 current = set( getResponses[ i ] )
3338 if len( current ) == len( getResponses[ i ] ):
3339 # no repeats
3340 if onosSet != current:
3341 main.log.error( "ONOS" + str( i + 1 ) +
3342 " has incorrect view" +
3343 " of set " + onosSetName + ":\n" +
3344 str( getResponses[ i ] ) )
3345 main.log.debug( "Expected: " + str( onosSet ) )
3346 main.log.debug( "Actual: " + str( current ) )
3347 getResults = main.FALSE
3348 else:
3349 # error, set is not a set
3350 main.log.error( "ONOS" + str( i + 1 ) +
3351 " has repeat elements in" +
3352 " set " + onosSetName + ":\n" +
3353 str( getResponses[ i ] ) )
3354 getResults = main.FALSE
3355 elif getResponses[ i ] == main.ERROR:
3356 getResults = main.FALSE
3357 sizeResponses = []
3358 threads = []
3359 for i in range( numControllers ):
3360 t = main.Thread( target=CLIs[i].setTestSize,
3361 name="setTestSize-" + str( i ),
3362 args=[ onosSetName ] )
3363 threads.append( t )
3364 t.start()
3365 for t in threads:
3366 t.join()
3367 sizeResponses.append( t.result )
3368 sizeResults = main.TRUE
3369 for i in range( numControllers ):
3370 if size != sizeResponses[ i ]:
3371 sizeResults = main.FALSE
3372 main.log.error( "ONOS" + str( i + 1 ) +
3373 " expected a size of " + str( size ) +
3374 " for set " + onosSetName +
3375 " but got " + str( sizeResponses[ i ] ) )
3376 removeAllResults = removeAllResults and getResults and sizeResults
3377 utilities.assert_equals( expect=main.TRUE,
3378 actual=removeAllResults,
3379 onpass="Set removeAll correct",
3380 onfail="Set removeAll was incorrect" )
3381
3382 main.step( "Distributed Set addAll()" )
3383 onosSet.update( addAllValue.split() )
3384 addResponses = []
3385 threads = []
3386 for i in range( numControllers ):
3387 t = main.Thread( target=CLIs[i].setTestAdd,
3388 name="setTestAddAll-" + str( i ),
3389 args=[ onosSetName, addAllValue ] )
3390 threads.append( t )
3391 t.start()
3392 for t in threads:
3393 t.join()
3394 addResponses.append( t.result )
3395
3396 # main.TRUE = successfully changed the set
3397 # main.FALSE = action resulted in no change in set
3398 # main.ERROR - Some error in executing the function
3399 addAllResults = main.TRUE
3400 for i in range( numControllers ):
3401 if addResponses[ i ] == main.TRUE:
3402 # All is well
3403 pass
3404 elif addResponses[ i ] == main.FALSE:
3405 # Already in set, probably fine
3406 pass
3407 elif addResponses[ i ] == main.ERROR:
3408 # Error in execution
3409 addAllResults = main.FALSE
3410 else:
3411 # unexpected result
3412 addAllResults = main.FALSE
3413 if addAllResults != main.TRUE:
3414 main.log.error( "Error executing set addAll" )
3415
3416 # Check if set is still correct
3417 size = len( onosSet )
3418 getResponses = []
3419 threads = []
3420 for i in range( numControllers ):
3421 t = main.Thread( target=CLIs[i].setTestGet,
3422 name="setTestGet-" + str( i ),
3423 args=[ onosSetName ] )
3424 threads.append( t )
3425 t.start()
3426 for t in threads:
3427 t.join()
3428 getResponses.append( t.result )
3429 getResults = main.TRUE
3430 for i in range( numControllers ):
3431 if isinstance( getResponses[ i ], list):
3432 current = set( getResponses[ i ] )
3433 if len( current ) == len( getResponses[ i ] ):
3434 # no repeats
3435 if onosSet != current:
3436 main.log.error( "ONOS" + str( i + 1 ) +
3437 " has incorrect view" +
3438 " of set " + onosSetName + ":\n" +
3439 str( getResponses[ i ] ) )
3440 main.log.debug( "Expected: " + str( onosSet ) )
3441 main.log.debug( "Actual: " + str( current ) )
3442 getResults = main.FALSE
3443 else:
3444 # error, set is not a set
3445 main.log.error( "ONOS" + str( i + 1 ) +
3446 " has repeat elements in" +
3447 " set " + onosSetName + ":\n" +
3448 str( getResponses[ i ] ) )
3449 getResults = main.FALSE
3450 elif getResponses[ i ] == main.ERROR:
3451 getResults = main.FALSE
3452 sizeResponses = []
3453 threads = []
3454 for i in range( numControllers ):
3455 t = main.Thread( target=CLIs[i].setTestSize,
3456 name="setTestSize-" + str( i ),
3457 args=[ onosSetName ] )
3458 threads.append( t )
3459 t.start()
3460 for t in threads:
3461 t.join()
3462 sizeResponses.append( t.result )
3463 sizeResults = main.TRUE
3464 for i in range( numControllers ):
3465 if size != sizeResponses[ i ]:
3466 sizeResults = main.FALSE
3467 main.log.error( "ONOS" + str( i + 1 ) +
3468 " expected a size of " + str( size ) +
3469 " for set " + onosSetName +
3470 " but got " + str( sizeResponses[ i ] ) )
3471 addAllResults = addAllResults and getResults and sizeResults
3472 utilities.assert_equals( expect=main.TRUE,
3473 actual=addAllResults,
3474 onpass="Set addAll correct",
3475 onfail="Set addAll was incorrect" )
3476
3477 main.step( "Distributed Set clear()" )
3478 onosSet.clear()
3479 clearResponses = []
3480 threads = []
3481 for i in range( numControllers ):
3482 t = main.Thread( target=CLIs[i].setTestRemove,
3483 name="setTestClear-" + str( i ),
3484 args=[ onosSetName, " "], # Values doesn't matter
3485 kwargs={ "clear": True } )
3486 threads.append( t )
3487 t.start()
3488 for t in threads:
3489 t.join()
3490 clearResponses.append( t.result )
3491
3492 # main.TRUE = successfully changed the set
3493 # main.FALSE = action resulted in no change in set
3494 # main.ERROR - Some error in executing the function
3495 clearResults = main.TRUE
3496 for i in range( numControllers ):
3497 if clearResponses[ i ] == main.TRUE:
3498 # All is well
3499 pass
3500 elif clearResponses[ i ] == main.FALSE:
3501 # Nothing set, probably fine
3502 pass
3503 elif clearResponses[ i ] == main.ERROR:
3504 # Error in execution
3505 clearResults = main.FALSE
3506 else:
3507 # unexpected result
3508 clearResults = main.FALSE
3509 if clearResults != main.TRUE:
3510 main.log.error( "Error executing set clear" )
3511
3512 # Check if set is still correct
3513 size = len( onosSet )
3514 getResponses = []
3515 threads = []
3516 for i in range( numControllers ):
3517 t = main.Thread( target=CLIs[i].setTestGet,
3518 name="setTestGet-" + str( i ),
3519 args=[ onosSetName ] )
3520 threads.append( t )
3521 t.start()
3522 for t in threads:
3523 t.join()
3524 getResponses.append( t.result )
3525 getResults = main.TRUE
3526 for i in range( numControllers ):
3527 if isinstance( getResponses[ i ], list):
3528 current = set( getResponses[ i ] )
3529 if len( current ) == len( getResponses[ i ] ):
3530 # no repeats
3531 if onosSet != current:
3532 main.log.error( "ONOS" + str( i + 1 ) +
3533 " has incorrect view" +
3534 " of set " + onosSetName + ":\n" +
3535 str( getResponses[ i ] ) )
3536 main.log.debug( "Expected: " + str( onosSet ) )
3537 main.log.debug( "Actual: " + str( current ) )
3538 getResults = main.FALSE
3539 else:
3540 # error, set is not a set
3541 main.log.error( "ONOS" + str( i + 1 ) +
3542 " has repeat elements in" +
3543 " set " + onosSetName + ":\n" +
3544 str( getResponses[ i ] ) )
3545 getResults = main.FALSE
3546 elif getResponses[ i ] == main.ERROR:
3547 getResults = main.FALSE
3548 sizeResponses = []
3549 threads = []
3550 for i in range( numControllers ):
3551 t = main.Thread( target=CLIs[i].setTestSize,
3552 name="setTestSize-" + str( i ),
3553 args=[ onosSetName ] )
3554 threads.append( t )
3555 t.start()
3556 for t in threads:
3557 t.join()
3558 sizeResponses.append( t.result )
3559 sizeResults = main.TRUE
3560 for i in range( numControllers ):
3561 if size != sizeResponses[ i ]:
3562 sizeResults = main.FALSE
3563 main.log.error( "ONOS" + str( i + 1 ) +
3564 " expected a size of " + str( size ) +
3565 " for set " + onosSetName +
3566 " but got " + str( sizeResponses[ i ] ) )
3567 clearResults = clearResults and getResults and sizeResults
3568 utilities.assert_equals( expect=main.TRUE,
3569 actual=clearResults,
3570 onpass="Set clear correct",
3571 onfail="Set clear was incorrect" )
3572
3573 main.step( "Distributed Set addAll()" )
3574 onosSet.update( addAllValue.split() )
3575 addResponses = []
3576 threads = []
3577 for i in range( numControllers ):
3578 t = main.Thread( target=CLIs[i].setTestAdd,
3579 name="setTestAddAll-" + str( i ),
3580 args=[ onosSetName, addAllValue ] )
3581 threads.append( t )
3582 t.start()
3583 for t in threads:
3584 t.join()
3585 addResponses.append( t.result )
3586
3587 # main.TRUE = successfully changed the set
3588 # main.FALSE = action resulted in no change in set
3589 # main.ERROR - Some error in executing the function
3590 addAllResults = main.TRUE
3591 for i in range( numControllers ):
3592 if addResponses[ i ] == main.TRUE:
3593 # All is well
3594 pass
3595 elif addResponses[ i ] == main.FALSE:
3596 # Already in set, probably fine
3597 pass
3598 elif addResponses[ i ] == main.ERROR:
3599 # Error in execution
3600 addAllResults = main.FALSE
3601 else:
3602 # unexpected result
3603 addAllResults = main.FALSE
3604 if addAllResults != main.TRUE:
3605 main.log.error( "Error executing set addAll" )
3606
3607 # Check if set is still correct
3608 size = len( onosSet )
3609 getResponses = []
3610 threads = []
3611 for i in range( numControllers ):
3612 t = main.Thread( target=CLIs[i].setTestGet,
3613 name="setTestGet-" + str( i ),
3614 args=[ onosSetName ] )
3615 threads.append( t )
3616 t.start()
3617 for t in threads:
3618 t.join()
3619 getResponses.append( t.result )
3620 getResults = main.TRUE
3621 for i in range( numControllers ):
3622 if isinstance( getResponses[ i ], list):
3623 current = set( getResponses[ i ] )
3624 if len( current ) == len( getResponses[ i ] ):
3625 # no repeats
3626 if onosSet != current:
3627 main.log.error( "ONOS" + str( i + 1 ) +
3628 " has incorrect view" +
3629 " of set " + onosSetName + ":\n" +
3630 str( getResponses[ i ] ) )
3631 main.log.debug( "Expected: " + str( onosSet ) )
3632 main.log.debug( "Actual: " + str( current ) )
3633 getResults = main.FALSE
3634 else:
3635 # error, set is not a set
3636 main.log.error( "ONOS" + str( i + 1 ) +
3637 " has repeat elements in" +
3638 " set " + onosSetName + ":\n" +
3639 str( getResponses[ i ] ) )
3640 getResults = main.FALSE
3641 elif getResponses[ i ] == main.ERROR:
3642 getResults = main.FALSE
3643 sizeResponses = []
3644 threads = []
3645 for i in range( numControllers ):
3646 t = main.Thread( target=CLIs[i].setTestSize,
3647 name="setTestSize-" + str( i ),
3648 args=[ onosSetName ] )
3649 threads.append( t )
3650 t.start()
3651 for t in threads:
3652 t.join()
3653 sizeResponses.append( t.result )
3654 sizeResults = main.TRUE
3655 for i in range( numControllers ):
3656 if size != sizeResponses[ i ]:
3657 sizeResults = main.FALSE
3658 main.log.error( "ONOS" + str( i + 1 ) +
3659 " expected a size of " + str( size ) +
3660 " for set " + onosSetName +
3661 " but got " + str( sizeResponses[ i ] ) )
3662 addAllResults = addAllResults and getResults and sizeResults
3663 utilities.assert_equals( expect=main.TRUE,
3664 actual=addAllResults,
3665 onpass="Set addAll correct",
3666 onfail="Set addAll was incorrect" )
3667
3668 main.step( "Distributed Set retain()" )
3669 onosSet.intersection_update( retainValue.split() )
3670 retainResponses = []
3671 threads = []
3672 for i in range( numControllers ):
3673 t = main.Thread( target=CLIs[i].setTestRemove,
3674 name="setTestRetain-" + str( i ),
3675 args=[ onosSetName, retainValue ],
3676 kwargs={ "retain": True } )
3677 threads.append( t )
3678 t.start()
3679 for t in threads:
3680 t.join()
3681 retainResponses.append( t.result )
3682
3683 # main.TRUE = successfully changed the set
3684 # main.FALSE = action resulted in no change in set
3685 # main.ERROR - Some error in executing the function
3686 retainResults = main.TRUE
3687 for i in range( numControllers ):
3688 if retainResponses[ i ] == main.TRUE:
3689 # All is well
3690 pass
3691 elif retainResponses[ i ] == main.FALSE:
3692 # Already in set, probably fine
3693 pass
3694 elif retainResponses[ i ] == main.ERROR:
3695 # Error in execution
3696 retainResults = main.FALSE
3697 else:
3698 # unexpected result
3699 retainResults = main.FALSE
3700 if retainResults != main.TRUE:
3701 main.log.error( "Error executing set retain" )
3702
3703 # Check if set is still correct
3704 size = len( onosSet )
3705 getResponses = []
3706 threads = []
3707 for i in range( numControllers ):
3708 t = main.Thread( target=CLIs[i].setTestGet,
3709 name="setTestGet-" + str( i ),
3710 args=[ onosSetName ] )
3711 threads.append( t )
3712 t.start()
3713 for t in threads:
3714 t.join()
3715 getResponses.append( t.result )
3716 getResults = main.TRUE
3717 for i in range( numControllers ):
3718 if isinstance( getResponses[ i ], list):
3719 current = set( getResponses[ i ] )
3720 if len( current ) == len( getResponses[ i ] ):
3721 # no repeats
3722 if onosSet != current:
3723 main.log.error( "ONOS" + str( i + 1 ) +
3724 " has incorrect view" +
3725 " of set " + onosSetName + ":\n" +
3726 str( getResponses[ i ] ) )
3727 main.log.debug( "Expected: " + str( onosSet ) )
3728 main.log.debug( "Actual: " + str( current ) )
3729 getResults = main.FALSE
3730 else:
3731 # error, set is not a set
3732 main.log.error( "ONOS" + str( i + 1 ) +
3733 " has repeat elements in" +
3734 " set " + onosSetName + ":\n" +
3735 str( getResponses[ i ] ) )
3736 getResults = main.FALSE
3737 elif getResponses[ i ] == main.ERROR:
3738 getResults = main.FALSE
3739 sizeResponses = []
3740 threads = []
3741 for i in range( numControllers ):
3742 t = main.Thread( target=CLIs[i].setTestSize,
3743 name="setTestSize-" + str( i ),
3744 args=[ onosSetName ] )
3745 threads.append( t )
3746 t.start()
3747 for t in threads:
3748 t.join()
3749 sizeResponses.append( t.result )
3750 sizeResults = main.TRUE
3751 for i in range( numControllers ):
3752 if size != sizeResponses[ i ]:
3753 sizeResults = main.FALSE
3754 main.log.error( "ONOS" + str( i + 1 ) +
3755 " expected a size of " +
3756 str( size ) + " for set " + onosSetName +
3757 " but got " + str( sizeResponses[ i ] ) )
3758 retainResults = retainResults and getResults and sizeResults
3759 utilities.assert_equals( expect=main.TRUE,
3760 actual=retainResults,
3761 onpass="Set retain correct",
3762 onfail="Set retain was incorrect" )
3763