blob: bb69fcc48f5c2fbb792a1ac5d5ce2153fd304159 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070021CASE16: Install Distributed Primitives app
22CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080023"""
Jon Hall8f89dda2015-01-22 16:03:33 -080024
25
Jon Hall73cf9cc2014-11-20 22:28:38 -080026class HATestClusterRestart:
27
Jon Hall6aec96b2015-01-19 14:49:31 -080028 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080029 self.default = ''
30
Jon Hall6aec96b2015-01-19 14:49:31 -080031 def CASE1( self, main ):
32 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080033 CASE1 is to compile ONOS and push it to the test machines
34
35 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080036 cell <name>
37 onos-verify-cell
38 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080039 onos-uninstall
40 start mininet
41 git pull
42 mvn clean install
43 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080044 onos-install -f
45 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080046 start cli sessions
47 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080048 """
49 main.log.report( "ONOS HA test: Restart all ONOS nodes - " +
50 "initialization" )
51 main.case( "Setting up test environment" )
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 Hall6aec96b2015-01-19 14:49:31 -0800129 else:
130 main.log.warn( "Did not pull new code so skipping mvn " +
131 "clean install" )
Jon Hall1b8f54a2015-02-04 13:24:20 -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 = "HAClusterRestart"
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 Hall8f89dda2015-01-22 16:03:33 -0800295 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800296 main.log.report( "Switch mastership assigned correctly" )
297 utilities.assert_equals(
298 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800299 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800300 onpass="Switch mastership assigned correctly",
301 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700302
303 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800304 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800305 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700306
307 ipList = [ ]
308 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800309 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700310 for i in range( 1, 29 ): # switches 1 through 28
311 # set up correct variables:
312 if i == 1:
313 ip = nodes[ 0 ].ip_address # ONOS1
314 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
315 elif i == 2:
316 ip = nodes[ 1 ].ip_address # ONOS2
317 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
318 elif i == 3:
319 ip = nodes[ 1 ].ip_address # ONOS2
320 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
321 elif i == 4:
322 ip = nodes[ 3 ].ip_address # ONOS4
323 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
324 elif i == 5:
325 ip = nodes[ 2 ].ip_address # ONOS3
326 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
327 elif i == 6:
328 ip = nodes[ 2 ].ip_address # ONOS3
329 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
330 elif i == 7:
331 ip = nodes[ 5 ].ip_address # ONOS6
332 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
333 elif i >= 8 and i <= 17:
334 ip = nodes[ 4 ].ip_address # ONOS5
335 dpid = '3' + str( i ).zfill( 3 )
336 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
337 elif i >= 18 and i <= 27:
338 ip = nodes[ 6 ].ip_address # ONOS7
339 dpid = '6' + str( i ).zfill( 3 )
340 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
341 elif i == 28:
342 ip = nodes[ 0 ].ip_address # ONOS1
343 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
344 else:
345 main.log.error( "You didn't write an else statement for " +
346 "switch s" + str( i ) )
347 # Assign switch
348 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
349 # TODO: make this controller dynamic
350 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
351 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700352 ipList.append( ip )
353 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800354 except ( AttributeError, AssertionError ):
355 main.log.exception( "Something is wrong with ONOS device view" )
356 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800357 utilities.assert_equals(
358 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800359 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800360 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800361 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800362
Jon Hall390696c2015-05-05 17:13:41 -0700363 main.step( "Check mastership was correctly assigned" )
364 roleCheck = main.TRUE
365 # NOTE: This is due to the fact that device mastership change is not
366 # atomic and is actually a multi step process
367 time.sleep( 5 )
368 for i in range( len( ipList ) ):
369 ip = ipList[i]
370 deviceId = deviceList[i]
371 # Check assignment
372 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
373 if ip in master:
374 roleCheck = roleCheck and main.TRUE
375 else:
376 roleCheck = roleCheck and main.FALSE
377 main.log.error( "Error, controller " + ip + " is not" +
378 " master " + "of device " +
379 str( deviceId ) + ". Master is " +
380 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800381 utilities.assert_equals(
382 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800383 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800384 onpass="Switches were successfully reassigned to designated " +
385 "controller",
386 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800387 mastershipCheck = mastershipCheck and roleCall and roleCheck
388 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800389 onpass="Switch mastership correctly assigned",
390 onfail="Error in (re)assigning switch" +
391 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800392
Jon Hall6aec96b2015-01-19 14:49:31 -0800393 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800394 """
395 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800396 """
397 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800398 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700399 assert numControllers, "numControllers not defined"
400 assert main, "main not defined"
401 assert utilities.assert_equals, "utilities.assert_equals not defined"
402 assert CLIs, "CLIs not defined"
403 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700404 # NOTE: we must reinstall intents until we have a persistant intent
405 # datastore!
Jon Hall6aec96b2015-01-19 14:49:31 -0800406 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700407 main.caseExplaination = "Discover hosts by using pingall then " +\
408 "assign predetermined host-to-host intents." +\
409 " After installation, check that the intent" +\
410 " is distributed to all nodes and the state" +\
411 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800412
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700414 main.step( "Install reactive forwarding app" )
415 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
416 utilities.assert_equals( expect=main.TRUE, actual=installResults,
417 onpass="Install fwd successful",
418 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700419
Jon Hallfeff3082015-05-19 10:23:26 -0700420 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700421 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700422 threads = []
423 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700424 t = main.Thread( target=CLIs[i].appToIDCheck,
425 name="appToIDCheck-" + str( i ),
426 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700427 threads.append( t )
428 t.start()
429
430 for t in threads:
431 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700432 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700433 if appCheck != main.TRUE:
434 main.log.warn( CLIs[0].apps() )
435 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700436 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
437 onpass="App Ids seem to be correct",
438 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800439
Jon Hallfeff3082015-05-19 10:23:26 -0700440 main.step( "Discovering Hosts( Via pingall for now )" )
441 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800442 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800443 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700444 for i in range(2): # Retry if pingall fails first time
445 time1 = time.time()
446 pingResult = main.Mininet1.pingall()
447 utilities.assert_equals(
448 expect=main.TRUE,
449 actual=pingResult,
450 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700451 onfail="Reactive Pingall failed, " +
452 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700453 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700454 main.log.info( "Time for pingall: %2f seconds" %
455 ( time2 - time1 ) )
456 # timeout for fwd flows
457 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800458 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700459 main.step( "Uninstall reactive forwarding app" )
460 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
461 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
462 onpass="Uninstall fwd successful",
463 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700464
465 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700466 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700467 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700468 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700469 t = main.Thread( target=CLIs[i].appToIDCheck,
470 name="appToIDCheck-" + str( i ),
471 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700472 threads.append( t )
473 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800474
Jon Hall5cfd23c2015-03-19 11:40:57 -0700475 for t in threads:
476 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700477 appCheck2 = appCheck2 and t.result
478 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700479 main.log.warn( CLIs[0].apps() )
480 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700481 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700482 onpass="App Ids seem to be correct",
483 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700484
Jon Hallfeff3082015-05-19 10:23:26 -0700485 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800486 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800487 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800488 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800489 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800490 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800491 for i in range( 8, 18 ):
492 main.log.info( "Adding host intent between h" + str( i ) +
493 " and h" + str( i + 10 ) )
494 host1 = "00:00:00:00:00:" + \
495 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
496 host2 = "00:00:00:00:00:" + \
497 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800498 # NOTE: getHost can return None
499 host1Dict = main.ONOScli1.getHost( host1 )
500 host2Dict = main.ONOScli1.getHost( host2 )
501 host1Id = None
502 host2Id = None
503 if host1Dict and host2Dict:
504 host1Id = host1Dict.get( 'id', None )
505 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800506 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700507 nodeNum = ( i % 7 )
508 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800509 if tmpId:
510 main.log.info( "Added intent with id: " + tmpId )
511 intentIds.append( tmpId )
512 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700513 main.log.error( "addHostIntent returned: " +
514 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800515 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700516 main.log.error( "Error, getHost() failed for h" + str( i ) +
517 " and/or h" + str( i + 10 ) )
518 hosts = CLIs[ 0 ].hosts()
519 main.log.warn( "Hosts output: " )
520 try:
521 main.log.warn( json.dumps( json.loads( hosts ),
522 sort_keys=True,
523 indent=4,
524 separators=( ',', ': ' ) ) )
525 except ( ValueError, TypeError ):
526 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800527 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700528 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
529 onpass="Found a host id for each host",
530 onfail="Error looking up host ids" )
531
Jon Halla9d26da2015-03-30 16:45:32 -0700532 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800533 onosIds = main.ONOScli1.getAllIntentsId()
534 main.log.info( "Submitted intents: " + str( intentIds ) )
535 main.log.info( "Intents in ONOS: " + str( onosIds ) )
536 for intent in intentIds:
537 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700538 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800539 else:
540 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700541 # FIXME: DEBUG
542 if intentAddResult:
543 intentStop = time.time()
544 else:
545 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800546 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800547 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800548 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800549 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800550 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
551 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700552 try:
553 for intent in json.loads( intents ):
554 state = intent.get( 'state', None )
555 if "INSTALLED" not in state:
556 installedCheck = False
557 intentId = intent.get( 'id', None )
558 intentStates.append( ( intentId, state ) )
559 except ( ValueError, TypeError ):
560 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800561 # add submitted intents not in the store
562 tmplist = [ i for i, s in intentStates ]
563 missingIntents = False
564 for i in intentIds:
565 if i not in tmplist:
566 intentStates.append( ( i, " - " ) )
567 missingIntents = True
568 intentStates.sort()
569 for i, s in intentStates:
570 count += 1
571 main.log.info( "%-6s%-15s%-15s" %
572 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700573 leaders = main.ONOScli1.leaders()
574 try:
575 if leaders:
576 parsedLeaders = json.loads( leaders )
577 main.log.warn( json.dumps( parsedLeaders,
578 sort_keys=True,
579 indent=4,
580 separators=( ',', ': ' ) ) )
581 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700582 topics = []
583 for i in range( 14 ):
584 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700585 main.log.debug( topics )
586 ONOStopics = [ j['topic'] for j in parsedLeaders ]
587 for topic in topics:
588 if topic not in ONOStopics:
589 main.log.error( "Error: " + topic +
590 " not in leaders" )
591 else:
592 main.log.error( "leaders() returned None" )
593 except ( ValueError, TypeError ):
594 main.log.exception( "Error parsing leaders" )
595 main.log.error( repr( leaders ) )
596 partitions = main.ONOScli1.partitions()
597 try:
598 if partitions :
599 parsedPartitions = json.loads( partitions )
600 main.log.warn( json.dumps( parsedPartitions,
601 sort_keys=True,
602 indent=4,
603 separators=( ',', ': ' ) ) )
604 # TODO check for a leader in all paritions
605 # TODO check for consistency among nodes
606 else:
607 main.log.error( "partitions() returned None" )
608 except ( ValueError, TypeError ):
609 main.log.exception( "Error parsing partitions" )
610 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800611 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700612 try:
613 if pendingMap :
614 parsedPending = json.loads( pendingMap )
615 main.log.warn( json.dumps( parsedPending,
616 sort_keys=True,
617 indent=4,
618 separators=( ',', ': ' ) ) )
619 # TODO check something here?
620 else:
621 main.log.error( "pendingMap() returned None" )
622 except ( ValueError, TypeError ):
623 main.log.exception( "Error parsing pending map" )
624 main.log.error( repr( pendingMap ) )
625
Jon Hallfeff3082015-05-19 10:23:26 -0700626 intentAddResult = bool( intentAddResult and not missingIntents and
627 installedCheck )
628 if not intentAddResult:
629 main.log.error( "Error in pushing host intents to ONOS" )
630
Jon Hall390696c2015-05-05 17:13:41 -0700631 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700632 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700633 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700634 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700635 for cli in CLIs:
636 onosIds = []
637 ids = cli.getAllIntentsId()
638 onosIds.append( ids )
639 main.log.debug( "Intents in " + cli.name + ": " +
640 str( sorted( onosIds ) ) )
641 if sorted( ids ) != sorted( intentIds ):
642 correct = False
643 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700644 break
645 else:
646 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700647 if not intentStop:
648 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700649 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700650 gossipTime = intentStop - intentStart
651 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700652 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700653 # FIXME: make this time configurable/calculate based off of number of
654 # nodes and gossip rounds
655 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700656 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700657 onpass="ECM anti-entropy for intents worked within " +
658 "expected time",
659 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700660 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700661 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800662
Jon Hall63604932015-02-26 17:09:50 -0800663 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800664 import time
Jon Hall63604932015-02-26 17:09:50 -0800665 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800666 main.log.info( "Sleeping 60 seconds to see if intents are found" )
667 time.sleep( 60 )
668 onosIds = main.ONOScli1.getAllIntentsId()
669 main.log.info( "Submitted intents: " + str( intentIds ) )
670 main.log.info( "Intents in ONOS: " + str( onosIds ) )
671 # Print the intent states
672 intents = main.ONOScli1.intents()
673 intentStates = []
674 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
675 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700676 try:
677 for intent in json.loads( intents ):
678 # Iter through intents of a node
679 state = intent.get( 'state', None )
680 if "INSTALLED" not in state:
681 installedCheck = False
682 intentId = intent.get( 'id', None )
683 intentStates.append( ( intentId, state ) )
684 except ( ValueError, TypeError ):
685 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800686 # add submitted intents not in the store
687 tmplist = [ i for i, s in intentStates ]
688 for i in intentIds:
689 if i not in tmplist:
690 intentStates.append( ( i, " - " ) )
691 intentStates.sort()
692 for i, s in intentStates:
693 count += 1
694 main.log.info( "%-6s%-15s%-15s" %
695 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700696 leaders = main.ONOScli1.leaders()
697 try:
698 if leaders:
699 parsedLeaders = json.loads( leaders )
700 main.log.warn( json.dumps( parsedLeaders,
701 sort_keys=True,
702 indent=4,
703 separators=( ',', ': ' ) ) )
704 # check for all intent partitions
705 # check for election
706 topics = []
707 for i in range( 14 ):
708 topics.append( "intent-partition-" + str( i ) )
709 # FIXME: this should only be after we start the app
710 topics.append( "org.onosproject.election" )
711 main.log.debug( topics )
712 ONOStopics = [ j['topic'] for j in parsedLeaders ]
713 for topic in topics:
714 if topic not in ONOStopics:
715 main.log.error( "Error: " + topic +
716 " not in leaders" )
717 else:
718 main.log.error( "leaders() returned None" )
719 except ( ValueError, TypeError ):
720 main.log.exception( "Error parsing leaders" )
721 main.log.error( repr( leaders ) )
722 partitions = main.ONOScli1.partitions()
723 try:
724 if partitions :
725 parsedPartitions = json.loads( partitions )
726 main.log.warn( json.dumps( parsedPartitions,
727 sort_keys=True,
728 indent=4,
729 separators=( ',', ': ' ) ) )
730 # TODO check for a leader in all paritions
731 # TODO check for consistency among nodes
732 else:
733 main.log.error( "partitions() returned None" )
734 except ( ValueError, TypeError ):
735 main.log.exception( "Error parsing partitions" )
736 main.log.error( repr( partitions ) )
737 pendingMap = main.ONOScli1.pendingMap()
738 try:
739 if pendingMap :
740 parsedPending = json.loads( pendingMap )
741 main.log.warn( json.dumps( parsedPending,
742 sort_keys=True,
743 indent=4,
744 separators=( ',', ': ' ) ) )
745 # TODO check something here?
746 else:
747 main.log.error( "pendingMap() returned None" )
748 except ( ValueError, TypeError ):
749 main.log.exception( "Error parsing pending map" )
750 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800751
Jon Hall6aec96b2015-01-19 14:49:31 -0800752 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800753 """
754 Ping across added host intents
755 """
Jon Hall58c76b72015-02-23 11:09:24 -0800756 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700757 import time
758 assert numControllers, "numControllers not defined"
759 assert main, "main not defined"
760 assert utilities.assert_equals, "utilities.assert_equals not defined"
761 assert CLIs, "CLIs not defined"
762 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700763 main.case( "Verify connectivity by sendind traffic across Intents" )
764 main.caseExplaination = "Ping across added host intents to check " +\
765 "functionality and check the state of " +\
766 "the intent"
767 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800768 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800769 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800770 ping = main.Mininet1.pingHost( src="h" + str( i ),
771 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800772 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800773 if ping == main.FALSE:
774 main.log.warn( "Ping failed between h" + str( i ) +
775 " and h" + str( i + 10 ) )
776 elif ping == main.TRUE:
777 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800778 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800779 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800780 main.log.report(
781 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800782 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700783 main.log.warn( "ONOS1 intents: " )
784 try:
785 tmpIntents = main.ONOScli1.intents()
786 main.log.warn( json.dumps( json.loads( tmpIntents ),
787 sort_keys=True,
788 indent=4,
789 separators=( ',', ': ' ) ) )
790 except ( ValueError, TypeError ):
791 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800792 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800793 main.log.report(
794 "Intents have been installed correctly and verified by pings" )
795 utilities.assert_equals(
796 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800797 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800798 onpass="Intents have been installed correctly and pings work",
799 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800800
Jon Hallfeff3082015-05-19 10:23:26 -0700801 main.step( "Check Intent state" )
Jon Hall63604932015-02-26 17:09:50 -0800802 installedCheck = True
Jon Hallfeff3082015-05-19 10:23:26 -0700803 # Print the intent states
804 intents = main.ONOScli1.intents()
805 intentStates = []
806 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
807 count = 0
808 # Iter through intents of a node
809 try:
810 for intent in json.loads( intents ):
811 state = intent.get( 'state', None )
812 if "INSTALLED" not in state:
813 installedCheck = False
814 intentId = intent.get( 'id', None )
815 intentStates.append( ( intentId, state ) )
816 except ( ValueError, TypeError ):
817 main.log.exception( "Error parsing intents." )
818 # Print states
819 intentStates.sort()
820 for i, s in intentStates:
821 count += 1
822 main.log.info( "%-6s%-15s%-15s" %
823 ( str( count ), str( i ), str( s ) ) )
824 utilities.assert_equals( expect=True, actual=installedCheck,
825 onpass="Intents are all INSTALLED",
826 onfail="Intents are not all in " +\
827 "INSTALLED state" )
828
829 main.step( "Check leadership of topics" )
830 leaders = main.ONOScli1.leaders()
831 topicCheck = main.TRUE
832 try:
833 if leaders:
834 parsedLeaders = json.loads( leaders )
835 main.log.warn( json.dumps( parsedLeaders,
836 sort_keys=True,
837 indent=4,
838 separators=( ',', ': ' ) ) )
839 # check for all intent partitions
840 # check for election
841 # TODO: Look at Devices as topics now that it uses this system
842 topics = []
843 for i in range( 14 ):
844 topics.append( "intent-partition-" + str( i ) )
845 # FIXME: this should only be after we start the app
846 # FIXME: topics.append( "org.onosproject.election" )
847 # Print leaders output
848 main.log.debug( topics )
849 ONOStopics = [ j['topic'] for j in parsedLeaders ]
850 for topic in topics:
851 if topic not in ONOStopics:
852 main.log.error( "Error: " + topic +
853 " not in leaders" )
854 topicCheck = main.FALSE
855 else:
856 main.log.error( "leaders() returned None" )
857 topicCheck = main.FALSE
858 except ( ValueError, TypeError ):
859 topicCheck = main.FALSE
860 main.log.exception( "Error parsing leaders" )
861 main.log.error( repr( leaders ) )
862 # TODO: Check for a leader of these topics
863 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
864 onpass="intent Partitions is in leaders",
865 onfail="Some topics were lost " )
866 # Print partitions
867 partitions = main.ONOScli1.partitions()
868 try:
869 if partitions :
870 parsedPartitions = json.loads( partitions )
871 main.log.warn( json.dumps( parsedPartitions,
872 sort_keys=True,
873 indent=4,
874 separators=( ',', ': ' ) ) )
875 # TODO check for a leader in all paritions
876 # TODO check for consistency among nodes
877 else:
878 main.log.error( "partitions() returned None" )
879 except ( ValueError, TypeError ):
880 main.log.exception( "Error parsing partitions" )
881 main.log.error( repr( partitions ) )
882 # Print Pending Map
883 pendingMap = main.ONOScli1.pendingMap()
884 try:
885 if pendingMap :
886 parsedPending = json.loads( pendingMap )
887 main.log.warn( json.dumps( parsedPending,
888 sort_keys=True,
889 indent=4,
890 separators=( ',', ': ' ) ) )
891 # TODO check something here?
892 else:
893 main.log.error( "pendingMap() returned None" )
894 except ( ValueError, TypeError ):
895 main.log.exception( "Error parsing pending map" )
896 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700897
Jon Hall63604932015-02-26 17:09:50 -0800898 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700899 main.log.info( "Waiting 60 seconds to see if the state of " +
900 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800901 time.sleep( 60 )
902 # Print the intent states
903 intents = main.ONOScli1.intents()
904 intentStates = []
905 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
906 count = 0
907 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700908 try:
909 for intent in json.loads( intents ):
910 state = intent.get( 'state', None )
911 if "INSTALLED" not in state:
912 installedCheck = False
913 intentId = intent.get( 'id', None )
914 intentStates.append( ( intentId, state ) )
915 except ( ValueError, TypeError ):
916 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800917 intentStates.sort()
918 for i, s in intentStates:
919 count += 1
920 main.log.info( "%-6s%-15s%-15s" %
921 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700922 leaders = main.ONOScli1.leaders()
923 try:
924 if leaders:
925 parsedLeaders = json.loads( leaders )
926 main.log.warn( json.dumps( parsedLeaders,
927 sort_keys=True,
928 indent=4,
929 separators=( ',', ': ' ) ) )
930 # check for all intent partitions
931 # check for election
932 topics = []
933 for i in range( 14 ):
934 topics.append( "intent-partition-" + str( i ) )
935 # FIXME: this should only be after we start the app
936 topics.append( "org.onosproject.election" )
937 main.log.debug( topics )
938 ONOStopics = [ j['topic'] for j in parsedLeaders ]
939 for topic in topics:
940 if topic not in ONOStopics:
941 main.log.error( "Error: " + topic +
942 " not in leaders" )
943 else:
944 main.log.error( "leaders() returned None" )
945 except ( ValueError, TypeError ):
946 main.log.exception( "Error parsing leaders" )
947 main.log.error( repr( leaders ) )
948 partitions = main.ONOScli1.partitions()
949 try:
950 if partitions :
951 parsedPartitions = json.loads( partitions )
952 main.log.warn( json.dumps( parsedPartitions,
953 sort_keys=True,
954 indent=4,
955 separators=( ',', ': ' ) ) )
956 # TODO check for a leader in all paritions
957 # TODO check for consistency among nodes
958 else:
959 main.log.error( "partitions() returned None" )
960 except ( ValueError, TypeError ):
961 main.log.exception( "Error parsing partitions" )
962 main.log.error( repr( partitions ) )
963 pendingMap = main.ONOScli1.pendingMap()
964 try:
965 if pendingMap :
966 parsedPending = json.loads( pendingMap )
967 main.log.warn( json.dumps( parsedPending,
968 sort_keys=True,
969 indent=4,
970 separators=( ',', ': ' ) ) )
971 # TODO check something here?
972 else:
973 main.log.error( "pendingMap() returned None" )
974 except ( ValueError, TypeError ):
975 main.log.exception( "Error parsing pending map" )
976 main.log.error( repr( pendingMap ) )
Jon Hall390696c2015-05-05 17:13:41 -0700977 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800978
Jon Hallfeff3082015-05-19 10:23:26 -0700979 main.step( "Wait a minute then ping again" )
980 PingResult = main.TRUE
981 for i in range( 8, 18 ):
982 ping = main.Mininet1.pingHost( src="h" + str( i ),
983 target="h" + str( i + 10 ) )
984 PingResult = PingResult and ping
985 if ping == main.FALSE:
986 main.log.warn( "Ping failed between h" + str( i ) +
987 " and h" + str( i + 10 ) )
988 elif ping == main.TRUE:
989 main.log.info( "Ping test passed!" )
990 # Don't set PingResult or you'd override failures
991 if PingResult == main.FALSE:
992 main.log.report(
993 "Intents have not been installed correctly, pings failed." )
994 # TODO: pretty print
995 main.log.warn( "ONOS1 intents: " )
996 try:
997 tmpIntents = main.ONOScli1.intents()
998 main.log.warn( json.dumps( json.loads( tmpIntents ),
999 sort_keys=True,
1000 indent=4,
1001 separators=( ',', ': ' ) ) )
1002 except ( ValueError, TypeError ):
1003 main.log.warn( repr( tmpIntents ) )
1004 utilities.assert_equals(
1005 expect=main.TRUE,
1006 actual=PingResult,
1007 onpass="Intents have been installed correctly and pings work",
1008 onfail="Intents have not been installed correctly, pings failed." )
1009
Jon Hall6aec96b2015-01-19 14:49:31 -08001010 def CASE5( self, main ):
1011 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001012 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001013 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001014 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001015 import time
1016 assert numControllers, "numControllers not defined"
1017 assert main, "main not defined"
1018 assert utilities.assert_equals, "utilities.assert_equals not defined"
1019 assert CLIs, "CLIs not defined"
1020 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001021 # assumes that sts is already in you PYTHONPATH
1022 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001023
Jon Hall6aec96b2015-01-19 14:49:31 -08001024 main.case( "Setting up and gathering data for current state" )
1025 # The general idea for this test case is to pull the state of
1026 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001027 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001028
Jon Hall5cfd23c2015-03-19 11:40:57 -07001029 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001030 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001031 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001032
Jon Hall6aec96b2015-01-19 14:49:31 -08001033 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001034 rolesNotNull = main.TRUE
1035 threads = []
1036 for i in range( numControllers ):
1037 t = main.Thread( target=CLIs[i].rolesNotNull,
1038 name="rolesNotNull-" + str( i ),
1039 args=[] )
1040 threads.append( t )
1041 t.start()
1042
1043 for t in threads:
1044 t.join()
1045 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001046 utilities.assert_equals(
1047 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001048 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001049 onpass="Each device has a master",
1050 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001051
Jon Hall5cfd23c2015-03-19 11:40:57 -07001052 main.step( "Get the Mastership of each switch from each controller" )
1053 ONOSMastership = []
1054 mastershipCheck = main.FALSE
1055 consistentMastership = True
1056 rolesResults = True
1057 threads = []
1058 for i in range( numControllers ):
1059 t = main.Thread( target=CLIs[i].roles,
1060 name="roles-" + str( i ),
1061 args=[] )
1062 threads.append( t )
1063 t.start()
1064
1065 for t in threads:
1066 t.join()
1067 ONOSMastership.append( t.result )
1068
1069 for i in range( numControllers ):
1070 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1071 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1072 " roles" )
1073 main.log.warn(
1074 "ONOS" + str( i + 1 ) + " mastership response: " +
1075 repr( ONOSMastership[i] ) )
1076 rolesResults = False
1077 utilities.assert_equals(
1078 expect=True,
1079 actual=rolesResults,
1080 onpass="No error in reading roles output",
1081 onfail="Error in reading roles from ONOS" )
1082
1083 main.step( "Check for consistency in roles from each controller" )
1084 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001085 main.log.report(
1086 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001087 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001088 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001089 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001090 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001091 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001092 onpass="Switch roles are consistent across all ONOS nodes",
1093 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001094
Jon Hall5cfd23c2015-03-19 11:40:57 -07001095 if rolesResults and not consistentMastership:
1096 for i in range( numControllers ):
1097 try:
1098 main.log.warn(
1099 "ONOS" + str( i + 1 ) + " roles: ",
1100 json.dumps(
1101 json.loads( ONOSMastership[ i ] ),
1102 sort_keys=True,
1103 indent=4,
1104 separators=( ',', ': ' ) ) )
1105 except ( ValueError, TypeError ):
1106 main.log.warn( repr( ONOSMastership[ i ] ) )
1107 elif rolesResults and consistentMastership:
1108 mastershipCheck = main.TRUE
1109 mastershipState = ONOSMastership[ 0 ]
1110
Jon Hall6aec96b2015-01-19 14:49:31 -08001111 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001112 global intentState
1113 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001114 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001115 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001116 consistentIntents = True
1117 intentsResults = True
1118 threads = []
1119 for i in range( numControllers ):
1120 t = main.Thread( target=CLIs[i].intents,
1121 name="intents-" + str( i ),
1122 args=[],
1123 kwargs={ 'jsonFormat': True } )
1124 threads.append( t )
1125 t.start()
1126
1127 for t in threads:
1128 t.join()
1129 ONOSIntents.append( t.result )
1130
1131 for i in range( numControllers ):
1132 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1133 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1134 " intents" )
1135 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1136 repr( ONOSIntents[ i ] ) )
1137 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001138 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001139 expect=True,
1140 actual=intentsResults,
1141 onpass="No error in reading intents output",
1142 onfail="Error in reading intents from ONOS" )
1143
1144 main.step( "Check for consistency in Intents from each controller" )
1145 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1146 main.log.report( "Intents are consistent across all ONOS " +
1147 "nodes" )
1148 else:
1149 consistentIntents = False
1150 main.log.report( "Intents not consistent" )
1151 utilities.assert_equals(
1152 expect=True,
1153 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001154 onpass="Intents are consistent across all ONOS nodes",
1155 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001156
Jon Hall390696c2015-05-05 17:13:41 -07001157 if intentsResults:
1158 # Try to make it easy to figure out what is happening
1159 #
1160 # Intent ONOS1 ONOS2 ...
1161 # 0x01 INSTALLED INSTALLING
1162 # ... ... ...
1163 # ... ... ...
1164 title = " Id"
1165 for n in range( numControllers ):
1166 title += " " * 10 + "ONOS" + str( n + 1 )
1167 main.log.warn( title )
1168 # get all intent keys in the cluster
1169 keys = []
1170 for nodeStr in ONOSIntents:
1171 node = json.loads( nodeStr )
1172 for intent in node:
1173 keys.append( intent.get( 'id' ) )
1174 keys = set( keys )
1175 for key in keys:
1176 row = "%-13s" % key
1177 for nodeStr in ONOSIntents:
1178 node = json.loads( nodeStr )
1179 for intent in node:
1180 if intent.get( 'id', "Error" ) == key:
1181 row += "%-15s" % intent.get( 'state' )
1182 main.log.warn( row )
1183 # End table view
1184
Jon Hall5cfd23c2015-03-19 11:40:57 -07001185 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001186 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001187 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001188 main.log.debug( "ONOS" + str( n ) + " intents: " )
1189 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1190 sort_keys=True,
1191 indent=4,
1192 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001193 for i in range( numControllers ):
1194 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001195 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1196 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1197 sort_keys=True,
1198 indent=4,
1199 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001200 else:
Jon Hall390696c2015-05-05 17:13:41 -07001201 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1202 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001203 elif intentsResults and consistentIntents:
1204 intentCheck = main.TRUE
1205 intentState = ONOSIntents[ 0 ]
1206
Jon Hall6aec96b2015-01-19 14:49:31 -08001207 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001208 global flowState
1209 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001210 ONOSFlows = []
1211 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001212 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001213 consistentFlows = True
1214 flowsResults = True
1215 threads = []
1216 for i in range( numControllers ):
1217 t = main.Thread( target=CLIs[i].flows,
1218 name="flows-" + str( i ),
1219 args=[],
1220 kwargs={ 'jsonFormat': True } )
1221 threads.append( t )
1222 t.start()
1223
Jon Halla9d26da2015-03-30 16:45:32 -07001224 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001225 time.sleep(30)
1226 for t in threads:
1227 t.join()
1228 result = t.result
1229 ONOSFlows.append( result )
1230
1231 for i in range( numControllers ):
1232 num = str( i + 1 )
1233 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1234 main.log.report( "Error in getting ONOS" + num + " flows" )
1235 main.log.warn( "ONOS" + num + " flows response: " +
1236 repr( ONOSFlows[ i ] ) )
1237 flowsResults = False
1238 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001239 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001240 try:
1241 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1242 except ( ValueError, TypeError ):
1243 # FIXME: change this to log.error?
1244 main.log.exception( "Error in parsing ONOS" + num +
1245 " response as json." )
1246 main.log.error( repr( ONOSFlows[ i ] ) )
1247 ONOSFlowsJson.append( None )
1248 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001249 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001250 expect=True,
1251 actual=flowsResults,
1252 onpass="No error in reading flows output",
1253 onfail="Error in reading flows from ONOS" )
1254
1255 main.step( "Check for consistency in Flows from each controller" )
1256 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1257 if all( tmp ):
1258 main.log.report( "Flow count is consistent across all ONOS nodes" )
1259 else:
1260 consistentFlows = False
1261 utilities.assert_equals(
1262 expect=True,
1263 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001264 onpass="The flow count is consistent across all ONOS nodes",
1265 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001266
Jon Hall5cfd23c2015-03-19 11:40:57 -07001267 if flowsResults and not consistentFlows:
1268 for i in range( numControllers ):
1269 try:
1270 main.log.warn(
1271 "ONOS" + str( i + 1 ) + " flows: " +
1272 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1273 indent=4, separators=( ',', ': ' ) ) )
1274 except ( ValueError, TypeError ):
1275 main.log.warn(
1276 "ONOS" + str( i + 1 ) + " flows: " +
1277 repr( ONOSFlows[ i ] ) )
1278 elif flowsResults and consistentFlows:
1279 flowCheck = main.TRUE
1280 flowState = ONOSFlows[ 0 ]
1281
Jon Hall6aec96b2015-01-19 14:49:31 -08001282 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001283 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001284 flows = []
1285 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001286 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001287 if flowCheck == main.FALSE:
1288 for table in flows:
1289 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001290 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001291
Jon Hall6aec96b2015-01-19 14:49:31 -08001292 main.step( "Start continuous pings" )
1293 main.Mininet2.pingLong(
1294 src=main.params[ 'PING' ][ 'source1' ],
1295 target=main.params[ 'PING' ][ 'target1' ],
1296 pingTime=500 )
1297 main.Mininet2.pingLong(
1298 src=main.params[ 'PING' ][ 'source2' ],
1299 target=main.params[ 'PING' ][ 'target2' ],
1300 pingTime=500 )
1301 main.Mininet2.pingLong(
1302 src=main.params[ 'PING' ][ 'source3' ],
1303 target=main.params[ 'PING' ][ 'target3' ],
1304 pingTime=500 )
1305 main.Mininet2.pingLong(
1306 src=main.params[ 'PING' ][ 'source4' ],
1307 target=main.params[ 'PING' ][ 'target4' ],
1308 pingTime=500 )
1309 main.Mininet2.pingLong(
1310 src=main.params[ 'PING' ][ 'source5' ],
1311 target=main.params[ 'PING' ][ 'target5' ],
1312 pingTime=500 )
1313 main.Mininet2.pingLong(
1314 src=main.params[ 'PING' ][ 'source6' ],
1315 target=main.params[ 'PING' ][ 'target6' ],
1316 pingTime=500 )
1317 main.Mininet2.pingLong(
1318 src=main.params[ 'PING' ][ 'source7' ],
1319 target=main.params[ 'PING' ][ 'target7' ],
1320 pingTime=500 )
1321 main.Mininet2.pingLong(
1322 src=main.params[ 'PING' ][ 'source8' ],
1323 target=main.params[ 'PING' ][ 'target8' ],
1324 pingTime=500 )
1325 main.Mininet2.pingLong(
1326 src=main.params[ 'PING' ][ 'source9' ],
1327 target=main.params[ 'PING' ][ 'target9' ],
1328 pingTime=500 )
1329 main.Mininet2.pingLong(
1330 src=main.params[ 'PING' ][ 'source10' ],
1331 target=main.params[ 'PING' ][ 'target10' ],
1332 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001333
Jon Hall6aec96b2015-01-19 14:49:31 -08001334 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001335 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001336 for node in nodes:
1337 temp = ( node, node.name, node.ip_address, 6633 )
1338 ctrls.append( temp )
1339 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001340
Jon Hall6aec96b2015-01-19 14:49:31 -08001341 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001342 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001343 threads = []
1344 for i in range( numControllers ):
1345 t = main.Thread( target=CLIs[i].devices,
1346 name="devices-" + str( i ),
1347 args=[ ] )
1348 threads.append( t )
1349 t.start()
1350
1351 for t in threads:
1352 t.join()
1353 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001354 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001355 threads = []
1356 for i in range( numControllers ):
1357 t = main.Thread( target=CLIs[i].hosts,
1358 name="hosts-" + str( i ),
1359 args=[ ] )
1360 threads.append( t )
1361 t.start()
1362
1363 for t in threads:
1364 t.join()
1365 try:
1366 hosts.append( json.loads( t.result ) )
1367 except ( ValueError, TypeError ):
1368 # FIXME: better handling of this, print which node
1369 # Maybe use thread name?
1370 main.log.exception( "Error parsing json output of hosts" )
1371 # FIXME: should this be an empty json object instead?
1372 hosts.append( None )
1373
Jon Hall73cf9cc2014-11-20 22:28:38 -08001374 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001375 threads = []
1376 for i in range( numControllers ):
1377 t = main.Thread( target=CLIs[i].ports,
1378 name="ports-" + str( i ),
1379 args=[ ] )
1380 threads.append( t )
1381 t.start()
1382
1383 for t in threads:
1384 t.join()
1385 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001386 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001387 threads = []
1388 for i in range( numControllers ):
1389 t = main.Thread( target=CLIs[i].links,
1390 name="links-" + str( i ),
1391 args=[ ] )
1392 threads.append( t )
1393 t.start()
1394
1395 for t in threads:
1396 t.join()
1397 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001398 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001399 threads = []
1400 for i in range( numControllers ):
1401 t = main.Thread( target=CLIs[i].clusters,
1402 name="clusters-" + str( i ),
1403 args=[ ] )
1404 threads.append( t )
1405 t.start()
1406
1407 for t in threads:
1408 t.join()
1409 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001410 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001411
Jon Hall6aec96b2015-01-19 14:49:31 -08001412 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001413 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001414 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001415 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001416 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001417 if "Error" not in hosts[ controller ]:
1418 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001419 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001420 else: # hosts not consistent
1421 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001422 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001423 " is inconsistent with ONOS1" )
1424 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001425 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001426
1427 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001428 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001429 controllerStr )
1430 consistentHostsResult = main.FALSE
1431 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001432 " hosts response: " +
1433 repr( hosts[ controller ] ) )
1434 utilities.assert_equals(
1435 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001436 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001437 onpass="Hosts view is consistent across all ONOS nodes",
1438 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001439
Jon Hall390696c2015-05-05 17:13:41 -07001440 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001441 ipResult = main.TRUE
1442 for controller in range( 0, len( hosts ) ):
1443 controllerStr = str( controller + 1 )
1444 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001445 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001446 main.log.error( "DEBUG:Error with host ips on controller" +
1447 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001448 ipResult = main.FALSE
1449 utilities.assert_equals(
1450 expect=main.TRUE,
1451 actual=ipResult,
1452 onpass="The ips of the hosts aren't empty",
1453 onfail="The ip of at least one host is missing" )
1454
Jon Hall6aec96b2015-01-19 14:49:31 -08001455 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001456 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001457 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001458 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001459 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001460 if "Error" not in clusters[ controller ]:
1461 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001462 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001463 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001464 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001465 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001466 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001467
1468 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001469 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001470 "from ONOS" + controllerStr )
1471 consistentClustersResult = main.FALSE
1472 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001473 " clusters response: " +
1474 repr( clusters[ controller ] ) )
1475 utilities.assert_equals(
1476 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001477 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001478 onpass="Clusters view is consistent across all ONOS nodes",
1479 onfail="ONOS nodes have different views of clusters" )
1480 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001481 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001482 try:
1483 numClusters = len( json.loads( clusters[ 0 ] ) )
1484 except ( ValueError, TypeError ):
1485 main.log.exception( "Error parsing clusters[0]: " +
1486 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001487 clusterResults = main.FALSE
1488 if numClusters == 1:
1489 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001490 utilities.assert_equals(
1491 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001492 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001493 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001494 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001495
Jon Hall6aec96b2015-01-19 14:49:31 -08001496 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001497 devicesResults = main.TRUE
1498 portsResults = main.TRUE
1499 linksResults = main.TRUE
1500 for controller in range( numControllers ):
1501 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001502 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001503 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001504 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001505 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001506 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001507 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001508 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001509 actual=currentDevicesResult,
1510 onpass="ONOS" + controllerStr +
1511 " Switches view is correct",
1512 onfail="ONOS" + controllerStr +
1513 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001514
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001516 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001517 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001518 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001519 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001520 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001521 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001522 actual=currentPortsResult,
1523 onpass="ONOS" + controllerStr +
1524 " ports view is correct",
1525 onfail="ONOS" + controllerStr +
1526 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001527
Jon Hall6aec96b2015-01-19 14:49:31 -08001528 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001529 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001530 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001531 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001532 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001533 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001534 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001535 actual=currentLinksResult,
1536 onpass="ONOS" + controllerStr +
1537 " links view is correct",
1538 onfail="ONOS" + controllerStr +
1539 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001540
Jon Hall8f89dda2015-01-22 16:03:33 -08001541 devicesResults = devicesResults and currentDevicesResult
1542 portsResults = portsResults and currentPortsResult
1543 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001544
Jon Hall5cfd23c2015-03-19 11:40:57 -07001545 topoResult = ( devicesResults and portsResults and linksResults
1546 and consistentHostsResult and consistentClustersResult
1547 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001548 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001549 onpass="Topology Check Test successful",
1550 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001551
Jon Hall6aec96b2015-01-19 14:49:31 -08001552 def CASE6( self, main ):
1553 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001554 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001555 """
Jon Hallfeff3082015-05-19 10:23:26 -07001556 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001557 assert numControllers, "numControllers not defined"
1558 assert main, "main not defined"
1559 assert utilities.assert_equals, "utilities.assert_equals not defined"
1560 assert CLIs, "CLIs not defined"
1561 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001562
1563 # Reset non-persistent variables
1564 try:
1565 iCounterValue = 0
1566 except NameError:
1567 main.log.error( "iCounterValue not defined, setting to 0" )
1568 iCounterValue = 0
1569
Jon Hall5cfd23c2015-03-19 11:40:57 -07001570 main.case( "Restart entire ONOS cluster" )
1571 main.step( "Killing ONOS nodes" )
1572 killResults = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001573 killTime = time.time()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001574 for node in nodes:
1575 killed = main.ONOSbench.onosKill( node.ip_address )
1576 killResults = killResults and killed
Jon Hall390696c2015-05-05 17:13:41 -07001577 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1578 onpass="ONOS nodes killed",
1579 onfail="ONOS kill unsuccessful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001580
Jon Hall6aec96b2015-01-19 14:49:31 -08001581 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001582 for i in range( 2 ):
1583 onosIsupResult = main.TRUE
1584 for node in nodes:
1585 started = main.ONOSbench.isup( node.ip_address )
1586 if not started:
1587 main.log.report( node.name + " didn't start!" )
1588 onosIsupResult = onosIsupResult and started
1589 if onosIsupResult == main.TRUE:
1590 break
Jon Hall390696c2015-05-05 17:13:41 -07001591 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1592 onpass="ONOS restarted",
1593 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001594
Jon Hall5cfd23c2015-03-19 11:40:57 -07001595 main.log.step( "Starting ONOS CLI sessions" )
1596 cliResults = main.TRUE
1597 threads = []
1598 for i in range( numControllers ):
1599 t = main.Thread( target=CLIs[i].startOnosCli,
1600 name="startOnosCli-" + str( i ),
1601 args=[nodes[i].ip_address] )
1602 threads.append( t )
1603 t.start()
1604
1605 for t in threads:
1606 t.join()
1607 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -07001608 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1609 onpass="ONOS cli started",
1610 onfail="ONOS clis did not restart" )
Jon Hallfeff3082015-05-19 10:23:26 -07001611
1612 # Grab the time of restart so we chan check how long the gossip
1613 # protocol has had time to work
1614 main.restartTime = time.time() - killTime
1615 main.log.debug( "Restart time: " + str( main.restartTime ) )
1616 '''
1617 # FIXME: revisit test plan for election with madan
1618 # Rerun for election on restarted nodes
1619 run1 = CLIs[0].electionTestRun()
1620 run2 = CLIs[1].electionTestRun()
1621 run3 = CLIs[2].electionTestRun()
1622 ...
1623 ...
1624 runResults = run1 and run2 and run3
1625 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1626 onpass="Reran for election",
1627 onfail="Failed to rerun for election" )
1628 '''
1629 # TODO: Make this configurable
1630 time.sleep( 60 )
1631 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1632 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1633 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001634
Jon Hall6aec96b2015-01-19 14:49:31 -08001635 def CASE7( self, main ):
1636 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001637 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001638 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001639 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001640 assert numControllers, "numControllers not defined"
1641 assert main, "main not defined"
1642 assert utilities.assert_equals, "utilities.assert_equals not defined"
1643 assert CLIs, "CLIs not defined"
1644 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001645 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001646
Jon Hall5cfd23c2015-03-19 11:40:57 -07001647 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001648 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001649 rolesNotNull = main.TRUE
1650 threads = []
1651 for i in range( numControllers ):
1652 t = main.Thread( target=CLIs[i].rolesNotNull,
1653 name="rolesNotNull-" + str( i ),
1654 args=[ ] )
1655 threads.append( t )
1656 t.start()
1657
1658 for t in threads:
1659 t.join()
1660 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001661 utilities.assert_equals(
1662 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001663 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001664 onpass="Each device has a master",
1665 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001666
Jon Hall390696c2015-05-05 17:13:41 -07001667 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001668 ONOSMastership = []
1669 mastershipCheck = main.FALSE
1670 consistentMastership = True
1671 rolesResults = True
1672 threads = []
1673 for i in range( numControllers ):
1674 t = main.Thread( target=CLIs[i].roles,
1675 name="roles-" + str( i ),
1676 args=[] )
1677 threads.append( t )
1678 t.start()
1679
1680 for t in threads:
1681 t.join()
1682 ONOSMastership.append( t.result )
1683
1684 for i in range( numControllers ):
1685 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1686 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1687 " roles" )
1688 main.log.warn(
1689 "ONOS" + str( i + 1 ) + " mastership response: " +
1690 repr( ONOSMastership[i] ) )
1691 rolesResults = False
1692 utilities.assert_equals(
1693 expect=True,
1694 actual=rolesResults,
1695 onpass="No error in reading roles output",
1696 onfail="Error in reading roles from ONOS" )
1697
1698 main.step( "Check for consistency in roles from each controller" )
1699 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001700 main.log.report(
1701 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001702 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001703 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001704 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001705 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001706 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001707 onpass="Switch roles are consistent across all ONOS nodes",
1708 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001709
Jon Hall5cfd23c2015-03-19 11:40:57 -07001710 if rolesResults and not consistentMastership:
1711 for i in range( numControllers ):
1712 main.log.warn(
1713 "ONOS" + str( i + 1 ) + " roles: ",
1714 json.dumps(
1715 json.loads( ONOSMastership[ i ] ),
1716 sort_keys=True,
1717 indent=4,
1718 separators=( ',', ': ' ) ) )
1719 elif rolesResults and not consistentMastership:
1720 mastershipCheck = main.TRUE
1721
Jon Hallfeff3082015-05-19 10:23:26 -07001722 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001723 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001724 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001725 try:
1726 currentJson = json.loads( ONOSMastership[0] )
1727 oldJson = json.loads( mastershipState )
1728 except ( ValueError, TypeError ):
1729 main.log.exception( "Something is wrong with parsing " +
1730 "ONOSMastership[0] or mastershipState" )
1731 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1732 main.log.error( "mastershipState" + repr( mastershipState ) )
1733 main.cleanup()
1734 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001735 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001736 for i in range( 1, 29 ):
1737 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001738 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001739 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001740 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001741 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001742 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001743 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001744 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001745 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001746 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001747 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001748 utilities.assert_equals(
1749 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001750 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001751 onpass="Mastership of Switches was not changed",
1752 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001753 '''
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 # NOTE: we expect mastership to change on controller failure
Jon Hall73cf9cc2014-11-20 22:28:38 -08001755
Jon Hall6aec96b2015-01-19 14:49:31 -08001756 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001757 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001758 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001759 consistentIntents = True
1760 intentsResults = True
1761 threads = []
1762 for i in range( numControllers ):
1763 t = main.Thread( target=CLIs[i].intents,
1764 name="intents-" + str( i ),
1765 args=[],
1766 kwargs={ 'jsonFormat': True } )
1767 threads.append( t )
1768 t.start()
1769
1770 for t in threads:
1771 t.join()
1772 ONOSIntents.append( t.result )
1773
1774 for i in range( numControllers ):
1775 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1776 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1777 " intents" )
1778 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1779 repr( ONOSIntents[ i ] ) )
1780 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001781 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001782 expect=True,
1783 actual=intentsResults,
1784 onpass="No error in reading intents output",
1785 onfail="Error in reading intents from ONOS" )
1786
1787 main.step( "Check for consistency in Intents from each controller" )
1788 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1789 main.log.report( "Intents are consistent across all ONOS " +
1790 "nodes" )
1791 else:
1792 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001793
1794 # Try to make it easy to figure out what is happening
1795 #
1796 # Intent ONOS1 ONOS2 ...
1797 # 0x01 INSTALLED INSTALLING
1798 # ... ... ...
1799 # ... ... ...
1800 title = " ID"
1801 for n in range( numControllers ):
1802 title += " " * 10 + "ONOS" + str( n + 1 )
1803 main.log.warn( title )
1804 # get all intent keys in the cluster
1805 keys = []
1806 for nodeStr in ONOSIntents:
1807 node = json.loads( nodeStr )
1808 for intent in node:
1809 keys.append( intent.get( 'id' ) )
1810 keys = set( keys )
1811 for key in keys:
1812 row = "%-13s" % key
1813 for nodeStr in ONOSIntents:
1814 node = json.loads( nodeStr )
1815 for intent in node:
1816 if intent.get( 'id' ) == key:
1817 row += "%-15s" % intent.get( 'state' )
1818 main.log.warn( row )
1819 # End table view
1820
Jon Hall5cfd23c2015-03-19 11:40:57 -07001821 utilities.assert_equals(
1822 expect=True,
1823 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001824 onpass="Intents are consistent across all ONOS nodes",
1825 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001826 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001827 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001828 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001829 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001830 try:
1831 for intent in json.loads( node ):
1832 nodeStates.append( intent[ 'state' ] )
1833 except ( ValueError, TypeError ):
1834 main.log.exception( "Error in parsing intents" )
1835 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001836 intentStates.append( nodeStates )
1837 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1838 main.log.info( dict( out ) )
1839
Jon Hall5cfd23c2015-03-19 11:40:57 -07001840 if intentsResults and not consistentIntents:
1841 for i in range( numControllers ):
1842 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1843 main.log.warn( json.dumps(
1844 json.loads( ONOSIntents[ i ] ),
1845 sort_keys=True,
1846 indent=4,
1847 separators=( ',', ': ' ) ) )
1848 elif intentsResults and consistentIntents:
1849 intentCheck = main.TRUE
1850
Jon Hall58c76b72015-02-23 11:09:24 -08001851 # NOTE: Store has no durability, so intents are lost across system
1852 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001853 """
1854 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001855 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001856 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001857 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001858 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001859 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001860 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001861 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001862 # what the acceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -08001863 else:
Jon Hall669173b2014-12-17 11:36:30 -08001864 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001865 main.log.warn( "ONOS intents: " )
1866 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1867 sort_keys=True, indent=4,
1868 separators=( ',', ': ' ) ) )
1869 except ( ValueError, TypeError ):
1870 main.log.exception( "Exception printing intents" )
1871 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001872 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001873 utilities.assert_equals(
1874 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001875 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001876 onpass="Intents are consistent with before failure",
1877 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001878 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08001879 """
1880 main.step( "Get the OF Table entries and compare to before " +
1881 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001882 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001883 flows2 = []
1884 for i in range( 28 ):
1885 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001886 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1887 flows2.append( tmpFlows )
1888 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001890 flow2=tmpFlows )
1891 FlowTables = FlowTables and tempResult
1892 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001893 main.log.info( "Differences in flow table for switch: s" +
1894 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001895 utilities.assert_equals(
1896 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001897 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001898 onpass="No changes were found in the flow tables",
1899 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001900
Jon Hall6aec96b2015-01-19 14:49:31 -08001901 main.step( "Check the continuous pings to ensure that no packets " +
1902 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001903 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1904 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001905 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001906 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1907 for i in range( 8, 18 ):
1908 main.log.info(
1909 "Checking for a loss in pings along flow from s" +
1910 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001911 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001912 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001913 str( i ) ) or LossInPings
1914 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001915 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001916 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001917 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001918 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001919 main.log.info( "No Loss in the pings" )
1920 main.log.report( "No loss of dataplane connectivity" )
1921 utilities.assert_equals(
1922 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001923 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001924 onpass="No Loss of connectivity",
1925 onfail="Loss of dataplane connectivity detected" )
Jon Hall58c76b72015-02-23 11:09:24 -08001926 # NOTE: Since intents are not persisted with IntnentStore,
1927 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08001928 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001929
Jon Hall390696c2015-05-05 17:13:41 -07001930 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001931 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001932 leaderList = []
1933 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001934 for cli in CLIs:
1935 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001936 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001937 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07001938 # error in response
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001940 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001941 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001942 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001943 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001944 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001945 " shows no leader for the election-app was" +
1946 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001947 leaderResult = main.FALSE
1948 if len( set( leaderList ) ) != 1:
1949 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001950 main.log.error(
1951 "Inconsistent view of leader for the election test app" )
1952 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08001953 utilities.assert_equals(
1954 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001955 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001956 onpass="Leadership election passed",
1957 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001958
Jon Hall6aec96b2015-01-19 14:49:31 -08001959 def CASE8( self, main ):
1960 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001961 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001962 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001963 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001964 # FIXME add this path to params
1965 sys.path.append( "/home/admin/sts" )
1966 # assumes that sts is already in you PYTHONPATH
1967 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001968 import json
1969 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001970 assert numControllers, "numControllers not defined"
1971 assert main, "main not defined"
1972 assert utilities.assert_equals, "utilities.assert_equals not defined"
1973 assert CLIs, "CLIs not defined"
1974 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001975
Jon Hallfeff3082015-05-19 10:23:26 -07001976 main.case( "Compare ONOS Topology view to Mininet topology" )
1977 main.caseExplaination = "Compare topology objects between Mininet" +\
1978 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08001979 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07001980 try:
1981 ctrls = []
1982 for node in nodes:
1983 temp = ( node, node.name, node.ip_address, 6633 )
1984 ctrls.append( temp )
1985 MNTopo = TestONTopology( main.Mininet1, ctrls )
1986 except Exception:
1987 objResult = main.FALSE
1988 else:
1989 objResult = main.TRUE
1990 utilities.assert_equals( expect=main.TRUE, actual=objResult,
1991 onpass="Created TestONTopology object",
1992 onfail="Exception while creating " +
1993 "TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001994
Jon Hallfeff3082015-05-19 10:23:26 -07001995 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001996 devicesResults = main.TRUE
1997 portsResults = main.TRUE
1998 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001999 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002000 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002001 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002002 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002004 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002005 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002006 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002007 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08002008 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002009 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08002010 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002011 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002012 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002013 threads = []
2014 for i in range( numControllers ):
2015 t = main.Thread( target=CLIs[i].devices,
2016 name="devices-" + str( i ),
2017 args=[ ] )
2018 threads.append( t )
2019 t.start()
2020
2021 for t in threads:
2022 t.join()
2023 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002024 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002025 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002026 threads = []
2027 for i in range( numControllers ):
2028 t = main.Thread( target=CLIs[i].hosts,
2029 name="hosts-" + str( i ),
2030 args=[ ] )
2031 threads.append( t )
2032 t.start()
2033
2034 for t in threads:
2035 t.join()
2036 try:
2037 hosts.append( json.loads( t.result ) )
2038 except ( ValueError, TypeError ):
2039 main.log.exception( "Error parsing hosts results" )
2040 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002041 for controller in range( 0, len( hosts ) ):
2042 controllerStr = str( controller + 1 )
2043 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002044 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002045 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07002046 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002047 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002048 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002049 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002050 threads = []
2051 for i in range( numControllers ):
2052 t = main.Thread( target=CLIs[i].ports,
2053 name="ports-" + str( i ),
2054 args=[ ] )
2055 threads.append( t )
2056 t.start()
2057
2058 for t in threads:
2059 t.join()
2060 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002061 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002062 threads = []
2063 for i in range( numControllers ):
2064 t = main.Thread( target=CLIs[i].links,
2065 name="links-" + str( i ),
2066 args=[ ] )
2067 threads.append( t )
2068 t.start()
2069
2070 for t in threads:
2071 t.join()
2072 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002073 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002074 threads = []
2075 for i in range( numControllers ):
2076 t = main.Thread( target=CLIs[i].clusters,
2077 name="clusters-" + str( i ),
2078 args=[ ] )
2079 threads.append( t )
2080 t.start()
2081
2082 for t in threads:
2083 t.join()
2084 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002085
Jon Hall8f89dda2015-01-22 16:03:33 -08002086 elapsed = time.time() - startTime
2087 cliTime = time.time() - cliStart
2088 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002089
Jon Hall8f89dda2015-01-22 16:03:33 -08002090 for controller in range( numControllers ):
2091 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002092 if devices[ controller ] or "Error" not in devices[
2093 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002094 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002095 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002096 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002097 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002098 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002099 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002100 actual=currentDevicesResult,
2101 onpass="ONOS" + controllerStr +
2102 " Switches view is correct",
2103 onfail="ONOS" + controllerStr +
2104 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002105
Jon Hall6aec96b2015-01-19 14:49:31 -08002106 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002107 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002108 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002109 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002110 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002111 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002112 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002113 actual=currentPortsResult,
2114 onpass="ONOS" + controllerStr +
2115 " ports view is correct",
2116 onfail="ONOS" + controllerStr +
2117 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002118
Jon Hall6aec96b2015-01-19 14:49:31 -08002119 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002120 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002121 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002122 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002123 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002124 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002125 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002126 actual=currentLinksResult,
2127 onpass="ONOS" + controllerStr +
2128 " links view is correct",
2129 onfail="ONOS" + controllerStr +
2130 " links view is incorrect" )
2131
2132 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2133 currentHostsResult = main.Mininet1.compareHosts(
2134 MNTopo, hosts[ controller ] )
2135 else:
2136 currentHostsResult = main.FALSE
2137 utilities.assert_equals( expect=main.TRUE,
2138 actual=currentHostsResult,
2139 onpass="ONOS" + controllerStr +
2140 " hosts exist in Mininet",
2141 onfail="ONOS" + controllerStr +
2142 " hosts don't match Mininet" )
2143
2144 devicesResults = devicesResults and currentDevicesResult
2145 portsResults = portsResults and currentPortsResult
2146 linksResults = linksResults and currentLinksResult
2147 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002148
Jon Hall529a37f2015-01-28 10:02:00 -08002149 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002150
Jon Hall6aec96b2015-01-19 14:49:31 -08002151 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002152 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002153 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002154 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002155 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002156 if "Error" not in hosts[ controller ]:
2157 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002158 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002159 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08002160 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002161 " is inconsistent with ONOS1" )
2162 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002163 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002164
2165 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002166 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002167 controllerStr )
2168 consistentHostsResult = main.FALSE
2169 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002170 " hosts response: " +
2171 repr( hosts[ controller ] ) )
2172 utilities.assert_equals(
2173 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002174 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002175 onpass="Hosts view is consistent across all ONOS nodes",
2176 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002177
Jon Hall6aec96b2015-01-19 14:49:31 -08002178 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002179 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002180 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002181 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002182 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002183 if "Error" not in clusters[ controller ]:
2184 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002185 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002186 else: # clusters not consistent
2187 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002188 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002189 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002190 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002191
2192 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002193 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002194 "from ONOS" + controllerStr )
2195 consistentClustersResult = main.FALSE
2196 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002197 " clusters response: " +
2198 repr( clusters[ controller ] ) )
2199 utilities.assert_equals(
2200 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002201 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002202 onpass="Clusters view is consistent across all ONOS nodes",
2203 onfail="ONOS nodes have different views of clusters" )
2204 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002205 main.step( "Topology view is correct and consistent across all " +
2206 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002207 try:
2208 numClusters = len( json.loads( clusters[ 0 ] ) )
2209 except ( ValueError, TypeError ):
2210 main.log.exception( "Error parsing clusters[0]: " +
2211 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002212 clusterResults = main.FALSE
2213 if numClusters == 1:
2214 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002215 utilities.assert_equals(
2216 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002217 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002218 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002219 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002220
Jon Hall8f89dda2015-01-22 16:03:33 -08002221 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002222 and hostsResults and consistentHostsResult
2223 and consistentClustersResult and clusterResults
2224 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002225
Jon Hall8f89dda2015-01-22 16:03:33 -08002226 topoResult = topoResult and int( count <= 2 )
2227 note = "note it takes about " + str( int( cliTime ) ) + \
2228 " seconds for the test to make all the cli calls to fetch " +\
2229 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002230 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002231 "Very crass estimate for topology discovery/convergence( " +
2232 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002234 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002235 onpass="Topology Check Test successful",
2236 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002237
Jon Halla9d26da2015-03-30 16:45:32 -07002238 # FIXME: move this to an ONOS state case
2239 main.step( "Checking ONOS nodes" )
2240 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002241 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002242 threads = []
2243 for i in range( numControllers ):
2244 t = main.Thread( target=CLIs[i].nodes,
2245 name="nodes-" + str( i ),
2246 args=[ ] )
2247 threads.append( t )
2248 t.start()
2249
2250 for t in threads:
2251 t.join()
2252 nodesOutput.append( t.result )
2253 ips = [ node.ip_address for node in nodes ]
2254 for i in nodesOutput:
2255 try:
2256 current = json.loads( i )
2257 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002258 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002259 if node['ip'] in ips: # node in nodes() output is in cell
2260 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002261 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002262 else:
2263 main.log.error( "Error in ONOS node availability" )
2264 main.log.error(
2265 json.dumps( current,
2266 sort_keys=True,
2267 indent=4,
2268 separators=( ',', ': ' ) ) )
2269 break
Jon Hall390696c2015-05-05 17:13:41 -07002270 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002271 except ( ValueError, TypeError ):
2272 main.log.error( "Error parsing nodes output" )
2273 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002274 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2275 onpass="Nodes check successful",
2276 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002277
Jon Hall6aec96b2015-01-19 14:49:31 -08002278 def CASE9( self, main ):
2279 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002280 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002281 """
2282 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002283 assert numControllers, "numControllers not defined"
2284 assert main, "main not defined"
2285 assert utilities.assert_equals, "utilities.assert_equals not defined"
2286 assert CLIs, "CLIs not defined"
2287 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002288 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002289
Jon Hall8f89dda2015-01-22 16:03:33 -08002290 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002291
Jon Hall6aec96b2015-01-19 14:49:31 -08002292 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002293 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002294 main.log.report( description )
2295 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002296
Jon Hall6aec96b2015-01-19 14:49:31 -08002297 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002298 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002299 main.log.info( "Waiting " + str( linkSleep ) +
2300 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002301 time.sleep( linkSleep )
2302 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002303 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002304 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002305 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002306
Jon Hall6aec96b2015-01-19 14:49:31 -08002307 def CASE10( self, main ):
2308 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002309 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002310 """
2311 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002312 assert numControllers, "numControllers not defined"
2313 assert main, "main not defined"
2314 assert utilities.assert_equals, "utilities.assert_equals not defined"
2315 assert CLIs, "CLIs not defined"
2316 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002317 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002318
Jon Hall8f89dda2015-01-22 16:03:33 -08002319 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002320
Jon Hall6aec96b2015-01-19 14:49:31 -08002321 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002322 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002323 main.log.report( description )
2324 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002325
Jon Hall6aec96b2015-01-19 14:49:31 -08002326 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002327 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002328 main.log.info( "Waiting " + str( linkSleep ) +
2329 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002330 time.sleep( linkSleep )
2331 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002332 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002333 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002334 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002335
Jon Hall6aec96b2015-01-19 14:49:31 -08002336 def CASE11( self, main ):
2337 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002338 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002339 """
2340 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002341 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002342 assert numControllers, "numControllers not defined"
2343 assert main, "main not defined"
2344 assert utilities.assert_equals, "utilities.assert_equals not defined"
2345 assert CLIs, "CLIs not defined"
2346 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002347
Jon Hall8f89dda2015-01-22 16:03:33 -08002348 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002349
2350 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002351 main.log.report( description )
2352 main.case( description )
2353 switch = main.params[ 'kill' ][ 'switch' ]
2354 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002355
Jon Hall6aec96b2015-01-19 14:49:31 -08002356 # TODO: Make this switch parameterizable
2357 main.step( "Kill " + switch )
2358 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002359 main.Mininet1.delSwitch( switch )
2360 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002361 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002362 time.sleep( switchSleep )
2363 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002364 # Peek at the deleted switch
2365 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002366 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002367 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002368 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002369 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002370 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002371 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002372
Jon Hall6aec96b2015-01-19 14:49:31 -08002373 def CASE12( self, main ):
2374 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002375 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002376 """
2377 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002378 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002379 assert numControllers, "numControllers not defined"
2380 assert main, "main not defined"
2381 assert utilities.assert_equals, "utilities.assert_equals not defined"
2382 assert CLIs, "CLIs not defined"
2383 assert nodes, "nodes not defined"
2384 assert ONOS1Port, "ONOS1Port not defined"
2385 assert ONOS2Port, "ONOS2Port not defined"
2386 assert ONOS3Port, "ONOS3Port not defined"
2387 assert ONOS4Port, "ONOS4Port not defined"
2388 assert ONOS5Port, "ONOS5Port not defined"
2389 assert ONOS6Port, "ONOS6Port not defined"
2390 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002391
Jon Hall8f89dda2015-01-22 16:03:33 -08002392 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002393 switch = main.params[ 'kill' ][ 'switch' ]
2394 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2395 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002396 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002397 main.log.report( description )
2398 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002399
Jon Hall6aec96b2015-01-19 14:49:31 -08002400 main.step( "Add back " + switch )
2401 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002402 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002403 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002404 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002405 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2406 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002407 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002408 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002409 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002410 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002411 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002412 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002413 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002414 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002415 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002416 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002417 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002418 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002419 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002420 port7=ONOS7Port )
2421 main.log.info( "Waiting " + str( switchSleep ) +
2422 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002423 time.sleep( switchSleep )
2424 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002425 # Peek at the deleted switch
2426 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002427 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002428 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002429 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002430 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002431 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002432 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002433
Jon Hall6aec96b2015-01-19 14:49:31 -08002434 def CASE13( self, main ):
2435 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002436 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002437 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002438 import os
2439 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002440 assert numControllers, "numControllers not defined"
2441 assert main, "main not defined"
2442 assert utilities.assert_equals, "utilities.assert_equals not defined"
2443 assert CLIs, "CLIs not defined"
2444 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002445
2446 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002447 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2448 'blue': '\033[94m', 'green': '\033[92m',
2449 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002450 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002451 main.log.report( description )
2452 main.case( description )
2453 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002454 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002455
Jon Hall6aec96b2015-01-19 14:49:31 -08002456 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002457 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002458 teststationUser = main.params[ 'TESTONUSER' ]
2459 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002460 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002461 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002462 # FIXME: scp
2463 # mn files
2464 # TODO: Load these from params
2465 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002466 logFolder = "/opt/onos/log/"
2467 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002468 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002469 dstDir = "~/packet_captures/"
2470 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002471 for node in nodes:
2472 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2473 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002474 teststationUser + "@" +
2475 teststationIP + ":" +
2476 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002477 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002478 main.ONOSbench.handle.expect( "\$" )
2479
Jon Hall6aec96b2015-01-19 14:49:31 -08002480 # std*.log's
2481 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002482 logFolder = "/opt/onos/var/"
2483 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002484 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002485 dstDir = "~/packet_captures/"
2486 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002487 for node in nodes:
2488 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2489 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002490 teststationUser + "@" +
2491 teststationIP + ":" +
2492 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002493 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002494 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 # sleep so scp can finish
2496 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002497
2498 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002499 mnResult = main.Mininet1.stopNet()
2500 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2501 onpass="Mininet stopped",
2502 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002503
2504 main.step( "Checking ONOS Logs for errors" )
2505 for node in nodes:
2506 print colors[ 'purple' ] + "Checking logs for errors on " + \
2507 node.name + ":" + colors[ 'end' ]
2508 print main.ONOSbench.checkLogs( node.ip_address )
2509
Jon Hall6aec96b2015-01-19 14:49:31 -08002510 main.step( "Packing and rotating pcap archives" )
2511 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002512
Jon Hallfeff3082015-05-19 10:23:26 -07002513 try:
2514 timerLog = open( main.logdir + "/Timers.csv", 'w')
2515 # Overwrite with empty line and close
2516 timerLog.write( "Restart\n" )
2517 timerLog.write( str( main.restartTime ) )
2518 timerLog.close()
2519 except NameError, e:
2520 main.log.exception(e)
2521
Jon Hall6aec96b2015-01-19 14:49:31 -08002522 def CASE14( self, main ):
2523 """
Jon Hall669173b2014-12-17 11:36:30 -08002524 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002525 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002526 assert numControllers, "numControllers not defined"
2527 assert main, "main not defined"
2528 assert utilities.assert_equals, "utilities.assert_equals not defined"
2529 assert CLIs, "CLIs not defined"
2530 assert nodes, "nodes not defined"
2531
Jon Hall390696c2015-05-05 17:13:41 -07002532 main.case("Start Leadership Election app")
2533 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002534 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2535 utilities.assert_equals(
2536 expect=main.TRUE,
2537 actual=appResult,
2538 onpass="Election app installed",
2539 onfail="Something went wrong with installing Leadership election" )
2540
2541 main.step( "Run for election on each node" )
2542 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002543 leaders = []
2544 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002545 cli.electionTestRun()
2546 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002547 leader = cli.electionTestLeader()
2548 if leader is None or leader == main.FALSE:
2549 main.log.report( cli.name + ": Leader for the election app " +
2550 "should be an ONOS node, instead got '" +
2551 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002552 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002553 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002554 utilities.assert_equals(
2555 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002556 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002557 onpass="Successfully ran for leadership",
2558 onfail="Failed to run for leadership" )
2559
2560 main.step( "Check that each node shows the same leader" )
2561 sameLeader = main.TRUE
2562 if len( set( leaders ) ) != 1:
2563 sameLeader = main.FALSE
2564 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2565 str( leaders ) )
2566 utilities.assert_equals(
2567 expect=main.TRUE,
2568 actual=sameLeader,
2569 onpass="Leadership is consistent for the election topic",
2570 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002571
Jon Hall6aec96b2015-01-19 14:49:31 -08002572 def CASE15( self, main ):
2573 """
Jon Hall669173b2014-12-17 11:36:30 -08002574 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002575 """
Jon Hall390696c2015-05-05 17:13:41 -07002576 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002577 assert numControllers, "numControllers not defined"
2578 assert main, "main not defined"
2579 assert utilities.assert_equals, "utilities.assert_equals not defined"
2580 assert CLIs, "CLIs not defined"
2581 assert nodes, "nodes not defined"
2582
Jon Hall8f89dda2015-01-22 16:03:33 -08002583 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002584 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002585 main.log.report( description )
2586 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002587 # NOTE: Need to re-run since being a canidate is not persistant
2588 main.step( "Run for election on each node" )
2589 leaderResult = main.TRUE
2590 leaders = []
2591 for cli in CLIs:
2592 cli.electionTestRun()
2593 for cli in CLIs:
2594 leader = cli.electionTestLeader()
2595 if leader is None or leader == main.FALSE:
2596 main.log.report( cli.name + ": Leader for the election app " +
2597 "should be an ONOS node, instead got '" +
2598 str( leader ) + "'" )
2599 leaderResult = main.FALSE
2600 leaders.append( leader )
2601 utilities.assert_equals(
2602 expect=main.TRUE,
2603 actual=leaderResult,
2604 onpass="Successfully ran for leadership",
2605 onfail="Failed to run for leadership" )
2606
2607 main.step( "Check that each node shows the same leader" )
2608 sameLeader = main.TRUE
2609 if len( set( leaders ) ) != 1:
2610 sameLeader = main.FALSE
2611 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2612 str( leaders ) )
2613 utilities.assert_equals(
2614 expect=main.TRUE,
2615 actual=sameLeader,
2616 onpass="Leadership is consistent for the election topic",
2617 onfail="Nodes have different leaders" )
2618
Jon Hall6aec96b2015-01-19 14:49:31 -08002619 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002620 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002621 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002622 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002623 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002624 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002625 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002626 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002627 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002628 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002629 for i in range( len( CLIs ) ):
2630 if leader == nodes[ i ].ip_address:
2631 oldLeader = CLIs[ i ]
2632 break
Jon Halla9d26da2015-03-30 16:45:32 -07002633 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002634 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002635 if oldLeader:
2636 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002637 utilities.assert_equals(
2638 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002639 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002640 onpass="Node was withdrawn from election",
2641 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002642
Jon Hall6aec96b2015-01-19 14:49:31 -08002643 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002644 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002645 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002646 for cli in CLIs:
2647 leaderN = cli.electionTestLeader()
2648 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002649 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002650 main.log.report( cli.name + " still sees " + str( leader ) +
2651 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002652 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002653 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002654 # error in response
2655 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002656 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002657 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002658 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002659 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002660 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002661 elif leaderN is None:
2662 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002663 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002664 leaderN = cli.electionTestLeader()
2665 leaderList.pop()
2666 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002667 consistentLeader = main.FALSE
2668 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002669 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002670 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002671 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002672 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002673 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002674 main.log.report(
2675 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002676 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002677 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002678 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002679 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002680 utilities.assert_equals(
2681 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002682 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002683 onpass="Leadership election passed",
2684 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002685
Jon Hall58c76b72015-02-23 11:09:24 -08002686 main.step( "Run for election on old leader( just so everyone " +
2687 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002688 if oldLeader:
2689 runResult = oldLeader.electionTestRun()
2690 else:
2691 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002692 utilities.assert_equals(
2693 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002694 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002695 onpass="App re-ran for election",
2696 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002697
Jon Hallfeff3082015-05-19 10:23:26 -07002698 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002699 afterRun = main.ONOScli1.electionTestLeader()
2700 # verify leader didn't just change
2701 if afterRun == leaderList[ 0 ]:
2702 afterResult = main.TRUE
2703 else:
2704 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002705
Jon Hall6aec96b2015-01-19 14:49:31 -08002706 utilities.assert_equals(
2707 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002708 actual=afterResult,
2709 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002710 onfail="Something went wrong with Leadership election after " +
2711 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002712
Jon Hall390696c2015-05-05 17:13:41 -07002713 def CASE16( self, main ):
2714 """
2715 Install Distributed Primitives app
2716 """
2717 assert numControllers, "numControllers not defined"
2718 assert main, "main not defined"
2719 assert utilities.assert_equals, "utilities.assert_equals not defined"
2720 assert CLIs, "CLIs not defined"
2721 assert nodes, "nodes not defined"
2722
2723 # Variables for the distributed primitives tests
2724 global pCounterName
2725 global iCounterName
2726 global pCounterValue
2727 global iCounterValue
2728 global onosSet
2729 global onosSetName
2730 pCounterName = "TestON-Partitions"
2731 iCounterName = "TestON-inMemory"
2732 pCounterValue = 0
2733 iCounterValue = 0
2734 onosSet = set([])
2735 onosSetName = "TestON-set"
2736
2737 description = "Install Primitives app"
2738 main.case( description )
2739 main.step( "Install Primitives app" )
2740 appName = "org.onosproject.distributedprimitives"
2741 appResults = CLIs[0].activateApp( appName )
2742 utilities.assert_equals( expect=main.TRUE,
2743 actual=appResults,
2744 onpass="Primitives app activated",
2745 onfail="Primitives app not activated" )
Jon Hallfeff3082015-05-19 10:23:26 -07002746 time.sleep (5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002747
2748 def CASE17( self, main ):
2749 """
2750 Check for basic functionality with distributed primitives
2751 """
2752 # Make sure variables are defined/set
2753 assert numControllers, "numControllers not defined"
2754 assert main, "main not defined"
2755 assert utilities.assert_equals, "utilities.assert_equals not defined"
2756 assert CLIs, "CLIs not defined"
2757 assert nodes, "nodes not defined"
2758 assert pCounterName, "pCounterName not defined"
2759 assert iCounterName, "iCounterName not defined"
2760 assert onosSetName, "onosSetName not defined"
2761 # NOTE: assert fails if value is 0/None/Empty/False
2762 try:
2763 pCounterValue
2764 except NameError:
2765 main.log.error( "pCounterValue not defined, setting to 0" )
2766 pCounterValue = 0
2767 try:
2768 iCounterValue
2769 except NameError:
2770 main.log.error( "iCounterValue not defined, setting to 0" )
2771 iCounterValue = 0
2772 try:
2773 onosSet
2774 except NameError:
2775 main.log.error( "onosSet not defined, setting to empty Set" )
2776 onosSet = set([])
2777 # Variables for the distributed primitives tests. These are local only
2778 addValue = "a"
2779 addAllValue = "a b c d e f"
2780 retainValue = "c d e f"
2781
2782 description = "Check for basic functionality with distributed " +\
2783 "primitives"
2784 main.case( description )
2785 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2786 # DISTRIBUTED ATOMIC COUNTERS
2787 main.step( "Increment and get a default counter on each node" )
2788 pCounters = []
2789 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002790 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002791 for i in range( numControllers ):
2792 t = main.Thread( target=CLIs[i].counterTestIncrement,
2793 name="counterIncrement-" + str( i ),
2794 args=[ pCounterName ] )
2795 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002796 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002797 threads.append( t )
2798 t.start()
2799
2800 for t in threads:
2801 t.join()
2802 pCounters.append( t.result )
2803 # Check that counter incremented numController times
2804 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002805 for i in addedPValues:
2806 tmpResult = i in pCounters
2807 pCounterResults = pCounterResults and tmpResult
2808 if not tmpResult:
2809 main.log.error( str( i ) + " is not in partitioned "
2810 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002811 utilities.assert_equals( expect=True,
2812 actual=pCounterResults,
2813 onpass="Default counter incremented",
2814 onfail="Error incrementing default" +
2815 " counter" )
2816
2817 main.step( "Increment and get an in memory counter on each node" )
2818 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002819 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002820 threads = []
2821 for i in range( numControllers ):
2822 t = main.Thread( target=CLIs[i].counterTestIncrement,
2823 name="icounterIncrement-" + str( i ),
2824 args=[ iCounterName ],
2825 kwargs={ "inMemory": True } )
2826 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002827 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002828 threads.append( t )
2829 t.start()
2830
2831 for t in threads:
2832 t.join()
2833 iCounters.append( t.result )
2834 # Check that counter incremented numController times
2835 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002836 for i in addedIValues:
2837 tmpResult = i in iCounters
2838 iCounterResults = iCounterResults and tmpResult
2839 if not tmpResult:
2840 main.log.error( str( i ) + " is not in the in-memory "
2841 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002842 utilities.assert_equals( expect=True,
2843 actual=iCounterResults,
2844 onpass="In memory counter incremented",
2845 onfail="Error incrementing in memory" +
2846 " counter" )
2847
2848 main.step( "Check counters are consistant across nodes" )
2849 onosCounters = []
2850 threads = []
2851 for i in range( numControllers ):
2852 t = main.Thread( target=CLIs[i].counters,
2853 name="counters-" + str( i ) )
2854 threads.append( t )
2855 t.start()
2856 for t in threads:
2857 t.join()
2858 onosCounters.append( t.result )
2859 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2860 if all( tmp ):
2861 main.log.info( "Counters are consistent across all nodes" )
2862 consistentCounterResults = main.TRUE
2863 else:
2864 main.log.error( "Counters are not consistent across all nodes" )
2865 consistentCounterResults = main.FALSE
2866 utilities.assert_equals( expect=main.TRUE,
2867 actual=consistentCounterResults,
2868 onpass="ONOS counters are consistent " +
2869 "across nodes",
2870 onfail="ONOS Counters are inconsistent " +
2871 "across nodes" )
2872
2873 main.step( "Counters we added have the correct values" )
2874 correctResults = main.TRUE
2875 for i in range( numControllers ):
2876 current = onosCounters[i]
2877 try:
2878 pValue = current.get( pCounterName )
2879 iValue = current.get( iCounterName )
2880 if pValue == pCounterValue:
2881 main.log.info( "Partitioned counter value is correct" )
2882 else:
2883 main.log.error( "Partitioned counter value is incorrect," +
2884 " expected value: " + str( pCounterValue )
2885 + " current value: " + str( pValue ) )
2886 correctResults = main.FALSE
2887 if iValue == iCounterValue:
2888 main.log.info( "In memory counter value is correct" )
2889 else:
2890 main.log.error( "In memory counter value is incorrect, " +
2891 "expected value: " + str( iCounterValue ) +
2892 " current value: " + str( iValue ) )
2893 correctResults = main.FALSE
2894 except AttributeError, e:
2895 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2896 "is not as expected" )
2897 correctResults = main.FALSE
2898 utilities.assert_equals( expect=main.TRUE,
2899 actual=correctResults,
2900 onpass="Added counters are correct",
2901 onfail="Added counters are incorrect" )
2902 # DISTRIBUTED SETS
2903 main.step( "Distributed Set get" )
2904 size = len( onosSet )
2905 getResponses = []
2906 threads = []
2907 for i in range( numControllers ):
2908 t = main.Thread( target=CLIs[i].setTestGet,
2909 name="setTestGet-" + str( i ),
2910 args=[ onosSetName ] )
2911 threads.append( t )
2912 t.start()
2913 for t in threads:
2914 t.join()
2915 getResponses.append( t.result )
2916
2917 getResults = main.TRUE
2918 for i in range( numControllers ):
2919 if isinstance( getResponses[ i ], list):
2920 current = set( getResponses[ i ] )
2921 if len( current ) == len( getResponses[ i ] ):
2922 # no repeats
2923 if onosSet != current:
2924 main.log.error( "ONOS" + str( i + 1 ) +
2925 " has incorrect view" +
2926 " of set " + onosSetName + ":\n" +
2927 str( getResponses[ i ] ) )
2928 main.log.debug( "Expected: " + str( onosSet ) )
2929 main.log.debug( "Actual: " + str( current ) )
2930 getResults = main.FALSE
2931 else:
2932 # error, set is not a set
2933 main.log.error( "ONOS" + str( i + 1 ) +
2934 " has repeat elements in" +
2935 " set " + onosSetName + ":\n" +
2936 str( getResponses[ i ] ) )
2937 getResults = main.FALSE
2938 elif getResponses[ i ] == main.ERROR:
2939 getResults = main.FALSE
2940 utilities.assert_equals( expect=main.TRUE,
2941 actual=getResults,
2942 onpass="Set elements are correct",
2943 onfail="Set elements are incorrect" )
2944
2945 main.step( "Distributed Set size" )
2946 sizeResponses = []
2947 threads = []
2948 for i in range( numControllers ):
2949 t = main.Thread( target=CLIs[i].setTestSize,
2950 name="setTestSize-" + str( i ),
2951 args=[ onosSetName ] )
2952 threads.append( t )
2953 t.start()
2954 for t in threads:
2955 t.join()
2956 sizeResponses.append( t.result )
2957
2958 sizeResults = main.TRUE
2959 for i in range( numControllers ):
2960 if size != sizeResponses[ i ]:
2961 sizeResults = main.FALSE
2962 main.log.error( "ONOS" + str( i + 1 ) +
2963 " expected a size of " + str( size ) +
2964 " for set " + onosSetName +
2965 " but got " + str( sizeResponses[ i ] ) )
2966 utilities.assert_equals( expect=main.TRUE,
2967 actual=sizeResults,
2968 onpass="Set sizes are correct",
2969 onfail="Set sizes are incorrect" )
2970
2971 main.step( "Distributed Set add()" )
2972 onosSet.add( addValue )
2973 addResponses = []
2974 threads = []
2975 for i in range( numControllers ):
2976 t = main.Thread( target=CLIs[i].setTestAdd,
2977 name="setTestAdd-" + str( i ),
2978 args=[ onosSetName, addValue ] )
2979 threads.append( t )
2980 t.start()
2981 for t in threads:
2982 t.join()
2983 addResponses.append( t.result )
2984
2985 # main.TRUE = successfully changed the set
2986 # main.FALSE = action resulted in no change in set
2987 # main.ERROR - Some error in executing the function
2988 addResults = main.TRUE
2989 for i in range( numControllers ):
2990 if addResponses[ i ] == main.TRUE:
2991 # All is well
2992 pass
2993 elif addResponses[ i ] == main.FALSE:
2994 # Already in set, probably fine
2995 pass
2996 elif addResponses[ i ] == main.ERROR:
2997 # Error in execution
2998 addResults = main.FALSE
2999 else:
3000 # unexpected result
3001 addResults = main.FALSE
3002 if addResults != main.TRUE:
3003 main.log.error( "Error executing set add" )
3004
3005 # Check if set is still correct
3006 size = len( onosSet )
3007 getResponses = []
3008 threads = []
3009 for i in range( numControllers ):
3010 t = main.Thread( target=CLIs[i].setTestGet,
3011 name="setTestGet-" + str( i ),
3012 args=[ onosSetName ] )
3013 threads.append( t )
3014 t.start()
3015 for t in threads:
3016 t.join()
3017 getResponses.append( t.result )
3018 getResults = main.TRUE
3019 for i in range( numControllers ):
3020 if isinstance( getResponses[ i ], list):
3021 current = set( getResponses[ i ] )
3022 if len( current ) == len( getResponses[ i ] ):
3023 # no repeats
3024 if onosSet != current:
3025 main.log.error( "ONOS" + str( i + 1 ) +
3026 " has incorrect view" +
3027 " of set " + onosSetName + ":\n" +
3028 str( getResponses[ i ] ) )
3029 main.log.debug( "Expected: " + str( onosSet ) )
3030 main.log.debug( "Actual: " + str( current ) )
3031 getResults = main.FALSE
3032 else:
3033 # error, set is not a set
3034 main.log.error( "ONOS" + str( i + 1 ) +
3035 " has repeat elements in" +
3036 " set " + onosSetName + ":\n" +
3037 str( getResponses[ i ] ) )
3038 getResults = main.FALSE
3039 elif getResponses[ i ] == main.ERROR:
3040 getResults = main.FALSE
3041 sizeResponses = []
3042 threads = []
3043 for i in range( numControllers ):
3044 t = main.Thread( target=CLIs[i].setTestSize,
3045 name="setTestSize-" + str( i ),
3046 args=[ onosSetName ] )
3047 threads.append( t )
3048 t.start()
3049 for t in threads:
3050 t.join()
3051 sizeResponses.append( t.result )
3052 sizeResults = main.TRUE
3053 for i in range( numControllers ):
3054 if size != sizeResponses[ i ]:
3055 sizeResults = main.FALSE
3056 main.log.error( "ONOS" + str( i + 1 ) +
3057 " expected a size of " + str( size ) +
3058 " for set " + onosSetName +
3059 " but got " + str( sizeResponses[ i ] ) )
3060 addResults = addResults and getResults and sizeResults
3061 utilities.assert_equals( expect=main.TRUE,
3062 actual=addResults,
3063 onpass="Set add correct",
3064 onfail="Set add was incorrect" )
3065
3066 main.step( "Distributed Set addAll()" )
3067 onosSet.update( addAllValue.split() )
3068 addResponses = []
3069 threads = []
3070 for i in range( numControllers ):
3071 t = main.Thread( target=CLIs[i].setTestAdd,
3072 name="setTestAddAll-" + str( i ),
3073 args=[ onosSetName, addAllValue ] )
3074 threads.append( t )
3075 t.start()
3076 for t in threads:
3077 t.join()
3078 addResponses.append( t.result )
3079
3080 # main.TRUE = successfully changed the set
3081 # main.FALSE = action resulted in no change in set
3082 # main.ERROR - Some error in executing the function
3083 addAllResults = main.TRUE
3084 for i in range( numControllers ):
3085 if addResponses[ i ] == main.TRUE:
3086 # All is well
3087 pass
3088 elif addResponses[ i ] == main.FALSE:
3089 # Already in set, probably fine
3090 pass
3091 elif addResponses[ i ] == main.ERROR:
3092 # Error in execution
3093 addAllResults = main.FALSE
3094 else:
3095 # unexpected result
3096 addAllResults = main.FALSE
3097 if addAllResults != main.TRUE:
3098 main.log.error( "Error executing set addAll" )
3099
3100 # Check if set is still correct
3101 size = len( onosSet )
3102 getResponses = []
3103 threads = []
3104 for i in range( numControllers ):
3105 t = main.Thread( target=CLIs[i].setTestGet,
3106 name="setTestGet-" + str( i ),
3107 args=[ onosSetName ] )
3108 threads.append( t )
3109 t.start()
3110 for t in threads:
3111 t.join()
3112 getResponses.append( t.result )
3113 getResults = main.TRUE
3114 for i in range( numControllers ):
3115 if isinstance( getResponses[ i ], list):
3116 current = set( getResponses[ i ] )
3117 if len( current ) == len( getResponses[ i ] ):
3118 # no repeats
3119 if onosSet != current:
3120 main.log.error( "ONOS" + str( i + 1 ) +
3121 " has incorrect view" +
3122 " of set " + onosSetName + ":\n" +
3123 str( getResponses[ i ] ) )
3124 main.log.debug( "Expected: " + str( onosSet ) )
3125 main.log.debug( "Actual: " + str( current ) )
3126 getResults = main.FALSE
3127 else:
3128 # error, set is not a set
3129 main.log.error( "ONOS" + str( i + 1 ) +
3130 " has repeat elements in" +
3131 " set " + onosSetName + ":\n" +
3132 str( getResponses[ i ] ) )
3133 getResults = main.FALSE
3134 elif getResponses[ i ] == main.ERROR:
3135 getResults = main.FALSE
3136 sizeResponses = []
3137 threads = []
3138 for i in range( numControllers ):
3139 t = main.Thread( target=CLIs[i].setTestSize,
3140 name="setTestSize-" + str( i ),
3141 args=[ onosSetName ] )
3142 threads.append( t )
3143 t.start()
3144 for t in threads:
3145 t.join()
3146 sizeResponses.append( t.result )
3147 sizeResults = main.TRUE
3148 for i in range( numControllers ):
3149 if size != sizeResponses[ i ]:
3150 sizeResults = main.FALSE
3151 main.log.error( "ONOS" + str( i + 1 ) +
3152 " expected a size of " + str( size ) +
3153 " for set " + onosSetName +
3154 " but got " + str( sizeResponses[ i ] ) )
3155 addAllResults = addAllResults and getResults and sizeResults
3156 utilities.assert_equals( expect=main.TRUE,
3157 actual=addAllResults,
3158 onpass="Set addAll correct",
3159 onfail="Set addAll was incorrect" )
3160
3161 main.step( "Distributed Set contains()" )
3162 containsResponses = []
3163 threads = []
3164 for i in range( numControllers ):
3165 t = main.Thread( target=CLIs[i].setTestGet,
3166 name="setContains-" + str( i ),
3167 args=[ onosSetName ],
3168 kwargs={ "values": addValue } )
3169 threads.append( t )
3170 t.start()
3171 for t in threads:
3172 t.join()
3173 # NOTE: This is the tuple
3174 containsResponses.append( t.result )
3175
3176 containsResults = main.TRUE
3177 for i in range( numControllers ):
3178 if containsResponses[ i ] == main.ERROR:
3179 containsResults = main.FALSE
3180 else:
3181 containsResults = containsResults and\
3182 containsResponses[ i ][ 1 ]
3183 utilities.assert_equals( expect=main.TRUE,
3184 actual=containsResults,
3185 onpass="Set contains is functional",
3186 onfail="Set contains failed" )
3187
3188 main.step( "Distributed Set containsAll()" )
3189 containsAllResponses = []
3190 threads = []
3191 for i in range( numControllers ):
3192 t = main.Thread( target=CLIs[i].setTestGet,
3193 name="setContainsAll-" + str( i ),
3194 args=[ onosSetName ],
3195 kwargs={ "values": addAllValue } )
3196 threads.append( t )
3197 t.start()
3198 for t in threads:
3199 t.join()
3200 # NOTE: This is the tuple
3201 containsAllResponses.append( t.result )
3202
3203 containsAllResults = main.TRUE
3204 for i in range( numControllers ):
3205 if containsResponses[ i ] == main.ERROR:
3206 containsResults = main.FALSE
3207 else:
3208 containsResults = containsResults and\
3209 containsResponses[ i ][ 1 ]
3210 utilities.assert_equals( expect=main.TRUE,
3211 actual=containsAllResults,
3212 onpass="Set containsAll is functional",
3213 onfail="Set containsAll failed" )
3214
3215 main.step( "Distributed Set remove()" )
3216 onosSet.remove( addValue )
3217 removeResponses = []
3218 threads = []
3219 for i in range( numControllers ):
3220 t = main.Thread( target=CLIs[i].setTestRemove,
3221 name="setTestRemove-" + str( i ),
3222 args=[ onosSetName, addValue ] )
3223 threads.append( t )
3224 t.start()
3225 for t in threads:
3226 t.join()
3227 removeResponses.append( t.result )
3228
3229 # main.TRUE = successfully changed the set
3230 # main.FALSE = action resulted in no change in set
3231 # main.ERROR - Some error in executing the function
3232 removeResults = main.TRUE
3233 for i in range( numControllers ):
3234 if removeResponses[ i ] == main.TRUE:
3235 # All is well
3236 pass
3237 elif removeResponses[ i ] == main.FALSE:
3238 # not in set, probably fine
3239 pass
3240 elif removeResponses[ i ] == main.ERROR:
3241 # Error in execution
3242 removeResults = main.FALSE
3243 else:
3244 # unexpected result
3245 removeResults = main.FALSE
3246 if removeResults != main.TRUE:
3247 main.log.error( "Error executing set remove" )
3248
3249 # Check if set is still correct
3250 size = len( onosSet )
3251 getResponses = []
3252 threads = []
3253 for i in range( numControllers ):
3254 t = main.Thread( target=CLIs[i].setTestGet,
3255 name="setTestGet-" + str( i ),
3256 args=[ onosSetName ] )
3257 threads.append( t )
3258 t.start()
3259 for t in threads:
3260 t.join()
3261 getResponses.append( t.result )
3262 getResults = main.TRUE
3263 for i in range( numControllers ):
3264 if isinstance( getResponses[ i ], list):
3265 current = set( getResponses[ i ] )
3266 if len( current ) == len( getResponses[ i ] ):
3267 # no repeats
3268 if onosSet != current:
3269 main.log.error( "ONOS" + str( i + 1 ) +
3270 " has incorrect view" +
3271 " of set " + onosSetName + ":\n" +
3272 str( getResponses[ i ] ) )
3273 main.log.debug( "Expected: " + str( onosSet ) )
3274 main.log.debug( "Actual: " + str( current ) )
3275 getResults = main.FALSE
3276 else:
3277 # error, set is not a set
3278 main.log.error( "ONOS" + str( i + 1 ) +
3279 " has repeat elements in" +
3280 " set " + onosSetName + ":\n" +
3281 str( getResponses[ i ] ) )
3282 getResults = main.FALSE
3283 elif getResponses[ i ] == main.ERROR:
3284 getResults = main.FALSE
3285 sizeResponses = []
3286 threads = []
3287 for i in range( numControllers ):
3288 t = main.Thread( target=CLIs[i].setTestSize,
3289 name="setTestSize-" + str( i ),
3290 args=[ onosSetName ] )
3291 threads.append( t )
3292 t.start()
3293 for t in threads:
3294 t.join()
3295 sizeResponses.append( t.result )
3296 sizeResults = main.TRUE
3297 for i in range( numControllers ):
3298 if size != sizeResponses[ i ]:
3299 sizeResults = main.FALSE
3300 main.log.error( "ONOS" + str( i + 1 ) +
3301 " expected a size of " + str( size ) +
3302 " for set " + onosSetName +
3303 " but got " + str( sizeResponses[ i ] ) )
3304 removeResults = removeResults and getResults and sizeResults
3305 utilities.assert_equals( expect=main.TRUE,
3306 actual=removeResults,
3307 onpass="Set remove correct",
3308 onfail="Set remove was incorrect" )
3309
3310 main.step( "Distributed Set removeAll()" )
3311 onosSet.difference_update( addAllValue.split() )
3312 removeAllResponses = []
3313 threads = []
3314 try:
3315 for i in range( numControllers ):
3316 t = main.Thread( target=CLIs[i].setTestRemove,
3317 name="setTestRemoveAll-" + str( i ),
3318 args=[ onosSetName, addAllValue ] )
3319 threads.append( t )
3320 t.start()
3321 for t in threads:
3322 t.join()
3323 removeAllResponses.append( t.result )
3324 except Exception, e:
3325 main.log.exception(e)
3326
3327 # main.TRUE = successfully changed the set
3328 # main.FALSE = action resulted in no change in set
3329 # main.ERROR - Some error in executing the function
3330 removeAllResults = main.TRUE
3331 for i in range( numControllers ):
3332 if removeAllResponses[ i ] == main.TRUE:
3333 # All is well
3334 pass
3335 elif removeAllResponses[ i ] == main.FALSE:
3336 # not in set, probably fine
3337 pass
3338 elif removeAllResponses[ i ] == main.ERROR:
3339 # Error in execution
3340 removeAllResults = main.FALSE
3341 else:
3342 # unexpected result
3343 removeAllResults = main.FALSE
3344 if removeAllResults != main.TRUE:
3345 main.log.error( "Error executing set removeAll" )
3346
3347 # Check if set is still correct
3348 size = len( onosSet )
3349 getResponses = []
3350 threads = []
3351 for i in range( numControllers ):
3352 t = main.Thread( target=CLIs[i].setTestGet,
3353 name="setTestGet-" + str( i ),
3354 args=[ onosSetName ] )
3355 threads.append( t )
3356 t.start()
3357 for t in threads:
3358 t.join()
3359 getResponses.append( t.result )
3360 getResults = main.TRUE
3361 for i in range( numControllers ):
3362 if isinstance( getResponses[ i ], list):
3363 current = set( getResponses[ i ] )
3364 if len( current ) == len( getResponses[ i ] ):
3365 # no repeats
3366 if onosSet != current:
3367 main.log.error( "ONOS" + str( i + 1 ) +
3368 " has incorrect view" +
3369 " of set " + onosSetName + ":\n" +
3370 str( getResponses[ i ] ) )
3371 main.log.debug( "Expected: " + str( onosSet ) )
3372 main.log.debug( "Actual: " + str( current ) )
3373 getResults = main.FALSE
3374 else:
3375 # error, set is not a set
3376 main.log.error( "ONOS" + str( i + 1 ) +
3377 " has repeat elements in" +
3378 " set " + onosSetName + ":\n" +
3379 str( getResponses[ i ] ) )
3380 getResults = main.FALSE
3381 elif getResponses[ i ] == main.ERROR:
3382 getResults = main.FALSE
3383 sizeResponses = []
3384 threads = []
3385 for i in range( numControllers ):
3386 t = main.Thread( target=CLIs[i].setTestSize,
3387 name="setTestSize-" + str( i ),
3388 args=[ onosSetName ] )
3389 threads.append( t )
3390 t.start()
3391 for t in threads:
3392 t.join()
3393 sizeResponses.append( t.result )
3394 sizeResults = main.TRUE
3395 for i in range( numControllers ):
3396 if size != sizeResponses[ i ]:
3397 sizeResults = main.FALSE
3398 main.log.error( "ONOS" + str( i + 1 ) +
3399 " expected a size of " + str( size ) +
3400 " for set " + onosSetName +
3401 " but got " + str( sizeResponses[ i ] ) )
3402 removeAllResults = removeAllResults and getResults and sizeResults
3403 utilities.assert_equals( expect=main.TRUE,
3404 actual=removeAllResults,
3405 onpass="Set removeAll correct",
3406 onfail="Set removeAll was incorrect" )
3407
3408 main.step( "Distributed Set addAll()" )
3409 onosSet.update( addAllValue.split() )
3410 addResponses = []
3411 threads = []
3412 for i in range( numControllers ):
3413 t = main.Thread( target=CLIs[i].setTestAdd,
3414 name="setTestAddAll-" + str( i ),
3415 args=[ onosSetName, addAllValue ] )
3416 threads.append( t )
3417 t.start()
3418 for t in threads:
3419 t.join()
3420 addResponses.append( t.result )
3421
3422 # main.TRUE = successfully changed the set
3423 # main.FALSE = action resulted in no change in set
3424 # main.ERROR - Some error in executing the function
3425 addAllResults = main.TRUE
3426 for i in range( numControllers ):
3427 if addResponses[ i ] == main.TRUE:
3428 # All is well
3429 pass
3430 elif addResponses[ i ] == main.FALSE:
3431 # Already in set, probably fine
3432 pass
3433 elif addResponses[ i ] == main.ERROR:
3434 # Error in execution
3435 addAllResults = main.FALSE
3436 else:
3437 # unexpected result
3438 addAllResults = main.FALSE
3439 if addAllResults != main.TRUE:
3440 main.log.error( "Error executing set addAll" )
3441
3442 # Check if set is still correct
3443 size = len( onosSet )
3444 getResponses = []
3445 threads = []
3446 for i in range( numControllers ):
3447 t = main.Thread( target=CLIs[i].setTestGet,
3448 name="setTestGet-" + str( i ),
3449 args=[ onosSetName ] )
3450 threads.append( t )
3451 t.start()
3452 for t in threads:
3453 t.join()
3454 getResponses.append( t.result )
3455 getResults = main.TRUE
3456 for i in range( numControllers ):
3457 if isinstance( getResponses[ i ], list):
3458 current = set( getResponses[ i ] )
3459 if len( current ) == len( getResponses[ i ] ):
3460 # no repeats
3461 if onosSet != current:
3462 main.log.error( "ONOS" + str( i + 1 ) +
3463 " has incorrect view" +
3464 " of set " + onosSetName + ":\n" +
3465 str( getResponses[ i ] ) )
3466 main.log.debug( "Expected: " + str( onosSet ) )
3467 main.log.debug( "Actual: " + str( current ) )
3468 getResults = main.FALSE
3469 else:
3470 # error, set is not a set
3471 main.log.error( "ONOS" + str( i + 1 ) +
3472 " has repeat elements in" +
3473 " set " + onosSetName + ":\n" +
3474 str( getResponses[ i ] ) )
3475 getResults = main.FALSE
3476 elif getResponses[ i ] == main.ERROR:
3477 getResults = main.FALSE
3478 sizeResponses = []
3479 threads = []
3480 for i in range( numControllers ):
3481 t = main.Thread( target=CLIs[i].setTestSize,
3482 name="setTestSize-" + str( i ),
3483 args=[ onosSetName ] )
3484 threads.append( t )
3485 t.start()
3486 for t in threads:
3487 t.join()
3488 sizeResponses.append( t.result )
3489 sizeResults = main.TRUE
3490 for i in range( numControllers ):
3491 if size != sizeResponses[ i ]:
3492 sizeResults = main.FALSE
3493 main.log.error( "ONOS" + str( i + 1 ) +
3494 " expected a size of " + str( size ) +
3495 " for set " + onosSetName +
3496 " but got " + str( sizeResponses[ i ] ) )
3497 addAllResults = addAllResults and getResults and sizeResults
3498 utilities.assert_equals( expect=main.TRUE,
3499 actual=addAllResults,
3500 onpass="Set addAll correct",
3501 onfail="Set addAll was incorrect" )
3502
3503 main.step( "Distributed Set clear()" )
3504 onosSet.clear()
3505 clearResponses = []
3506 threads = []
3507 for i in range( numControllers ):
3508 t = main.Thread( target=CLIs[i].setTestRemove,
3509 name="setTestClear-" + str( i ),
3510 args=[ onosSetName, " "], # Values doesn't matter
3511 kwargs={ "clear": True } )
3512 threads.append( t )
3513 t.start()
3514 for t in threads:
3515 t.join()
3516 clearResponses.append( t.result )
3517
3518 # main.TRUE = successfully changed the set
3519 # main.FALSE = action resulted in no change in set
3520 # main.ERROR - Some error in executing the function
3521 clearResults = main.TRUE
3522 for i in range( numControllers ):
3523 if clearResponses[ i ] == main.TRUE:
3524 # All is well
3525 pass
3526 elif clearResponses[ i ] == main.FALSE:
3527 # Nothing set, probably fine
3528 pass
3529 elif clearResponses[ i ] == main.ERROR:
3530 # Error in execution
3531 clearResults = main.FALSE
3532 else:
3533 # unexpected result
3534 clearResults = main.FALSE
3535 if clearResults != main.TRUE:
3536 main.log.error( "Error executing set clear" )
3537
3538 # Check if set is still correct
3539 size = len( onosSet )
3540 getResponses = []
3541 threads = []
3542 for i in range( numControllers ):
3543 t = main.Thread( target=CLIs[i].setTestGet,
3544 name="setTestGet-" + str( i ),
3545 args=[ onosSetName ] )
3546 threads.append( t )
3547 t.start()
3548 for t in threads:
3549 t.join()
3550 getResponses.append( t.result )
3551 getResults = main.TRUE
3552 for i in range( numControllers ):
3553 if isinstance( getResponses[ i ], list):
3554 current = set( getResponses[ i ] )
3555 if len( current ) == len( getResponses[ i ] ):
3556 # no repeats
3557 if onosSet != current:
3558 main.log.error( "ONOS" + str( i + 1 ) +
3559 " has incorrect view" +
3560 " of set " + onosSetName + ":\n" +
3561 str( getResponses[ i ] ) )
3562 main.log.debug( "Expected: " + str( onosSet ) )
3563 main.log.debug( "Actual: " + str( current ) )
3564 getResults = main.FALSE
3565 else:
3566 # error, set is not a set
3567 main.log.error( "ONOS" + str( i + 1 ) +
3568 " has repeat elements in" +
3569 " set " + onosSetName + ":\n" +
3570 str( getResponses[ i ] ) )
3571 getResults = main.FALSE
3572 elif getResponses[ i ] == main.ERROR:
3573 getResults = main.FALSE
3574 sizeResponses = []
3575 threads = []
3576 for i in range( numControllers ):
3577 t = main.Thread( target=CLIs[i].setTestSize,
3578 name="setTestSize-" + str( i ),
3579 args=[ onosSetName ] )
3580 threads.append( t )
3581 t.start()
3582 for t in threads:
3583 t.join()
3584 sizeResponses.append( t.result )
3585 sizeResults = main.TRUE
3586 for i in range( numControllers ):
3587 if size != sizeResponses[ i ]:
3588 sizeResults = main.FALSE
3589 main.log.error( "ONOS" + str( i + 1 ) +
3590 " expected a size of " + str( size ) +
3591 " for set " + onosSetName +
3592 " but got " + str( sizeResponses[ i ] ) )
3593 clearResults = clearResults and getResults and sizeResults
3594 utilities.assert_equals( expect=main.TRUE,
3595 actual=clearResults,
3596 onpass="Set clear correct",
3597 onfail="Set clear was incorrect" )
3598
3599 main.step( "Distributed Set addAll()" )
3600 onosSet.update( addAllValue.split() )
3601 addResponses = []
3602 threads = []
3603 for i in range( numControllers ):
3604 t = main.Thread( target=CLIs[i].setTestAdd,
3605 name="setTestAddAll-" + str( i ),
3606 args=[ onosSetName, addAllValue ] )
3607 threads.append( t )
3608 t.start()
3609 for t in threads:
3610 t.join()
3611 addResponses.append( t.result )
3612
3613 # main.TRUE = successfully changed the set
3614 # main.FALSE = action resulted in no change in set
3615 # main.ERROR - Some error in executing the function
3616 addAllResults = main.TRUE
3617 for i in range( numControllers ):
3618 if addResponses[ i ] == main.TRUE:
3619 # All is well
3620 pass
3621 elif addResponses[ i ] == main.FALSE:
3622 # Already in set, probably fine
3623 pass
3624 elif addResponses[ i ] == main.ERROR:
3625 # Error in execution
3626 addAllResults = main.FALSE
3627 else:
3628 # unexpected result
3629 addAllResults = main.FALSE
3630 if addAllResults != main.TRUE:
3631 main.log.error( "Error executing set addAll" )
3632
3633 # Check if set is still correct
3634 size = len( onosSet )
3635 getResponses = []
3636 threads = []
3637 for i in range( numControllers ):
3638 t = main.Thread( target=CLIs[i].setTestGet,
3639 name="setTestGet-" + str( i ),
3640 args=[ onosSetName ] )
3641 threads.append( t )
3642 t.start()
3643 for t in threads:
3644 t.join()
3645 getResponses.append( t.result )
3646 getResults = main.TRUE
3647 for i in range( numControllers ):
3648 if isinstance( getResponses[ i ], list):
3649 current = set( getResponses[ i ] )
3650 if len( current ) == len( getResponses[ i ] ):
3651 # no repeats
3652 if onosSet != current:
3653 main.log.error( "ONOS" + str( i + 1 ) +
3654 " has incorrect view" +
3655 " of set " + onosSetName + ":\n" +
3656 str( getResponses[ i ] ) )
3657 main.log.debug( "Expected: " + str( onosSet ) )
3658 main.log.debug( "Actual: " + str( current ) )
3659 getResults = main.FALSE
3660 else:
3661 # error, set is not a set
3662 main.log.error( "ONOS" + str( i + 1 ) +
3663 " has repeat elements in" +
3664 " set " + onosSetName + ":\n" +
3665 str( getResponses[ i ] ) )
3666 getResults = main.FALSE
3667 elif getResponses[ i ] == main.ERROR:
3668 getResults = main.FALSE
3669 sizeResponses = []
3670 threads = []
3671 for i in range( numControllers ):
3672 t = main.Thread( target=CLIs[i].setTestSize,
3673 name="setTestSize-" + str( i ),
3674 args=[ onosSetName ] )
3675 threads.append( t )
3676 t.start()
3677 for t in threads:
3678 t.join()
3679 sizeResponses.append( t.result )
3680 sizeResults = main.TRUE
3681 for i in range( numControllers ):
3682 if size != sizeResponses[ i ]:
3683 sizeResults = main.FALSE
3684 main.log.error( "ONOS" + str( i + 1 ) +
3685 " expected a size of " + str( size ) +
3686 " for set " + onosSetName +
3687 " but got " + str( sizeResponses[ i ] ) )
3688 addAllResults = addAllResults and getResults and sizeResults
3689 utilities.assert_equals( expect=main.TRUE,
3690 actual=addAllResults,
3691 onpass="Set addAll correct",
3692 onfail="Set addAll was incorrect" )
3693
3694 main.step( "Distributed Set retain()" )
3695 onosSet.intersection_update( retainValue.split() )
3696 retainResponses = []
3697 threads = []
3698 for i in range( numControllers ):
3699 t = main.Thread( target=CLIs[i].setTestRemove,
3700 name="setTestRetain-" + str( i ),
3701 args=[ onosSetName, retainValue ],
3702 kwargs={ "retain": True } )
3703 threads.append( t )
3704 t.start()
3705 for t in threads:
3706 t.join()
3707 retainResponses.append( t.result )
3708
3709 # main.TRUE = successfully changed the set
3710 # main.FALSE = action resulted in no change in set
3711 # main.ERROR - Some error in executing the function
3712 retainResults = main.TRUE
3713 for i in range( numControllers ):
3714 if retainResponses[ i ] == main.TRUE:
3715 # All is well
3716 pass
3717 elif retainResponses[ i ] == main.FALSE:
3718 # Already in set, probably fine
3719 pass
3720 elif retainResponses[ i ] == main.ERROR:
3721 # Error in execution
3722 retainResults = main.FALSE
3723 else:
3724 # unexpected result
3725 retainResults = main.FALSE
3726 if retainResults != main.TRUE:
3727 main.log.error( "Error executing set retain" )
3728
3729 # Check if set is still correct
3730 size = len( onosSet )
3731 getResponses = []
3732 threads = []
3733 for i in range( numControllers ):
3734 t = main.Thread( target=CLIs[i].setTestGet,
3735 name="setTestGet-" + str( i ),
3736 args=[ onosSetName ] )
3737 threads.append( t )
3738 t.start()
3739 for t in threads:
3740 t.join()
3741 getResponses.append( t.result )
3742 getResults = main.TRUE
3743 for i in range( numControllers ):
3744 if isinstance( getResponses[ i ], list):
3745 current = set( getResponses[ i ] )
3746 if len( current ) == len( getResponses[ i ] ):
3747 # no repeats
3748 if onosSet != current:
3749 main.log.error( "ONOS" + str( i + 1 ) +
3750 " has incorrect view" +
3751 " of set " + onosSetName + ":\n" +
3752 str( getResponses[ i ] ) )
3753 main.log.debug( "Expected: " + str( onosSet ) )
3754 main.log.debug( "Actual: " + str( current ) )
3755 getResults = main.FALSE
3756 else:
3757 # error, set is not a set
3758 main.log.error( "ONOS" + str( i + 1 ) +
3759 " has repeat elements in" +
3760 " set " + onosSetName + ":\n" +
3761 str( getResponses[ i ] ) )
3762 getResults = main.FALSE
3763 elif getResponses[ i ] == main.ERROR:
3764 getResults = main.FALSE
3765 sizeResponses = []
3766 threads = []
3767 for i in range( numControllers ):
3768 t = main.Thread( target=CLIs[i].setTestSize,
3769 name="setTestSize-" + str( i ),
3770 args=[ onosSetName ] )
3771 threads.append( t )
3772 t.start()
3773 for t in threads:
3774 t.join()
3775 sizeResponses.append( t.result )
3776 sizeResults = main.TRUE
3777 for i in range( numControllers ):
3778 if size != sizeResponses[ i ]:
3779 sizeResults = main.FALSE
3780 main.log.error( "ONOS" + str( i + 1 ) +
3781 " expected a size of " +
3782 str( size ) + " for set " + onosSetName +
3783 " but got " + str( sizeResponses[ i ] ) )
3784 retainResults = retainResults and getResults and sizeResults
3785 utilities.assert_equals( expect=main.TRUE,
3786 actual=retainResults,
3787 onpass="Set retain correct",
3788 onfail="Set retain was incorrect" )
3789