blob: af96bb5aa9c7a18ca3f063dd2d10ceef54b9a90d [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070021CASE16: Install Distributed Primitives app
22CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080023"""
Jon Hall8f89dda2015-01-22 16:03:33 -080024
25
Jon Hall73cf9cc2014-11-20 22:28:38 -080026class HATestMinorityRestart:
27
Jon Hall6aec96b2015-01-19 14:49:31 -080028 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080029 self.default = ''
30
Jon Hall6aec96b2015-01-19 14:49:31 -080031 def CASE1( self, main ):
32 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080033 CASE1 is to compile ONOS and push it to the test machines
34
35 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080036 cell <name>
37 onos-verify-cell
38 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080039 onos-uninstall
40 start mininet
41 git pull
42 mvn clean install
43 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080044 onos-install -f
45 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080046 start cli sessions
47 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080048 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070049 main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
Jon Hall390696c2015-05-05 17:13:41 -070050 "initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080051 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070052 main.caseExplaination = "Setup the test environment including " +\
53 "installing ONOS, starting Mininet and ONOS" +\
54 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080055 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080056
Jon Hall5cfd23c2015-03-19 11:40:57 -070057 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080058 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080059 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080060 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080061 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080062 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080063
64 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS7Port
72 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080073 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080074
Jon Hall5cfd23c2015-03-19 11:40:57 -070075 # FIXME: just get controller port from params?
76 # TODO: do we really need all these?
77 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
78 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
79 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
80 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
81 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
82 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
83 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
84
85 global CLIs
86 CLIs = []
87 global nodes
88 nodes = []
89 for i in range( 1, numControllers + 1 ):
90 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
91 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
92
Jon Hall6aec96b2015-01-19 14:49:31 -080093 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080094 cellResult = main.ONOSbench.setCell( cellName )
95 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080096
Jon Hall6aec96b2015-01-19 14:49:31 -080097 # FIXME:this is short term fix
Jon Hall40d2cbd2015-06-03 16:24:29 -070098 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080099 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700100
Jon Hall40d2cbd2015-06-03 16:24:29 -0700101 main.log.info( "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
Jon Hall40d2cbd2015-06-03 16:24:29 -0700106 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700107 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 Hall8f89dda2015-01-22 16:03:33 -0800129 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700130
131 main.step( "Using mvn clean install" )
132 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700133 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700134 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700135 else:
136 main.log.warn( "Did not pull new code so skipping mvn " +
137 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700138 utilities.assert_equals( expect=main.TRUE,
139 actual=cleanInstallResult,
140 onpass="MCI successful",
141 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700142 # GRAPHS
143 # NOTE: important params here:
144 # job = name of Jenkins job
145 # Plot Name = Plot-HA, only can be used if multiple plots
146 # index = The number of the graph under plot name
147 job = "HAMinorityRestart"
Jon Hall40d2cbd2015-06-03 16:24:29 -0700148 plotName = "Plot-HA"
Jon Hall390696c2015-05-05 17:13:41 -0700149 graphs = '<ac:structured-macro ac:name="html">\n'
150 graphs += '<ac:plain-text-body><![CDATA[\n'
151 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Hall40d2cbd2015-06-03 16:24:29 -0700152 '/plot/' + plotName + '/getPlot?index=0' +\
153 '&width=500&height=300"' +\
Jon Hall390696c2015-05-05 17:13:41 -0700154 'noborder="0" width="500" height="300" scrolling="yes" ' +\
155 'seamless="seamless"></iframe>\n'
156 graphs += ']]></ac:plain-text-body>\n'
157 graphs += '</ac:structured-macro>\n'
158 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800159
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800161 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700162 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
163 onpass="ONOS package successful",
164 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800165
Jon Hall6aec96b2015-01-19 14:49:31 -0800166 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700167 onosInstallResult = main.TRUE
168 for node in nodes:
169 tmpResult = main.ONOSbench.onosInstall( options="-f",
170 node=node.ip_address )
171 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700172 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
173 onpass="ONOS install successful",
174 onfail="ONOS install failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800175
Jon Hall6aec96b2015-01-19 14:49:31 -0800176 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700178 onosIsupResult = main.TRUE
179 for node in nodes:
180 started = main.ONOSbench.isup( node.ip_address )
181 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700182 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700183 main.ONOSbench.onosStop( node.ip_address )
184 main.ONOSbench.onosStart( node.ip_address )
185 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800186 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800187 break
Jon Hall390696c2015-05-05 17:13:41 -0700188 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
189 onpass="ONOS startup successful",
190 onfail="ONOS startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800191
Jon Hall5cfd23c2015-03-19 11:40:57 -0700192 main.log.step( "Starting ONOS CLI sessions" )
193 cliResults = main.TRUE
194 threads = []
195 for i in range( numControllers ):
196 t = main.Thread( target=CLIs[i].startOnosCli,
197 name="startOnosCli-" + str( i ),
198 args=[nodes[i].ip_address] )
199 threads.append( t )
200 t.start()
201
202 for t in threads:
203 t.join()
204 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700205 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
206 onpass="ONOS cli startup successful",
207 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800208
Jon Hall40d2cbd2015-06-03 16:24:29 -0700209 if main.params[ 'tcpdump' ].lower() == "true":
210 main.step( "Start Packet Capture MN" )
211 main.Mininet2.startTcpdump(
212 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
213 + "-MN.pcap",
214 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
215 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800216
Jon Hall390696c2015-05-05 17:13:41 -0700217 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700218 appCheck = main.TRUE
219 threads = []
220 for i in range( numControllers ):
221 t = main.Thread( target=CLIs[i].appToIDCheck,
222 name="appToIDCheck-" + str( i ),
223 args=[] )
224 threads.append( t )
225 t.start()
226
227 for t in threads:
228 t.join()
229 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700230 if appCheck != main.TRUE:
231 main.log.warn( CLIs[0].apps() )
232 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700233 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
234 onpass="App Ids seem to be correct",
235 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700236
Jon Hallfeff3082015-05-19 10:23:26 -0700237 if cliResults == main.FALSE:
238 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hall94fd0472014-12-08 11:52:42 -0800239 main.cleanup()
240 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800241
Jon Hall6aec96b2015-01-19 14:49:31 -0800242 def CASE2( self, main ):
243 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800244 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800245 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800246 import re
Jon Hall390696c2015-05-05 17:13:41 -0700247 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700248 assert numControllers, "numControllers not defined"
249 assert main, "main not defined"
250 assert utilities.assert_equals, "utilities.assert_equals not defined"
251 assert CLIs, "CLIs not defined"
252 assert nodes, "nodes not defined"
253 assert ONOS1Port, "ONOS1Port not defined"
254 assert ONOS2Port, "ONOS2Port not defined"
255 assert ONOS3Port, "ONOS3Port not defined"
256 assert ONOS4Port, "ONOS4Port not defined"
257 assert ONOS5Port, "ONOS5Port not defined"
258 assert ONOS6Port, "ONOS6Port not defined"
259 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800260
Jon Hall6aec96b2015-01-19 14:49:31 -0800261 main.case( "Assigning Controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700262 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
263 "and check that an ONOS node becomes the " +\
264 "master of the device. Then manually assign" +\
265 " mastership to specific ONOS nodes using" +\
266 " 'device-role'"
Jon Hall6aec96b2015-01-19 14:49:31 -0800267 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800268
Jon Hall5cfd23c2015-03-19 11:40:57 -0700269 # TODO: rewrite this function to take lists of ips and ports?
270 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800271 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800272 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800273 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800274 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700275 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
276 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
277 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
278 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
279 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
280 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
281 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800282
Jon Hall8f89dda2015-01-22 16:03:33 -0800283 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800284 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800285 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800286 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800287 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800288 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800289 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700290 for node in nodes:
291 if re.search( "tcp:" + node.ip_address, response ):
292 mastershipCheck = mastershipCheck and main.TRUE
293 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700294 main.log.error( "Error, node " + node.ip_address + " is " +
295 "not in the list of controllers s" +
296 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700297 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800298 utilities.assert_equals(
299 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800300 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800301 onpass="Switch mastership assigned correctly",
302 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700303
304 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800305 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800306 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700307
308 ipList = [ ]
309 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800310 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700311 for i in range( 1, 29 ): # switches 1 through 28
312 # set up correct variables:
313 if i == 1:
314 ip = nodes[ 0 ].ip_address # ONOS1
315 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
316 elif i == 2:
317 ip = nodes[ 1 ].ip_address # ONOS2
318 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
319 elif i == 3:
320 ip = nodes[ 1 ].ip_address # ONOS2
321 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
322 elif i == 4:
323 ip = nodes[ 3 ].ip_address # ONOS4
324 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
325 elif i == 5:
326 ip = nodes[ 2 ].ip_address # ONOS3
327 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
328 elif i == 6:
329 ip = nodes[ 2 ].ip_address # ONOS3
330 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
331 elif i == 7:
332 ip = nodes[ 5 ].ip_address # ONOS6
333 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
334 elif i >= 8 and i <= 17:
335 ip = nodes[ 4 ].ip_address # ONOS5
336 dpid = '3' + str( i ).zfill( 3 )
337 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
338 elif i >= 18 and i <= 27:
339 ip = nodes[ 6 ].ip_address # ONOS7
340 dpid = '6' + str( i ).zfill( 3 )
341 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
342 elif i == 28:
343 ip = nodes[ 0 ].ip_address # ONOS1
344 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
345 else:
346 main.log.error( "You didn't write an else statement for " +
347 "switch s" + str( i ) )
348 # Assign switch
349 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
350 # TODO: make this controller dynamic
351 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
352 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700353 ipList.append( ip )
354 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800355 except ( AttributeError, AssertionError ):
356 main.log.exception( "Something is wrong with ONOS device view" )
357 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800358 utilities.assert_equals(
359 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800360 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800361 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800362 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800363
Jon Hall390696c2015-05-05 17:13:41 -0700364 main.step( "Check mastership was correctly assigned" )
365 roleCheck = main.TRUE
366 # NOTE: This is due to the fact that device mastership change is not
367 # atomic and is actually a multi step process
368 time.sleep( 5 )
369 for i in range( len( ipList ) ):
370 ip = ipList[i]
371 deviceId = deviceList[i]
372 # Check assignment
373 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
374 if ip in master:
375 roleCheck = roleCheck and main.TRUE
376 else:
377 roleCheck = roleCheck and main.FALSE
378 main.log.error( "Error, controller " + ip + " is not" +
379 " master " + "of device " +
380 str( deviceId ) + ". Master is " +
381 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800382 utilities.assert_equals(
383 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800384 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 onpass="Switches were successfully reassigned to designated " +
386 "controller",
387 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800388 mastershipCheck = mastershipCheck and roleCall and roleCheck
389 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800390 onpass="Switch mastership correctly assigned",
391 onfail="Error in (re)assigning switch" +
392 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800393
Jon Hall6aec96b2015-01-19 14:49:31 -0800394 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800395 """
396 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800397 """
398 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800399 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700400 assert numControllers, "numControllers not defined"
401 assert main, "main not defined"
402 assert utilities.assert_equals, "utilities.assert_equals not defined"
403 assert CLIs, "CLIs not defined"
404 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800405 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700406 main.caseExplaination = "Discover hosts by using pingall then " +\
407 "assign predetermined host-to-host intents." +\
408 " After installation, check that the intent" +\
409 " is distributed to all nodes and the state" +\
410 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800411
Jon Hall6aec96b2015-01-19 14:49:31 -0800412 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700413 main.step( "Install reactive forwarding app" )
414 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
415 utilities.assert_equals( expect=main.TRUE, actual=installResults,
416 onpass="Install fwd successful",
417 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700418
Jon Hallfeff3082015-05-19 10:23:26 -0700419 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700420 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700421 threads = []
422 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700423 t = main.Thread( target=CLIs[i].appToIDCheck,
424 name="appToIDCheck-" + str( i ),
425 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700426 threads.append( t )
427 t.start()
428
429 for t in threads:
430 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700431 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700432 if appCheck != main.TRUE:
433 main.log.warn( CLIs[0].apps() )
434 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700435 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
436 onpass="App Ids seem to be correct",
437 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800438
Jon Hallfeff3082015-05-19 10:23:26 -0700439 main.step( "Discovering Hosts( Via pingall for now )" )
440 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800441 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800442 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700443 for i in range(2): # Retry if pingall fails first time
444 time1 = time.time()
445 pingResult = main.Mininet1.pingall()
446 utilities.assert_equals(
447 expect=main.TRUE,
448 actual=pingResult,
449 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700450 onfail="Reactive Pingall failed, " +
451 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700452 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700453 main.log.info( "Time for pingall: %2f seconds" %
454 ( time2 - time1 ) )
455 # timeout for fwd flows
456 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800457 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700458 main.step( "Uninstall reactive forwarding app" )
459 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
460 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
461 onpass="Uninstall fwd successful",
462 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700463
464 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700465 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700466 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700467 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700468 t = main.Thread( target=CLIs[i].appToIDCheck,
469 name="appToIDCheck-" + str( i ),
470 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700471 threads.append( t )
472 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800473
Jon Hall5cfd23c2015-03-19 11:40:57 -0700474 for t in threads:
475 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700476 appCheck2 = appCheck2 and t.result
477 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700478 main.log.warn( CLIs[0].apps() )
479 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700480 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700481 onpass="App Ids seem to be correct",
482 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700483
Jon Hallfeff3082015-05-19 10:23:26 -0700484 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800485 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800486 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800487 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800488 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800489 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800490 for i in range( 8, 18 ):
491 main.log.info( "Adding host intent between h" + str( i ) +
492 " and h" + str( i + 10 ) )
493 host1 = "00:00:00:00:00:" + \
494 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
495 host2 = "00:00:00:00:00:" + \
496 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800497 # NOTE: getHost can return None
498 host1Dict = main.ONOScli1.getHost( host1 )
499 host2Dict = main.ONOScli1.getHost( host2 )
500 host1Id = None
501 host2Id = None
502 if host1Dict and host2Dict:
503 host1Id = host1Dict.get( 'id', None )
504 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800505 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700506 nodeNum = ( i % 7 )
507 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800508 if tmpId:
509 main.log.info( "Added intent with id: " + tmpId )
510 intentIds.append( tmpId )
511 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700512 main.log.error( "addHostIntent returned: " +
513 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800514 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700515 main.log.error( "Error, getHost() failed for h" + str( i ) +
516 " and/or h" + str( i + 10 ) )
517 hosts = CLIs[ 0 ].hosts()
518 main.log.warn( "Hosts output: " )
519 try:
520 main.log.warn( json.dumps( json.loads( hosts ),
521 sort_keys=True,
522 indent=4,
523 separators=( ',', ': ' ) ) )
524 except ( ValueError, TypeError ):
525 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800526 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700527 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
528 onpass="Found a host id for each host",
529 onfail="Error looking up host ids" )
530
Jon Halla9d26da2015-03-30 16:45:32 -0700531 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800532 onosIds = main.ONOScli1.getAllIntentsId()
533 main.log.info( "Submitted intents: " + str( intentIds ) )
534 main.log.info( "Intents in ONOS: " + str( onosIds ) )
535 for intent in intentIds:
536 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700537 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800538 else:
539 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700540 # FIXME: DEBUG
541 if intentAddResult:
542 intentStop = time.time()
543 else:
544 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800545 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800546 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800547 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700548 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800549 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
550 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700551 try:
552 for intent in json.loads( intents ):
553 state = intent.get( 'state', None )
554 if "INSTALLED" not in state:
555 installedCheck = False
556 intentId = intent.get( 'id', None )
557 intentStates.append( ( intentId, state ) )
558 except ( ValueError, TypeError ):
559 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800560 # add submitted intents not in the store
561 tmplist = [ i for i, s in intentStates ]
562 missingIntents = False
563 for i in intentIds:
564 if i not in tmplist:
565 intentStates.append( ( i, " - " ) )
566 missingIntents = True
567 intentStates.sort()
568 for i, s in intentStates:
569 count += 1
570 main.log.info( "%-6s%-15s%-15s" %
571 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700572 leaders = main.ONOScli1.leaders()
573 try:
574 if leaders:
575 parsedLeaders = json.loads( leaders )
576 main.log.warn( json.dumps( parsedLeaders,
577 sort_keys=True,
578 indent=4,
579 separators=( ',', ': ' ) ) )
580 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700581 topics = []
582 for i in range( 14 ):
583 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700584 main.log.debug( topics )
585 ONOStopics = [ j['topic'] for j in parsedLeaders ]
586 for topic in topics:
587 if topic not in ONOStopics:
588 main.log.error( "Error: " + topic +
589 " not in leaders" )
590 else:
591 main.log.error( "leaders() returned None" )
592 except ( ValueError, TypeError ):
593 main.log.exception( "Error parsing leaders" )
594 main.log.error( repr( leaders ) )
595 partitions = main.ONOScli1.partitions()
596 try:
597 if partitions :
598 parsedPartitions = json.loads( partitions )
599 main.log.warn( json.dumps( parsedPartitions,
600 sort_keys=True,
601 indent=4,
602 separators=( ',', ': ' ) ) )
603 # TODO check for a leader in all paritions
604 # TODO check for consistency among nodes
605 else:
606 main.log.error( "partitions() returned None" )
607 except ( ValueError, TypeError ):
608 main.log.exception( "Error parsing partitions" )
609 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800610 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700611 try:
612 if pendingMap :
613 parsedPending = json.loads( pendingMap )
614 main.log.warn( json.dumps( parsedPending,
615 sort_keys=True,
616 indent=4,
617 separators=( ',', ': ' ) ) )
618 # TODO check something here?
619 else:
620 main.log.error( "pendingMap() returned None" )
621 except ( ValueError, TypeError ):
622 main.log.exception( "Error parsing pending map" )
623 main.log.error( repr( pendingMap ) )
624
Jon Hallfeff3082015-05-19 10:23:26 -0700625 intentAddResult = bool( intentAddResult and not missingIntents and
626 installedCheck )
627 if not intentAddResult:
628 main.log.error( "Error in pushing host intents to ONOS" )
629
Jon Hall390696c2015-05-05 17:13:41 -0700630 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700631 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700632 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700633 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700634 for cli in CLIs:
635 onosIds = []
636 ids = cli.getAllIntentsId()
637 onosIds.append( ids )
638 main.log.debug( "Intents in " + cli.name + ": " +
639 str( sorted( onosIds ) ) )
640 if sorted( ids ) != sorted( intentIds ):
641 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700642 break
643 else:
644 intents = json.loads( cli.intents() )
645 for intent in intents:
646 if intent[ 'state' ] != "INSTALLED":
647 correct = False
648 break
Jon Hall390696c2015-05-05 17:13:41 -0700649 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700650 break
651 else:
652 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700653 if not intentStop:
654 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700655 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700656 gossipTime = intentStop - intentStart
657 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700658 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700659 # FIXME: make this time configurable/calculate based off of number of
660 # nodes and gossip rounds
661 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700662 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700663 onpass="ECM anti-entropy for intents worked within " +
664 "expected time",
665 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700666 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700667 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800668
Jon Hall63604932015-02-26 17:09:50 -0800669 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800670 import time
Jon Hall63604932015-02-26 17:09:50 -0800671 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800672 main.log.info( "Sleeping 60 seconds to see if intents are found" )
673 time.sleep( 60 )
674 onosIds = main.ONOScli1.getAllIntentsId()
675 main.log.info( "Submitted intents: " + str( intentIds ) )
676 main.log.info( "Intents in ONOS: " + str( onosIds ) )
677 # Print the intent states
678 intents = main.ONOScli1.intents()
679 intentStates = []
680 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
681 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700682 try:
683 for intent in json.loads( intents ):
684 # Iter through intents of a node
685 state = intent.get( 'state', None )
686 if "INSTALLED" not in state:
687 installedCheck = False
688 intentId = intent.get( 'id', None )
689 intentStates.append( ( intentId, state ) )
690 except ( ValueError, TypeError ):
691 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800692 # add submitted intents not in the store
693 tmplist = [ i for i, s in intentStates ]
694 for i in intentIds:
695 if i not in tmplist:
696 intentStates.append( ( i, " - " ) )
697 intentStates.sort()
698 for i, s in intentStates:
699 count += 1
700 main.log.info( "%-6s%-15s%-15s" %
701 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700702 leaders = main.ONOScli1.leaders()
703 try:
704 if leaders:
705 parsedLeaders = json.loads( leaders )
706 main.log.warn( json.dumps( parsedLeaders,
707 sort_keys=True,
708 indent=4,
709 separators=( ',', ': ' ) ) )
710 # check for all intent partitions
711 # check for election
712 topics = []
713 for i in range( 14 ):
714 topics.append( "intent-partition-" + str( i ) )
715 # FIXME: this should only be after we start the app
716 topics.append( "org.onosproject.election" )
717 main.log.debug( topics )
718 ONOStopics = [ j['topic'] for j in parsedLeaders ]
719 for topic in topics:
720 if topic not in ONOStopics:
721 main.log.error( "Error: " + topic +
722 " not in leaders" )
723 else:
724 main.log.error( "leaders() returned None" )
725 except ( ValueError, TypeError ):
726 main.log.exception( "Error parsing leaders" )
727 main.log.error( repr( leaders ) )
728 partitions = main.ONOScli1.partitions()
729 try:
730 if partitions :
731 parsedPartitions = json.loads( partitions )
732 main.log.warn( json.dumps( parsedPartitions,
733 sort_keys=True,
734 indent=4,
735 separators=( ',', ': ' ) ) )
736 # TODO check for a leader in all paritions
737 # TODO check for consistency among nodes
738 else:
739 main.log.error( "partitions() returned None" )
740 except ( ValueError, TypeError ):
741 main.log.exception( "Error parsing partitions" )
742 main.log.error( repr( partitions ) )
743 pendingMap = main.ONOScli1.pendingMap()
744 try:
745 if pendingMap :
746 parsedPending = json.loads( pendingMap )
747 main.log.warn( json.dumps( parsedPending,
748 sort_keys=True,
749 indent=4,
750 separators=( ',', ': ' ) ) )
751 # TODO check something here?
752 else:
753 main.log.error( "pendingMap() returned None" )
754 except ( ValueError, TypeError ):
755 main.log.exception( "Error parsing pending map" )
756 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800757
Jon Hall6aec96b2015-01-19 14:49:31 -0800758 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800759 """
760 Ping across added host intents
761 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700763 import time
764 assert numControllers, "numControllers not defined"
765 assert main, "main not defined"
766 assert utilities.assert_equals, "utilities.assert_equals not defined"
767 assert CLIs, "CLIs not defined"
768 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700769 main.case( "Verify connectivity by sendind traffic across Intents" )
770 main.caseExplaination = "Ping across added host intents to check " +\
771 "functionality and check the state of " +\
772 "the intent"
773 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800774 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800775 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800776 ping = main.Mininet1.pingHost( src="h" + str( i ),
777 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800778 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800779 if ping == main.FALSE:
780 main.log.warn( "Ping failed between h" + str( i ) +
781 " and h" + str( i + 10 ) )
782 elif ping == main.TRUE:
783 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800784 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800785 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700786 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800787 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800788 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700789 main.log.warn( "ONOS1 intents: " )
790 try:
791 tmpIntents = main.ONOScli1.intents()
792 main.log.warn( json.dumps( json.loads( tmpIntents ),
793 sort_keys=True,
794 indent=4,
795 separators=( ',', ': ' ) ) )
796 except ( ValueError, TypeError ):
797 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800798 utilities.assert_equals(
799 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800800 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800801 onpass="Intents have been installed correctly and pings work",
802 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800803
Jon Hallfeff3082015-05-19 10:23:26 -0700804 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700805 installedCheck = False
Jon Hallfeff3082015-05-19 10:23:26 -0700806 count = 0
Jon Hall40d2cbd2015-06-03 16:24:29 -0700807 while not installedCheck and count < 40:
808 installedCheck = True
809 # Print the intent states
810 intents = main.ONOScli1.intents()
811 intentStates = []
812 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
813 count = 0
814 # Iter through intents of a node
815 try:
816 for intent in json.loads( intents ):
817 state = intent.get( 'state', None )
818 if "INSTALLED" not in state:
819 installedCheck = False
820 intentId = intent.get( 'id', None )
821 intentStates.append( ( intentId, state ) )
822 except ( ValueError, TypeError ):
823 main.log.exception( "Error parsing intents." )
824 # Print states
825 intentStates.sort()
826 for i, s in intentStates:
827 count += 1
828 main.log.info( "%-6s%-15s%-15s" %
829 ( str( count ), str( i ), str( s ) ) )
830 if not installedCheck:
831 time.sleep( 1 )
832 count += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700833 utilities.assert_equals( expect=True, actual=installedCheck,
834 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700835 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700836 "INSTALLED state" )
837
838 main.step( "Check leadership of topics" )
839 leaders = main.ONOScli1.leaders()
840 topicCheck = main.TRUE
841 try:
842 if leaders:
843 parsedLeaders = json.loads( leaders )
844 main.log.warn( json.dumps( parsedLeaders,
845 sort_keys=True,
846 indent=4,
847 separators=( ',', ': ' ) ) )
848 # check for all intent partitions
849 # check for election
850 # TODO: Look at Devices as topics now that it uses this system
851 topics = []
852 for i in range( 14 ):
853 topics.append( "intent-partition-" + str( i ) )
854 # FIXME: this should only be after we start the app
855 # FIXME: topics.append( "org.onosproject.election" )
856 # Print leaders output
857 main.log.debug( topics )
858 ONOStopics = [ j['topic'] for j in parsedLeaders ]
859 for topic in topics:
860 if topic not in ONOStopics:
861 main.log.error( "Error: " + topic +
862 " not in leaders" )
863 topicCheck = main.FALSE
864 else:
865 main.log.error( "leaders() returned None" )
866 topicCheck = main.FALSE
867 except ( ValueError, TypeError ):
868 topicCheck = main.FALSE
869 main.log.exception( "Error parsing leaders" )
870 main.log.error( repr( leaders ) )
871 # TODO: Check for a leader of these topics
872 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
873 onpass="intent Partitions is in leaders",
874 onfail="Some topics were lost " )
875 # Print partitions
876 partitions = main.ONOScli1.partitions()
877 try:
878 if partitions :
879 parsedPartitions = json.loads( partitions )
880 main.log.warn( json.dumps( parsedPartitions,
881 sort_keys=True,
882 indent=4,
883 separators=( ',', ': ' ) ) )
884 # TODO check for a leader in all paritions
885 # TODO check for consistency among nodes
886 else:
887 main.log.error( "partitions() returned None" )
888 except ( ValueError, TypeError ):
889 main.log.exception( "Error parsing partitions" )
890 main.log.error( repr( partitions ) )
891 # Print Pending Map
892 pendingMap = main.ONOScli1.pendingMap()
893 try:
894 if pendingMap :
895 parsedPending = json.loads( pendingMap )
896 main.log.warn( json.dumps( parsedPending,
897 sort_keys=True,
898 indent=4,
899 separators=( ',', ': ' ) ) )
900 # TODO check something here?
901 else:
902 main.log.error( "pendingMap() returned None" )
903 except ( ValueError, TypeError ):
904 main.log.exception( "Error parsing pending map" )
905 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700906
Jon Hall63604932015-02-26 17:09:50 -0800907 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700908 main.log.info( "Waiting 60 seconds to see if the state of " +
909 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800910 time.sleep( 60 )
911 # Print the intent states
912 intents = main.ONOScli1.intents()
913 intentStates = []
914 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
915 count = 0
916 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700917 try:
918 for intent in json.loads( intents ):
919 state = intent.get( 'state', None )
920 if "INSTALLED" not in state:
921 installedCheck = False
922 intentId = intent.get( 'id', None )
923 intentStates.append( ( intentId, state ) )
924 except ( ValueError, TypeError ):
925 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800926 intentStates.sort()
927 for i, s in intentStates:
928 count += 1
929 main.log.info( "%-6s%-15s%-15s" %
930 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700931 leaders = main.ONOScli1.leaders()
932 try:
933 if leaders:
934 parsedLeaders = json.loads( leaders )
935 main.log.warn( json.dumps( parsedLeaders,
936 sort_keys=True,
937 indent=4,
938 separators=( ',', ': ' ) ) )
939 # check for all intent partitions
940 # check for election
941 topics = []
942 for i in range( 14 ):
943 topics.append( "intent-partition-" + str( i ) )
944 # FIXME: this should only be after we start the app
945 topics.append( "org.onosproject.election" )
946 main.log.debug( topics )
947 ONOStopics = [ j['topic'] for j in parsedLeaders ]
948 for topic in topics:
949 if topic not in ONOStopics:
950 main.log.error( "Error: " + topic +
951 " not in leaders" )
952 else:
953 main.log.error( "leaders() returned None" )
954 except ( ValueError, TypeError ):
955 main.log.exception( "Error parsing leaders" )
956 main.log.error( repr( leaders ) )
957 partitions = main.ONOScli1.partitions()
958 try:
959 if partitions :
960 parsedPartitions = json.loads( partitions )
961 main.log.warn( json.dumps( parsedPartitions,
962 sort_keys=True,
963 indent=4,
964 separators=( ',', ': ' ) ) )
965 # TODO check for a leader in all paritions
966 # TODO check for consistency among nodes
967 else:
968 main.log.error( "partitions() returned None" )
969 except ( ValueError, TypeError ):
970 main.log.exception( "Error parsing partitions" )
971 main.log.error( repr( partitions ) )
972 pendingMap = main.ONOScli1.pendingMap()
973 try:
974 if pendingMap :
975 parsedPending = json.loads( pendingMap )
976 main.log.warn( json.dumps( parsedPending,
977 sort_keys=True,
978 indent=4,
979 separators=( ',', ': ' ) ) )
980 # TODO check something here?
981 else:
982 main.log.error( "pendingMap() returned None" )
983 except ( ValueError, TypeError ):
984 main.log.exception( "Error parsing pending map" )
985 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700986 # Print flowrules
987 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -0700988 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700989 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -0700990 PingResult = main.TRUE
991 for i in range( 8, 18 ):
992 ping = main.Mininet1.pingHost( src="h" + str( i ),
993 target="h" + str( i + 10 ) )
994 PingResult = PingResult and ping
995 if ping == main.FALSE:
996 main.log.warn( "Ping failed between h" + str( i ) +
997 " and h" + str( i + 10 ) )
998 elif ping == main.TRUE:
999 main.log.info( "Ping test passed!" )
1000 # Don't set PingResult or you'd override failures
1001 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001002 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001003 "Intents have not been installed correctly, pings failed." )
1004 # TODO: pretty print
1005 main.log.warn( "ONOS1 intents: " )
1006 try:
1007 tmpIntents = main.ONOScli1.intents()
1008 main.log.warn( json.dumps( json.loads( tmpIntents ),
1009 sort_keys=True,
1010 indent=4,
1011 separators=( ',', ': ' ) ) )
1012 except ( ValueError, TypeError ):
1013 main.log.warn( repr( tmpIntents ) )
1014 utilities.assert_equals(
1015 expect=main.TRUE,
1016 actual=PingResult,
1017 onpass="Intents have been installed correctly and pings work",
1018 onfail="Intents have not been installed correctly, pings failed." )
1019
Jon Hall6aec96b2015-01-19 14:49:31 -08001020 def CASE5( self, main ):
1021 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001022 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001023 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001024 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001025 import time
1026 assert numControllers, "numControllers not defined"
1027 assert main, "main not defined"
1028 assert utilities.assert_equals, "utilities.assert_equals not defined"
1029 assert CLIs, "CLIs not defined"
1030 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001031 # assumes that sts is already in you PYTHONPATH
1032 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001033
Jon Hall6aec96b2015-01-19 14:49:31 -08001034 main.case( "Setting up and gathering data for current state" )
1035 # The general idea for this test case is to pull the state of
1036 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001037 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001038
Jon Hall5cfd23c2015-03-19 11:40:57 -07001039 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001040 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001041 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001042
Jon Hall6aec96b2015-01-19 14:49:31 -08001043 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001044 rolesNotNull = main.TRUE
1045 threads = []
1046 for i in range( numControllers ):
1047 t = main.Thread( target=CLIs[i].rolesNotNull,
1048 name="rolesNotNull-" + str( i ),
1049 args=[] )
1050 threads.append( t )
1051 t.start()
1052
1053 for t in threads:
1054 t.join()
1055 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001056 utilities.assert_equals(
1057 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001058 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001059 onpass="Each device has a master",
1060 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001061
Jon Hall5cfd23c2015-03-19 11:40:57 -07001062 main.step( "Get the Mastership of each switch from each controller" )
1063 ONOSMastership = []
1064 mastershipCheck = main.FALSE
1065 consistentMastership = True
1066 rolesResults = True
1067 threads = []
1068 for i in range( numControllers ):
1069 t = main.Thread( target=CLIs[i].roles,
1070 name="roles-" + str( i ),
1071 args=[] )
1072 threads.append( t )
1073 t.start()
1074
1075 for t in threads:
1076 t.join()
1077 ONOSMastership.append( t.result )
1078
1079 for i in range( numControllers ):
1080 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001081 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001082 " roles" )
1083 main.log.warn(
1084 "ONOS" + str( i + 1 ) + " mastership response: " +
1085 repr( ONOSMastership[i] ) )
1086 rolesResults = False
1087 utilities.assert_equals(
1088 expect=True,
1089 actual=rolesResults,
1090 onpass="No error in reading roles output",
1091 onfail="Error in reading roles from ONOS" )
1092
1093 main.step( "Check for consistency in roles from each controller" )
1094 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001095 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001096 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001097 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001098 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001099 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001100 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001101 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001102 onpass="Switch roles are consistent across all ONOS nodes",
1103 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001104
Jon Hall5cfd23c2015-03-19 11:40:57 -07001105 if rolesResults and not consistentMastership:
1106 for i in range( numControllers ):
1107 try:
1108 main.log.warn(
1109 "ONOS" + str( i + 1 ) + " roles: ",
1110 json.dumps(
1111 json.loads( ONOSMastership[ i ] ),
1112 sort_keys=True,
1113 indent=4,
1114 separators=( ',', ': ' ) ) )
1115 except ( ValueError, TypeError ):
1116 main.log.warn( repr( ONOSMastership[ i ] ) )
1117 elif rolesResults and consistentMastership:
1118 mastershipCheck = main.TRUE
1119 mastershipState = ONOSMastership[ 0 ]
1120
Jon Hall6aec96b2015-01-19 14:49:31 -08001121 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001122 global intentState
1123 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001124 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001125 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001126 consistentIntents = True
1127 intentsResults = True
1128 threads = []
1129 for i in range( numControllers ):
1130 t = main.Thread( target=CLIs[i].intents,
1131 name="intents-" + str( i ),
1132 args=[],
1133 kwargs={ 'jsonFormat': True } )
1134 threads.append( t )
1135 t.start()
1136
1137 for t in threads:
1138 t.join()
1139 ONOSIntents.append( t.result )
1140
1141 for i in range( numControllers ):
1142 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001143 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001144 " intents" )
1145 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1146 repr( ONOSIntents[ i ] ) )
1147 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001148 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001149 expect=True,
1150 actual=intentsResults,
1151 onpass="No error in reading intents output",
1152 onfail="Error in reading intents from ONOS" )
1153
1154 main.step( "Check for consistency in Intents from each controller" )
1155 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001156 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001157 "nodes" )
1158 else:
1159 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001160 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001161 utilities.assert_equals(
1162 expect=True,
1163 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001164 onpass="Intents are consistent across all ONOS nodes",
1165 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001166
Jon Hall390696c2015-05-05 17:13:41 -07001167 if intentsResults:
1168 # Try to make it easy to figure out what is happening
1169 #
1170 # Intent ONOS1 ONOS2 ...
1171 # 0x01 INSTALLED INSTALLING
1172 # ... ... ...
1173 # ... ... ...
1174 title = " Id"
1175 for n in range( numControllers ):
1176 title += " " * 10 + "ONOS" + str( n + 1 )
1177 main.log.warn( title )
1178 # get all intent keys in the cluster
1179 keys = []
1180 for nodeStr in ONOSIntents:
1181 node = json.loads( nodeStr )
1182 for intent in node:
1183 keys.append( intent.get( 'id' ) )
1184 keys = set( keys )
1185 for key in keys:
1186 row = "%-13s" % key
1187 for nodeStr in ONOSIntents:
1188 node = json.loads( nodeStr )
1189 for intent in node:
1190 if intent.get( 'id', "Error" ) == key:
1191 row += "%-15s" % intent.get( 'state' )
1192 main.log.warn( row )
1193 # End table view
1194
Jon Hall5cfd23c2015-03-19 11:40:57 -07001195 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001196 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001197 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001198 main.log.debug( "ONOS" + str( n ) + " intents: " )
1199 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1200 sort_keys=True,
1201 indent=4,
1202 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001203 for i in range( numControllers ):
1204 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001205 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1206 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1207 sort_keys=True,
1208 indent=4,
1209 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001210 else:
Jon Hall390696c2015-05-05 17:13:41 -07001211 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1212 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001213 elif intentsResults and consistentIntents:
1214 intentCheck = main.TRUE
1215 intentState = ONOSIntents[ 0 ]
1216
Jon Hall6aec96b2015-01-19 14:49:31 -08001217 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001218 global flowState
1219 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001220 ONOSFlows = []
1221 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001222 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001223 consistentFlows = True
1224 flowsResults = True
1225 threads = []
1226 for i in range( numControllers ):
1227 t = main.Thread( target=CLIs[i].flows,
1228 name="flows-" + str( i ),
1229 args=[],
1230 kwargs={ 'jsonFormat': True } )
1231 threads.append( t )
1232 t.start()
1233
Jon Halla9d26da2015-03-30 16:45:32 -07001234 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001235 time.sleep(30)
1236 for t in threads:
1237 t.join()
1238 result = t.result
1239 ONOSFlows.append( result )
1240
1241 for i in range( numControllers ):
1242 num = str( i + 1 )
1243 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001244 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001245 main.log.warn( "ONOS" + num + " flows response: " +
1246 repr( ONOSFlows[ i ] ) )
1247 flowsResults = False
1248 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001249 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001250 try:
1251 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1252 except ( ValueError, TypeError ):
1253 # FIXME: change this to log.error?
1254 main.log.exception( "Error in parsing ONOS" + num +
1255 " response as json." )
1256 main.log.error( repr( ONOSFlows[ i ] ) )
1257 ONOSFlowsJson.append( None )
1258 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001259 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001260 expect=True,
1261 actual=flowsResults,
1262 onpass="No error in reading flows output",
1263 onfail="Error in reading flows from ONOS" )
1264
1265 main.step( "Check for consistency in Flows from each controller" )
1266 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1267 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001268 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001269 else:
1270 consistentFlows = False
1271 utilities.assert_equals(
1272 expect=True,
1273 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001274 onpass="The flow count is consistent across all ONOS nodes",
1275 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001276
Jon Hall5cfd23c2015-03-19 11:40:57 -07001277 if flowsResults and not consistentFlows:
1278 for i in range( numControllers ):
1279 try:
1280 main.log.warn(
1281 "ONOS" + str( i + 1 ) + " flows: " +
1282 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1283 indent=4, separators=( ',', ': ' ) ) )
1284 except ( ValueError, TypeError ):
1285 main.log.warn(
1286 "ONOS" + str( i + 1 ) + " flows: " +
1287 repr( ONOSFlows[ i ] ) )
1288 elif flowsResults and consistentFlows:
1289 flowCheck = main.TRUE
1290 flowState = ONOSFlows[ 0 ]
1291
Jon Hall6aec96b2015-01-19 14:49:31 -08001292 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001293 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001294 flows = []
1295 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001296 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001297 if flowCheck == main.FALSE:
1298 for table in flows:
1299 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001300 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001301
Jon Hall6aec96b2015-01-19 14:49:31 -08001302 main.step( "Start continuous pings" )
1303 main.Mininet2.pingLong(
1304 src=main.params[ 'PING' ][ 'source1' ],
1305 target=main.params[ 'PING' ][ 'target1' ],
1306 pingTime=500 )
1307 main.Mininet2.pingLong(
1308 src=main.params[ 'PING' ][ 'source2' ],
1309 target=main.params[ 'PING' ][ 'target2' ],
1310 pingTime=500 )
1311 main.Mininet2.pingLong(
1312 src=main.params[ 'PING' ][ 'source3' ],
1313 target=main.params[ 'PING' ][ 'target3' ],
1314 pingTime=500 )
1315 main.Mininet2.pingLong(
1316 src=main.params[ 'PING' ][ 'source4' ],
1317 target=main.params[ 'PING' ][ 'target4' ],
1318 pingTime=500 )
1319 main.Mininet2.pingLong(
1320 src=main.params[ 'PING' ][ 'source5' ],
1321 target=main.params[ 'PING' ][ 'target5' ],
1322 pingTime=500 )
1323 main.Mininet2.pingLong(
1324 src=main.params[ 'PING' ][ 'source6' ],
1325 target=main.params[ 'PING' ][ 'target6' ],
1326 pingTime=500 )
1327 main.Mininet2.pingLong(
1328 src=main.params[ 'PING' ][ 'source7' ],
1329 target=main.params[ 'PING' ][ 'target7' ],
1330 pingTime=500 )
1331 main.Mininet2.pingLong(
1332 src=main.params[ 'PING' ][ 'source8' ],
1333 target=main.params[ 'PING' ][ 'target8' ],
1334 pingTime=500 )
1335 main.Mininet2.pingLong(
1336 src=main.params[ 'PING' ][ 'source9' ],
1337 target=main.params[ 'PING' ][ 'target9' ],
1338 pingTime=500 )
1339 main.Mininet2.pingLong(
1340 src=main.params[ 'PING' ][ 'source10' ],
1341 target=main.params[ 'PING' ][ 'target10' ],
1342 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001343
Jon Hall6aec96b2015-01-19 14:49:31 -08001344 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001345 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001346 for node in nodes:
1347 temp = ( node, node.name, node.ip_address, 6633 )
1348 ctrls.append( temp )
1349 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001350
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001352 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001353 threads = []
1354 for i in range( numControllers ):
1355 t = main.Thread( target=CLIs[i].devices,
1356 name="devices-" + str( i ),
1357 args=[ ] )
1358 threads.append( t )
1359 t.start()
1360
1361 for t in threads:
1362 t.join()
1363 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001364 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001365 threads = []
1366 for i in range( numControllers ):
1367 t = main.Thread( target=CLIs[i].hosts,
1368 name="hosts-" + str( i ),
1369 args=[ ] )
1370 threads.append( t )
1371 t.start()
1372
1373 for t in threads:
1374 t.join()
1375 try:
1376 hosts.append( json.loads( t.result ) )
1377 except ( ValueError, TypeError ):
1378 # FIXME: better handling of this, print which node
1379 # Maybe use thread name?
1380 main.log.exception( "Error parsing json output of hosts" )
1381 # FIXME: should this be an empty json object instead?
1382 hosts.append( None )
1383
Jon Hall73cf9cc2014-11-20 22:28:38 -08001384 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001385 threads = []
1386 for i in range( numControllers ):
1387 t = main.Thread( target=CLIs[i].ports,
1388 name="ports-" + str( i ),
1389 args=[ ] )
1390 threads.append( t )
1391 t.start()
1392
1393 for t in threads:
1394 t.join()
1395 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001396 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001397 threads = []
1398 for i in range( numControllers ):
1399 t = main.Thread( target=CLIs[i].links,
1400 name="links-" + str( i ),
1401 args=[ ] )
1402 threads.append( t )
1403 t.start()
1404
1405 for t in threads:
1406 t.join()
1407 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001408 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001409 threads = []
1410 for i in range( numControllers ):
1411 t = main.Thread( target=CLIs[i].clusters,
1412 name="clusters-" + str( i ),
1413 args=[ ] )
1414 threads.append( t )
1415 t.start()
1416
1417 for t in threads:
1418 t.join()
1419 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001420 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001421
Jon Hall6aec96b2015-01-19 14:49:31 -08001422 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001423 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001424 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001425 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001426 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001427 if "Error" not in hosts[ controller ]:
1428 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001429 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001430 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001431 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001432 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001433 " is inconsistent with ONOS1" )
1434 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001435 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001436
1437 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001438 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001439 controllerStr )
1440 consistentHostsResult = main.FALSE
1441 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001442 " hosts response: " +
1443 repr( hosts[ controller ] ) )
1444 utilities.assert_equals(
1445 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001446 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001447 onpass="Hosts view is consistent across all ONOS nodes",
1448 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001449
Jon Hall390696c2015-05-05 17:13:41 -07001450 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001451 ipResult = main.TRUE
1452 for controller in range( 0, len( hosts ) ):
1453 controllerStr = str( controller + 1 )
1454 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001455 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001456 main.log.error( "DEBUG:Error with host ips on controller" +
1457 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001458 ipResult = main.FALSE
1459 utilities.assert_equals(
1460 expect=main.TRUE,
1461 actual=ipResult,
1462 onpass="The ips of the hosts aren't empty",
1463 onfail="The ip of at least one host is missing" )
1464
Jon Hall6aec96b2015-01-19 14:49:31 -08001465 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001466 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001467 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001468 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001469 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001470 if "Error" not in clusters[ controller ]:
1471 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001472 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001473 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001474 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001475 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001476 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001477
1478 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001479 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001480 "from ONOS" + controllerStr )
1481 consistentClustersResult = main.FALSE
1482 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001483 " clusters response: " +
1484 repr( clusters[ controller ] ) )
1485 utilities.assert_equals(
1486 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001487 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001488 onpass="Clusters view is consistent across all ONOS nodes",
1489 onfail="ONOS nodes have different views of clusters" )
1490 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001491 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001492 try:
1493 numClusters = len( json.loads( clusters[ 0 ] ) )
1494 except ( ValueError, TypeError ):
1495 main.log.exception( "Error parsing clusters[0]: " +
1496 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001497 clusterResults = main.FALSE
1498 if numClusters == 1:
1499 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001500 utilities.assert_equals(
1501 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001502 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001503 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001504 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001505
Jon Hall6aec96b2015-01-19 14:49:31 -08001506 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001507 devicesResults = main.TRUE
1508 portsResults = main.TRUE
1509 linksResults = main.TRUE
1510 for controller in range( numControllers ):
1511 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001513 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001514 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001515 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001516 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001517 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001518 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001519 actual=currentDevicesResult,
1520 onpass="ONOS" + controllerStr +
1521 " Switches view is correct",
1522 onfail="ONOS" + controllerStr +
1523 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001524
Jon Hall6aec96b2015-01-19 14:49:31 -08001525 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001526 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001527 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001528 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001529 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001530 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001531 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001532 actual=currentPortsResult,
1533 onpass="ONOS" + controllerStr +
1534 " ports view is correct",
1535 onfail="ONOS" + controllerStr +
1536 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001537
Jon Hall6aec96b2015-01-19 14:49:31 -08001538 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001539 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001540 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001541 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001542 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001543 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001544 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001545 actual=currentLinksResult,
1546 onpass="ONOS" + controllerStr +
1547 " links view is correct",
1548 onfail="ONOS" + controllerStr +
1549 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001550
Jon Hall8f89dda2015-01-22 16:03:33 -08001551 devicesResults = devicesResults and currentDevicesResult
1552 portsResults = portsResults and currentPortsResult
1553 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001554
Jon Hall5cfd23c2015-03-19 11:40:57 -07001555 topoResult = ( devicesResults and portsResults and linksResults
1556 and consistentHostsResult and consistentClustersResult
1557 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001558 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001559 onpass="Topology Check Test successful",
1560 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001561
Jon Hall6aec96b2015-01-19 14:49:31 -08001562 def CASE6( self, main ):
1563 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001564 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001565 """
Jon Hall94fd0472014-12-08 11:52:42 -08001566 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001567 assert numControllers, "numControllers not defined"
1568 assert main, "main not defined"
1569 assert utilities.assert_equals, "utilities.assert_equals not defined"
1570 assert CLIs, "CLIs not defined"
1571 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001572 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001573 main.step( "Killing 3 ONOS nodes" )
Jon Hallfeff3082015-05-19 10:23:26 -07001574 killTime = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001575 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001576 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001577 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001578 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001579 killResults = killResults and\
1580 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001581 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001582 killResults = killResults and\
1583 main.ONOSbench.onosKill( nodes[2].ip_address )
1584 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1585 onpass="ONOS Killed successfully",
1586 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001587
Jon Hall6aec96b2015-01-19 14:49:31 -08001588 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001589 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001590 onosIsupResult = main.FALSE
1591 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001592 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1593 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1594 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001595 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001596 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001597 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001598 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1599 onpass="ONOS restarted successfully",
1600 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001601
Jon Hall390696c2015-05-05 17:13:41 -07001602 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001603 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1604 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1605 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001606 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001607 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1608 onpass="ONOS cli restarted",
1609 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001610
Jon Hall21270ac2015-02-16 17:59:55 -08001611 # Grab the time of restart so we chan check how long the gossip
1612 # protocol has had time to work
Jon Hallfeff3082015-05-19 10:23:26 -07001613 main.restartTime = time.time() - killTime
1614 main.log.debug( "Restart time: " + str( main.restartTime ) )
1615 '''
1616 # FIXME: revisit test plan for election with madan
1617 # Rerun for election on restarted nodes
1618 run1 = CLIs[0].electionTestRun()
1619 run2 = CLIs[1].electionTestRun()
1620 run3 = CLIs[2].electionTestRun()
1621 runResults = run1 and run2 and run3
1622 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1623 onpass="Reran for election",
1624 onfail="Failed to rerun for election" )
1625 '''
1626 # TODO: MAke this configurable. Also, we are breaking the above timer
1627 time.sleep( 60 )
1628 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1629 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1630 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001631
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 def CASE7( self, main ):
1633 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001634 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001635 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001636 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001637 assert numControllers, "numControllers not defined"
1638 assert main, "main not defined"
1639 assert utilities.assert_equals, "utilities.assert_equals not defined"
1640 assert CLIs, "CLIs not defined"
1641 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001642 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001643
Jon Hall5cfd23c2015-03-19 11:40:57 -07001644 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001645 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001646 rolesNotNull = main.TRUE
1647 threads = []
1648 for i in range( numControllers ):
1649 t = main.Thread( target=CLIs[i].rolesNotNull,
1650 name="rolesNotNull-" + str( i ),
1651 args=[ ] )
1652 threads.append( t )
1653 t.start()
1654
1655 for t in threads:
1656 t.join()
1657 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001658 utilities.assert_equals(
1659 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001660 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001661 onpass="Each device has a master",
1662 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001663
Jon Hall390696c2015-05-05 17:13:41 -07001664 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001665 ONOSMastership = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001666 consistentMastership = True
1667 rolesResults = True
1668 threads = []
1669 for i in range( numControllers ):
1670 t = main.Thread( target=CLIs[i].roles,
1671 name="roles-" + str( i ),
1672 args=[] )
1673 threads.append( t )
1674 t.start()
1675
1676 for t in threads:
1677 t.join()
1678 ONOSMastership.append( t.result )
1679
1680 for i in range( numControllers ):
1681 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001682 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001683 " roles" )
1684 main.log.warn(
1685 "ONOS" + str( i + 1 ) + " mastership response: " +
1686 repr( ONOSMastership[i] ) )
1687 rolesResults = False
1688 utilities.assert_equals(
1689 expect=True,
1690 actual=rolesResults,
1691 onpass="No error in reading roles output",
1692 onfail="Error in reading roles from ONOS" )
1693
1694 main.step( "Check for consistency in roles from each controller" )
1695 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001696 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001697 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001698 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001699 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001700 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001701 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001702 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001703 onpass="Switch roles are consistent across all ONOS nodes",
1704 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001705
Jon Hall5cfd23c2015-03-19 11:40:57 -07001706 if rolesResults and not consistentMastership:
1707 for i in range( numControllers ):
1708 main.log.warn(
1709 "ONOS" + str( i + 1 ) + " roles: ",
1710 json.dumps(
1711 json.loads( ONOSMastership[ i ] ),
1712 sort_keys=True,
1713 indent=4,
1714 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001715
Jon Hallfeff3082015-05-19 10:23:26 -07001716 # NOTE: we expect mastership to change on controller failure
1717 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001718 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001719 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001720 try:
1721 currentJson = json.loads( ONOSMastership[0] )
1722 oldJson = json.loads( mastershipState )
1723 except ( ValueError, TypeError ):
1724 main.log.exception( "Something is wrong with parsing " +
1725 "ONOSMastership[0] or mastershipState" )
1726 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1727 main.log.error( "mastershipState" + repr( mastershipState ) )
1728 main.cleanup()
1729 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001730 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001731 for i in range( 1, 29 ):
1732 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001733 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001734 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001735 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001736 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001737 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001738 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001739 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001740 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001741 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001742 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001743 utilities.assert_equals(
1744 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001745 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001746 onpass="Mastership of Switches was not changed",
1747 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001748 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001749
Jon Hall58c76b72015-02-23 11:09:24 -08001750 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001751 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001752 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001753 consistentIntents = True
1754 intentsResults = True
1755 threads = []
1756 for i in range( numControllers ):
1757 t = main.Thread( target=CLIs[i].intents,
1758 name="intents-" + str( i ),
1759 args=[],
1760 kwargs={ 'jsonFormat': True } )
1761 threads.append( t )
1762 t.start()
1763
1764 for t in threads:
1765 t.join()
1766 ONOSIntents.append( t.result )
1767
1768 for i in range( numControllers ):
1769 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001770 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001771 " intents" )
1772 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1773 repr( ONOSIntents[ i ] ) )
1774 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001775 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001776 expect=True,
1777 actual=intentsResults,
1778 onpass="No error in reading intents output",
1779 onfail="Error in reading intents from ONOS" )
1780
1781 main.step( "Check for consistency in Intents from each controller" )
1782 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001783 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001784 "nodes" )
1785 else:
1786 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001787
1788 # Try to make it easy to figure out what is happening
1789 #
1790 # Intent ONOS1 ONOS2 ...
1791 # 0x01 INSTALLED INSTALLING
1792 # ... ... ...
1793 # ... ... ...
1794 title = " ID"
1795 for n in range( numControllers ):
1796 title += " " * 10 + "ONOS" + str( n + 1 )
1797 main.log.warn( title )
1798 # get all intent keys in the cluster
1799 keys = []
1800 for nodeStr in ONOSIntents:
1801 node = json.loads( nodeStr )
1802 for intent in node:
1803 keys.append( intent.get( 'id' ) )
1804 keys = set( keys )
1805 for key in keys:
1806 row = "%-13s" % key
1807 for nodeStr in ONOSIntents:
1808 node = json.loads( nodeStr )
1809 for intent in node:
1810 if intent.get( 'id' ) == key:
1811 row += "%-15s" % intent.get( 'state' )
1812 main.log.warn( row )
1813 # End table view
1814
Jon Hall5cfd23c2015-03-19 11:40:57 -07001815 utilities.assert_equals(
1816 expect=True,
1817 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001818 onpass="Intents are consistent across all ONOS nodes",
1819 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001820 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001821 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001822 nodeStates = []
1823 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001824 try:
1825 for intent in json.loads( node ):
1826 nodeStates.append( intent[ 'state' ] )
1827 except ( ValueError, TypeError ):
1828 main.log.exception( "Error in parsing intents" )
1829 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001830 intentStates.append( nodeStates )
1831 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1832 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001833
Jon Hall5cfd23c2015-03-19 11:40:57 -07001834 if intentsResults and not consistentIntents:
1835 for i in range( numControllers ):
1836 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1837 main.log.warn( json.dumps(
1838 json.loads( ONOSIntents[ i ] ),
1839 sort_keys=True,
1840 indent=4,
1841 separators=( ',', ': ' ) ) )
1842 elif intentsResults and consistentIntents:
1843 intentCheck = main.TRUE
1844
Jon Hall58c76b72015-02-23 11:09:24 -08001845 # NOTE: Store has no durability, so intents are lost across system
1846 # restarts
1847 main.step( "Compare current intents with intents before the failure" )
1848 # NOTE: this requires case 5 to pass for intentState to be set.
1849 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001850 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001851 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001852 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001853 main.log.info( "Intents are consistent with before failure" )
Jon Hall58c76b72015-02-23 11:09:24 -08001854 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001855 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001856 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1857 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001858 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001859 before = json.loads( intentState )
1860 after = json.loads( ONOSIntents[ 0 ] )
1861 for intent in before:
1862 if intent not in after:
1863 sameIntents = main.FALSE
1864 main.log.debug( "Intent is not currently in ONOS " +\
1865 "(at least in the same form):" )
1866 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001867 except ( ValueError, TypeError ):
1868 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001869 main.log.debug( repr( ONOSIntents[0] ) )
1870 main.log.debug( repr( intentState ) )
1871 if sameIntents == main.FALSE:
1872 try:
1873 main.log.debug( "ONOS intents before: " )
1874 main.log.debug( json.dumps( json.loads( intentState ),
1875 sort_keys=True, indent=4,
1876 separators=( ',', ': ' ) ) )
1877 main.log.debug( "Current ONOS intents: " )
1878 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1879 sort_keys=True, indent=4,
1880 separators=( ',', ': ' ) ) )
1881 except ( ValueError, TypeError ):
1882 main.log.exception( "Exception printing intents" )
1883 main.log.debug( repr( ONOSIntents[0] ) )
1884 main.log.debug( repr( intentState ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001885 utilities.assert_equals(
1886 expect=main.TRUE,
1887 actual=sameIntents,
1888 onpass="Intents are consistent with before failure",
1889 onfail="The Intents changed during failure" )
1890 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001891
Jon Hall58c76b72015-02-23 11:09:24 -08001892 main.step( "Get the OF Table entries and compare to before " +
1893 "component failure" )
1894 FlowTables = main.TRUE
1895 flows2 = []
1896 for i in range( 28 ):
1897 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1898 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1899 flows2.append( tmpFlows )
1900 tempResult = main.Mininet2.flowComp(
1901 flow1=flows[ i ],
1902 flow2=tmpFlows )
1903 FlowTables = FlowTables and tempResult
1904 if FlowTables == main.FALSE:
1905 main.log.info( "Differences in flow table for switch: s" +
1906 str( i + 1 ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001907 utilities.assert_equals(
1908 expect=main.TRUE,
1909 actual=FlowTables,
1910 onpass="No changes were found in the flow tables",
1911 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001912
Jon Hall6aec96b2015-01-19 14:49:31 -08001913 main.step( "Check the continuous pings to ensure that no packets " +
1914 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001915 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1916 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001917 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001918 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1919 for i in range( 8, 18 ):
1920 main.log.info(
1921 "Checking for a loss in pings along flow from s" +
1922 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001923 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001924 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001925 str( i ) ) or LossInPings
1926 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001927 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001928 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001929 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001930 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001931 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001932 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001933 utilities.assert_equals(
1934 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001935 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001936 onpass="No Loss of connectivity",
1937 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001938
Jon Hall390696c2015-05-05 17:13:41 -07001939 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001940 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001941 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001942 # FIXME: make sure this matches nodes that were restarted
1943 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1944 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07001945
Jon Hall8f89dda2015-01-22 16:03:33 -08001946 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001947 for cli in CLIs:
1948 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001949 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001950 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07001951 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001952 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001953 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001954 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001955 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001956 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001957 main.log.error( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 " shows no leader for the election-app was" +
1959 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001960 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001961 elif leaderN in restarted:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001962 main.log.error( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001963 " as leader for the election-app, but it " +
1964 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001965 leaderResult = main.FALSE
1966 if len( set( leaderList ) ) != 1:
1967 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 main.log.error(
1969 "Inconsistent view of leader for the election test app" )
1970 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08001971 utilities.assert_equals(
1972 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001973 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001974 onpass="Leadership election passed",
1975 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001976
Jon Hall6aec96b2015-01-19 14:49:31 -08001977 def CASE8( self, main ):
1978 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001979 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001980 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001981 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001982 # FIXME add this path to params
1983 sys.path.append( "/home/admin/sts" )
1984 # assumes that sts is already in you PYTHONPATH
1985 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001986 import json
1987 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001988 assert numControllers, "numControllers not defined"
1989 assert main, "main not defined"
1990 assert utilities.assert_equals, "utilities.assert_equals not defined"
1991 assert CLIs, "CLIs not defined"
1992 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001993
Jon Hallfeff3082015-05-19 10:23:26 -07001994 main.case( "Compare ONOS Topology view to Mininet topology" )
1995 main.caseExplaination = "Compare topology objects between Mininet" +\
1996 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08001997 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07001998 try:
1999 ctrls = []
2000 for node in nodes:
2001 temp = ( node, node.name, node.ip_address, 6633 )
2002 ctrls.append( temp )
2003 MNTopo = TestONTopology( main.Mininet1, ctrls )
2004 except Exception:
2005 objResult = main.FALSE
2006 else:
2007 objResult = main.TRUE
2008 utilities.assert_equals( expect=main.TRUE, actual=objResult,
2009 onpass="Created TestONTopology object",
2010 onfail="Exception while creating " +
2011 "TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002012
Jon Hallfeff3082015-05-19 10:23:26 -07002013 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 devicesResults = main.TRUE
2015 portsResults = main.TRUE
2016 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002017 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002018 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002019 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002020 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002021 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002022 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002023 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002024 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002025 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08002026 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002027 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08002028 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002029 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002030 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002031 threads = []
2032 for i in range( numControllers ):
2033 t = main.Thread( target=CLIs[i].devices,
2034 name="devices-" + str( i ),
2035 args=[ ] )
2036 threads.append( t )
2037 t.start()
2038
2039 for t in threads:
2040 t.join()
2041 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002042 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002043 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002044 threads = []
2045 for i in range( numControllers ):
2046 t = main.Thread( target=CLIs[i].hosts,
2047 name="hosts-" + str( i ),
2048 args=[ ] )
2049 threads.append( t )
2050 t.start()
2051
2052 for t in threads:
2053 t.join()
2054 try:
2055 hosts.append( json.loads( t.result ) )
2056 except ( ValueError, TypeError ):
2057 main.log.exception( "Error parsing hosts results" )
2058 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002059 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002060 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002062 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08002063 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002064 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002065 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002066 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002067 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002068 threads = []
2069 for i in range( numControllers ):
2070 t = main.Thread( target=CLIs[i].ports,
2071 name="ports-" + str( i ),
2072 args=[ ] )
2073 threads.append( t )
2074 t.start()
2075
2076 for t in threads:
2077 t.join()
2078 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002079 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002080 threads = []
2081 for i in range( numControllers ):
2082 t = main.Thread( target=CLIs[i].links,
2083 name="links-" + str( i ),
2084 args=[ ] )
2085 threads.append( t )
2086 t.start()
2087
2088 for t in threads:
2089 t.join()
2090 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002091 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002092 threads = []
2093 for i in range( numControllers ):
2094 t = main.Thread( target=CLIs[i].clusters,
2095 name="clusters-" + str( i ),
2096 args=[ ] )
2097 threads.append( t )
2098 t.start()
2099
2100 for t in threads:
2101 t.join()
2102 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002103
Jon Hall8f89dda2015-01-22 16:03:33 -08002104 elapsed = time.time() - startTime
2105 cliTime = time.time() - cliStart
2106 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002107
Jon Hall8f89dda2015-01-22 16:03:33 -08002108 for controller in range( numControllers ):
2109 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002110 if devices[ controller ] or "Error" not in devices[
2111 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002112 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002113 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002114 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002115 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002116 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002117 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002118 actual=currentDevicesResult,
2119 onpass="ONOS" + controllerStr +
2120 " Switches view is correct",
2121 onfail="ONOS" + controllerStr +
2122 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002123
Jon Hall6aec96b2015-01-19 14:49:31 -08002124 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002125 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002126 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002127 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002128 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002129 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002130 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002131 actual=currentPortsResult,
2132 onpass="ONOS" + controllerStr +
2133 " ports view is correct",
2134 onfail="ONOS" + controllerStr +
2135 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002136
Jon Hall6aec96b2015-01-19 14:49:31 -08002137 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002138 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002139 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002140 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002141 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002142 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002143 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002144 actual=currentLinksResult,
2145 onpass="ONOS" + controllerStr +
2146 " links view is correct",
2147 onfail="ONOS" + controllerStr +
2148 " links view is incorrect" )
2149
2150 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2151 currentHostsResult = main.Mininet1.compareHosts(
2152 MNTopo, hosts[ controller ] )
2153 else:
2154 currentHostsResult = main.FALSE
2155 utilities.assert_equals( expect=main.TRUE,
2156 actual=currentHostsResult,
2157 onpass="ONOS" + controllerStr +
2158 " hosts exist in Mininet",
2159 onfail="ONOS" + controllerStr +
2160 " hosts don't match Mininet" )
2161
2162 devicesResults = devicesResults and currentDevicesResult
2163 portsResults = portsResults and currentPortsResult
2164 linksResults = linksResults and currentLinksResult
2165 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002166
Jon Hall529a37f2015-01-28 10:02:00 -08002167 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002168
Jon Hall6aec96b2015-01-19 14:49:31 -08002169 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002170 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002171 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002172 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002173 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002174 if "Error" not in hosts[ controller ]:
2175 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002176 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002177 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07002178 main.log.error( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002179 " is inconsistent with ONOS1" )
2180 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002181 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002182
2183 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002184 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002185 controllerStr )
2186 consistentHostsResult = main.FALSE
2187 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002188 " hosts response: " +
2189 repr( hosts[ controller ] ) )
2190 utilities.assert_equals(
2191 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002192 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002193 onpass="Hosts view is consistent across all ONOS nodes",
2194 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002195
Jon Hall6aec96b2015-01-19 14:49:31 -08002196 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002197 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002198 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002199 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002200 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002201 if "Error" not in clusters[ controller ]:
2202 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002203 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002204 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07002205 main.log.error( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002206 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002207 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002208 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002209
2210 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002211 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002212 "from ONOS" + controllerStr )
2213 consistentClustersResult = main.FALSE
2214 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002215 " clusters response: " +
2216 repr( clusters[ controller ] ) )
2217 utilities.assert_equals(
2218 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002219 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002220 onpass="Clusters view is consistent across all ONOS nodes",
2221 onfail="ONOS nodes have different views of clusters" )
2222 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002223 main.step( "Topology view is correct and consistent across all " +
2224 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002225 try:
2226 numClusters = len( json.loads( clusters[ 0 ] ) )
2227 except ( ValueError, TypeError ):
2228 main.log.exception( "Error parsing clusters[0]: " +
2229 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002230 clusterResults = main.FALSE
2231 if numClusters == 1:
2232 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 utilities.assert_equals(
2234 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002235 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002236 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002237 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002238
Jon Hall8f89dda2015-01-22 16:03:33 -08002239 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002240 and hostsResults and consistentHostsResult
2241 and consistentClustersResult and clusterResults
2242 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002243
Jon Hall8f89dda2015-01-22 16:03:33 -08002244 topoResult = topoResult and int( count <= 2 )
2245 note = "note it takes about " + str( int( cliTime ) ) + \
2246 " seconds for the test to make all the cli calls to fetch " +\
2247 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002248 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002249 "Very crass estimate for topology discovery/convergence( " +
2250 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002251 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002252 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002253 onpass="Topology Check Test successful",
2254 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002255
Jon Halla9d26da2015-03-30 16:45:32 -07002256 # FIXME: move this to an ONOS state case
2257 main.step( "Checking ONOS nodes" )
2258 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002259 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002260 threads = []
2261 for i in range( numControllers ):
2262 t = main.Thread( target=CLIs[i].nodes,
2263 name="nodes-" + str( i ),
2264 args=[ ] )
2265 threads.append( t )
2266 t.start()
2267
2268 for t in threads:
2269 t.join()
2270 nodesOutput.append( t.result )
2271 ips = [ node.ip_address for node in nodes ]
2272 for i in nodesOutput:
2273 try:
2274 current = json.loads( i )
2275 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002276 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002277 if node['ip'] in ips: # node in nodes() output is in cell
2278 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002279 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002280 else:
2281 main.log.error( "Error in ONOS node availability" )
2282 main.log.error(
2283 json.dumps( current,
2284 sort_keys=True,
2285 indent=4,
2286 separators=( ',', ': ' ) ) )
2287 break
Jon Hall390696c2015-05-05 17:13:41 -07002288 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002289 except ( ValueError, TypeError ):
2290 main.log.error( "Error parsing nodes output" )
2291 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002292 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2293 onpass="Nodes check successful",
2294 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002295
Jon Hall6aec96b2015-01-19 14:49:31 -08002296 def CASE9( self, main ):
2297 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002298 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002299 """
2300 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002301 assert numControllers, "numControllers not defined"
2302 assert main, "main not defined"
2303 assert utilities.assert_equals, "utilities.assert_equals not defined"
2304 assert CLIs, "CLIs not defined"
2305 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002306 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002307
Jon Hall8f89dda2015-01-22 16:03:33 -08002308 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002309
Jon Hall6aec96b2015-01-19 14:49:31 -08002310 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002311 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002312 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002313
Jon Hall6aec96b2015-01-19 14:49:31 -08002314 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002315 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002316 main.log.info( "Waiting " + str( linkSleep ) +
2317 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002318 time.sleep( linkSleep )
2319 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002320 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002321 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002322 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002323
Jon Hall6aec96b2015-01-19 14:49:31 -08002324 def CASE10( self, main ):
2325 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002326 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002327 """
2328 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002329 assert numControllers, "numControllers not defined"
2330 assert main, "main not defined"
2331 assert utilities.assert_equals, "utilities.assert_equals not defined"
2332 assert CLIs, "CLIs not defined"
2333 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002334 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002335
Jon Hall8f89dda2015-01-22 16:03:33 -08002336 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002337
Jon Hall6aec96b2015-01-19 14:49:31 -08002338 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002339 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002340 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002341
Jon Hall6aec96b2015-01-19 14:49:31 -08002342 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002343 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002344 main.log.info( "Waiting " + str( linkSleep ) +
2345 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002346 time.sleep( linkSleep )
2347 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002348 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002349 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002350 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002351
Jon Hall6aec96b2015-01-19 14:49:31 -08002352 def CASE11( self, main ):
2353 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002354 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002355 """
2356 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002357 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002358 assert numControllers, "numControllers not defined"
2359 assert main, "main not defined"
2360 assert utilities.assert_equals, "utilities.assert_equals not defined"
2361 assert CLIs, "CLIs not defined"
2362 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002363
Jon Hall8f89dda2015-01-22 16:03:33 -08002364 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002365
2366 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002367 main.case( description )
2368 switch = main.params[ 'kill' ][ 'switch' ]
2369 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002370
Jon Hall6aec96b2015-01-19 14:49:31 -08002371 # TODO: Make this switch parameterizable
2372 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002373 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002374 main.Mininet1.delSwitch( switch )
2375 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002376 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002377 time.sleep( switchSleep )
2378 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 # Peek at the deleted switch
2380 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002381 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002382 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002383 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002384 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002385 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002386 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002387
Jon Hall6aec96b2015-01-19 14:49:31 -08002388 def CASE12( self, main ):
2389 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002390 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002391 """
2392 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002393 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002394 assert numControllers, "numControllers not defined"
2395 assert main, "main not defined"
2396 assert utilities.assert_equals, "utilities.assert_equals not defined"
2397 assert CLIs, "CLIs not defined"
2398 assert nodes, "nodes not defined"
2399 assert ONOS1Port, "ONOS1Port not defined"
2400 assert ONOS2Port, "ONOS2Port not defined"
2401 assert ONOS3Port, "ONOS3Port not defined"
2402 assert ONOS4Port, "ONOS4Port not defined"
2403 assert ONOS5Port, "ONOS5Port not defined"
2404 assert ONOS6Port, "ONOS6Port not defined"
2405 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002406
Jon Hall8f89dda2015-01-22 16:03:33 -08002407 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002408 switch = main.params[ 'kill' ][ 'switch' ]
2409 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2410 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002411 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002412 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002413
Jon Hall6aec96b2015-01-19 14:49:31 -08002414 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002415 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002416 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002417 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002418 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2419 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002420 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002421 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002422 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002423 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002424 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002425 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002426 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002427 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002428 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002429 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002430 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002431 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002432 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002433 port7=ONOS7Port )
2434 main.log.info( "Waiting " + str( switchSleep ) +
2435 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002436 time.sleep( switchSleep )
2437 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002438 # Peek at the deleted switch
2439 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002440 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002441 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002442 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002443 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002444 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002445 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002446
Jon Hall6aec96b2015-01-19 14:49:31 -08002447 def CASE13( self, main ):
2448 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002449 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002450 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002451 import os
2452 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002453 assert numControllers, "numControllers not defined"
2454 assert main, "main not defined"
2455 assert utilities.assert_equals, "utilities.assert_equals not defined"
2456 assert CLIs, "CLIs not defined"
2457 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002458
2459 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002460 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2461 'blue': '\033[94m', 'green': '\033[92m',
2462 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002463 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002464 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002465 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002466
Jon Hall6aec96b2015-01-19 14:49:31 -08002467 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002468 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002469 teststationUser = main.params[ 'TESTONUSER' ]
2470 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002471 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002472 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002473 # FIXME: scp
2474 # mn files
2475 # TODO: Load these from params
2476 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002477 logFolder = "/opt/onos/log/"
2478 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002479 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002480 dstDir = "~/packet_captures/"
2481 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002482 for node in nodes:
2483 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2484 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002485 teststationUser + "@" +
2486 teststationIP + ":" +
2487 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002488 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002489 main.ONOSbench.handle.expect( "\$" )
2490
Jon Hall6aec96b2015-01-19 14:49:31 -08002491 # std*.log's
2492 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002493 logFolder = "/opt/onos/var/"
2494 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002496 dstDir = "~/packet_captures/"
2497 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002498 for node in nodes:
2499 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2500 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002501 teststationUser + "@" +
2502 teststationIP + ":" +
2503 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002504 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002505 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002506 # sleep so scp can finish
2507 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002508
2509 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002510 mnResult = main.Mininet1.stopNet()
2511 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2512 onpass="Mininet stopped",
2513 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002514
2515 main.step( "Checking ONOS Logs for errors" )
2516 for node in nodes:
2517 print colors[ 'purple' ] + "Checking logs for errors on " + \
2518 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002519 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002520
Jon Hall6aec96b2015-01-19 14:49:31 -08002521 main.step( "Packing and rotating pcap archives" )
2522 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002523
Jon Hallfeff3082015-05-19 10:23:26 -07002524 try:
2525 timerLog = open( main.logdir + "/Timers.csv", 'w')
2526 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002527 labels = "Gossip Intents, Restart"
2528 data = str( gossipTime ) + ", " + str( main.restartTime )
2529 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002530 timerLog.close()
2531 except NameError, e:
2532 main.log.exception(e)
2533
Jon Hall6aec96b2015-01-19 14:49:31 -08002534 def CASE14( self, main ):
2535 """
Jon Hall669173b2014-12-17 11:36:30 -08002536 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002537 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002538 assert numControllers, "numControllers not defined"
2539 assert main, "main not defined"
2540 assert utilities.assert_equals, "utilities.assert_equals not defined"
2541 assert CLIs, "CLIs not defined"
2542 assert nodes, "nodes not defined"
2543
Jon Hall390696c2015-05-05 17:13:41 -07002544 main.case("Start Leadership Election app")
2545 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002546 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2547 utilities.assert_equals(
2548 expect=main.TRUE,
2549 actual=appResult,
2550 onpass="Election app installed",
2551 onfail="Something went wrong with installing Leadership election" )
2552
2553 main.step( "Run for election on each node" )
2554 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002555 leaders = []
2556 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002557 cli.electionTestRun()
2558 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002559 leader = cli.electionTestLeader()
2560 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002561 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002562 "should be an ONOS node, instead got '" +
2563 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002564 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002565 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002566 utilities.assert_equals(
2567 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002568 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002569 onpass="Successfully ran for leadership",
2570 onfail="Failed to run for leadership" )
2571
2572 main.step( "Check that each node shows the same leader" )
2573 sameLeader = main.TRUE
2574 if len( set( leaders ) ) != 1:
2575 sameLeader = main.FALSE
2576 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2577 str( leaders ) )
2578 utilities.assert_equals(
2579 expect=main.TRUE,
2580 actual=sameLeader,
2581 onpass="Leadership is consistent for the election topic",
2582 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002583
Jon Hall6aec96b2015-01-19 14:49:31 -08002584 def CASE15( self, main ):
2585 """
Jon Hall669173b2014-12-17 11:36:30 -08002586 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002587 """
Jon Hall390696c2015-05-05 17:13:41 -07002588 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002589 assert numControllers, "numControllers not defined"
2590 assert main, "main not defined"
2591 assert utilities.assert_equals, "utilities.assert_equals not defined"
2592 assert CLIs, "CLIs not defined"
2593 assert nodes, "nodes not defined"
2594
Jon Hall8f89dda2015-01-22 16:03:33 -08002595 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002596 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002597 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002598
2599 main.step( "Check that each node shows the same leader" )
2600 sameLeader = main.TRUE
2601 leaders = []
2602 for cli in CLIs:
2603 leader = cli.electionTestLeader()
2604 leaders.append( leader )
2605 if len( set( leaders ) ) != 1:
2606 sameLeader = main.FALSE
2607 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2608 str( leaders ) )
2609 utilities.assert_equals(
2610 expect=main.TRUE,
2611 actual=sameLeader,
2612 onpass="Leadership is consistent for the election topic",
2613 onfail="Nodes have different leaders" )
2614
Jon Hall6aec96b2015-01-19 14:49:31 -08002615 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002616 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002617 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002618 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002619 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002620 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002621 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002622 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002623 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002624 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002625 for i in range( len( CLIs ) ):
2626 if leader == nodes[ i ].ip_address:
2627 oldLeader = CLIs[ i ]
2628 break
Jon Halla9d26da2015-03-30 16:45:32 -07002629 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002630 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002631 if oldLeader:
2632 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002633 utilities.assert_equals(
2634 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002635 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002636 onpass="Node was withdrawn from election",
2637 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002638
Jon Hall6aec96b2015-01-19 14:49:31 -08002639 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002640 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002641 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002642 for cli in CLIs:
2643 leaderN = cli.electionTestLeader()
2644 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002645 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002646 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002647 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002648 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002649 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002650 # error in response
2651 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002652 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002653 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002654 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002655 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002656 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002657 elif leaderN is None:
2658 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002659 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002660 leaderN = cli.electionTestLeader()
2661 leaderList.pop()
2662 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002663 consistentLeader = main.FALSE
2664 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002665 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002666 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002667 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002668 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002669 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002670 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002671 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002672 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002673 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002674 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002675 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002676 utilities.assert_equals(
2677 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002678 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002679 onpass="Leadership election passed",
2680 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002681
Jon Hall58c76b72015-02-23 11:09:24 -08002682 main.step( "Run for election on old leader( just so everyone " +
2683 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002684 if oldLeader:
2685 runResult = oldLeader.electionTestRun()
2686 else:
2687 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002688 utilities.assert_equals(
2689 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002690 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002691 onpass="App re-ran for election",
2692 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002693
Jon Hallfeff3082015-05-19 10:23:26 -07002694 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002695 afterRun = main.ONOScli1.electionTestLeader()
2696 # verify leader didn't just change
2697 if afterRun == leaderList[ 0 ]:
2698 afterResult = main.TRUE
2699 else:
2700 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002701
Jon Hall6aec96b2015-01-19 14:49:31 -08002702 utilities.assert_equals(
2703 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002704 actual=afterResult,
2705 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002706 onfail="Something went wrong with Leadership election after " +
2707 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002708
Jon Hall390696c2015-05-05 17:13:41 -07002709 def CASE16( self, main ):
2710 """
2711 Install Distributed Primitives app
2712 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002713 import time
Jon Hall390696c2015-05-05 17:13:41 -07002714 assert numControllers, "numControllers not defined"
2715 assert main, "main not defined"
2716 assert utilities.assert_equals, "utilities.assert_equals not defined"
2717 assert CLIs, "CLIs not defined"
2718 assert nodes, "nodes not defined"
2719
2720 # Variables for the distributed primitives tests
2721 global pCounterName
2722 global iCounterName
2723 global pCounterValue
2724 global iCounterValue
2725 global onosSet
2726 global onosSetName
2727 pCounterName = "TestON-Partitions"
2728 iCounterName = "TestON-inMemory"
2729 pCounterValue = 0
2730 iCounterValue = 0
2731 onosSet = set([])
2732 onosSetName = "TestON-set"
2733
2734 description = "Install Primitives app"
2735 main.case( description )
2736 main.step( "Install Primitives app" )
2737 appName = "org.onosproject.distributedprimitives"
2738 appResults = CLIs[0].activateApp( appName )
2739 utilities.assert_equals( expect=main.TRUE,
2740 actual=appResults,
2741 onpass="Primitives app activated",
2742 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002743 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002744
2745 def CASE17( self, main ):
2746 """
2747 Check for basic functionality with distributed primitives
2748 """
2749 # Make sure variables are defined/set
2750 assert numControllers, "numControllers not defined"
2751 assert main, "main not defined"
2752 assert utilities.assert_equals, "utilities.assert_equals not defined"
2753 assert CLIs, "CLIs not defined"
2754 assert nodes, "nodes not defined"
2755 assert pCounterName, "pCounterName not defined"
2756 assert iCounterName, "iCounterName not defined"
2757 assert onosSetName, "onosSetName not defined"
2758 # NOTE: assert fails if value is 0/None/Empty/False
2759 try:
2760 pCounterValue
2761 except NameError:
2762 main.log.error( "pCounterValue not defined, setting to 0" )
2763 pCounterValue = 0
2764 try:
2765 iCounterValue
2766 except NameError:
2767 main.log.error( "iCounterValue not defined, setting to 0" )
2768 iCounterValue = 0
2769 try:
2770 onosSet
2771 except NameError:
2772 main.log.error( "onosSet not defined, setting to empty Set" )
2773 onosSet = set([])
2774 # Variables for the distributed primitives tests. These are local only
2775 addValue = "a"
2776 addAllValue = "a b c d e f"
2777 retainValue = "c d e f"
2778
2779 description = "Check for basic functionality with distributed " +\
2780 "primitives"
2781 main.case( description )
2782 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2783 # DISTRIBUTED ATOMIC COUNTERS
2784 main.step( "Increment and get a default counter on each node" )
2785 pCounters = []
2786 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002787 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002788 for i in range( numControllers ):
2789 t = main.Thread( target=CLIs[i].counterTestIncrement,
2790 name="counterIncrement-" + str( i ),
2791 args=[ pCounterName ] )
2792 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002793 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002794 threads.append( t )
2795 t.start()
2796
2797 for t in threads:
2798 t.join()
2799 pCounters.append( t.result )
2800 # Check that counter incremented numController times
2801 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002802 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002803 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002804 pCounterResults = pCounterResults and tmpResult
2805 if not tmpResult:
2806 main.log.error( str( i ) + " is not in partitioned "
2807 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002808 utilities.assert_equals( expect=True,
2809 actual=pCounterResults,
2810 onpass="Default counter incremented",
2811 onfail="Error incrementing default" +
2812 " counter" )
2813
2814 main.step( "Increment and get an in memory counter on each node" )
2815 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002816 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002817 threads = []
2818 for i in range( numControllers ):
2819 t = main.Thread( target=CLIs[i].counterTestIncrement,
2820 name="icounterIncrement-" + str( i ),
2821 args=[ iCounterName ],
2822 kwargs={ "inMemory": True } )
2823 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002824 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002825 threads.append( t )
2826 t.start()
2827
2828 for t in threads:
2829 t.join()
2830 iCounters.append( t.result )
2831 # Check that counter incremented numController times
2832 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002833 for i in addedIValues:
2834 tmpResult = i in iCounters
2835 iCounterResults = iCounterResults and tmpResult
2836 if not tmpResult:
2837 main.log.error( str( i ) + " is not in the in-memory "
2838 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002839 utilities.assert_equals( expect=True,
2840 actual=iCounterResults,
2841 onpass="In memory counter incremented",
2842 onfail="Error incrementing in memory" +
2843 " counter" )
2844
2845 main.step( "Check counters are consistant across nodes" )
2846 onosCounters = []
2847 threads = []
2848 for i in range( numControllers ):
2849 t = main.Thread( target=CLIs[i].counters,
2850 name="counters-" + str( i ) )
2851 threads.append( t )
2852 t.start()
2853 for t in threads:
2854 t.join()
2855 onosCounters.append( t.result )
2856 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2857 if all( tmp ):
2858 main.log.info( "Counters are consistent across all nodes" )
2859 consistentCounterResults = main.TRUE
2860 else:
2861 main.log.error( "Counters are not consistent across all nodes" )
2862 consistentCounterResults = main.FALSE
2863 utilities.assert_equals( expect=main.TRUE,
2864 actual=consistentCounterResults,
2865 onpass="ONOS counters are consistent " +
2866 "across nodes",
2867 onfail="ONOS Counters are inconsistent " +
2868 "across nodes" )
2869
2870 main.step( "Counters we added have the correct values" )
2871 correctResults = main.TRUE
2872 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002873 current = json.loads( onosCounters[i] )
2874 pValue = None
2875 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002876 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002877 for database in current:
2878 partitioned = database.get( 'partitionedDatabaseCounters' )
2879 if partitioned:
2880 for value in partitioned:
2881 if value.get( 'name' ) == pCounterName:
2882 pValue = value.get( 'value' )
2883 break
2884 inMemory = database.get( 'inMemoryDatabaseCounters' )
2885 if inMemory:
2886 for value in inMemory:
2887 if value.get( 'name' ) == iCounterName:
2888 iValue = value.get( 'value' )
2889 break
Jon Hall390696c2015-05-05 17:13:41 -07002890 except AttributeError, e:
2891 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2892 "is not as expected" )
2893 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07002894 if pValue == pCounterValue:
2895 main.log.info( "Partitioned counter value is correct" )
2896 else:
2897 main.log.error( "Partitioned counter value is incorrect," +
2898 " expected value: " + str( pCounterValue )
2899 + " current value: " + str( pValue ) )
2900 correctResults = main.FALSE
2901 if iValue == iCounterValue:
2902 main.log.info( "In memory counter value is correct" )
2903 else:
2904 main.log.error( "In memory counter value is incorrect, " +
2905 "expected value: " + str( iCounterValue ) +
2906 " current value: " + str( iValue ) )
2907 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07002908 utilities.assert_equals( expect=main.TRUE,
2909 actual=correctResults,
2910 onpass="Added counters are correct",
2911 onfail="Added counters are incorrect" )
2912 # DISTRIBUTED SETS
2913 main.step( "Distributed Set get" )
2914 size = len( onosSet )
2915 getResponses = []
2916 threads = []
2917 for i in range( numControllers ):
2918 t = main.Thread( target=CLIs[i].setTestGet,
2919 name="setTestGet-" + str( i ),
2920 args=[ onosSetName ] )
2921 threads.append( t )
2922 t.start()
2923 for t in threads:
2924 t.join()
2925 getResponses.append( t.result )
2926
2927 getResults = main.TRUE
2928 for i in range( numControllers ):
2929 if isinstance( getResponses[ i ], list):
2930 current = set( getResponses[ i ] )
2931 if len( current ) == len( getResponses[ i ] ):
2932 # no repeats
2933 if onosSet != current:
2934 main.log.error( "ONOS" + str( i + 1 ) +
2935 " has incorrect view" +
2936 " of set " + onosSetName + ":\n" +
2937 str( getResponses[ i ] ) )
2938 main.log.debug( "Expected: " + str( onosSet ) )
2939 main.log.debug( "Actual: " + str( current ) )
2940 getResults = main.FALSE
2941 else:
2942 # error, set is not a set
2943 main.log.error( "ONOS" + str( i + 1 ) +
2944 " has repeat elements in" +
2945 " set " + onosSetName + ":\n" +
2946 str( getResponses[ i ] ) )
2947 getResults = main.FALSE
2948 elif getResponses[ i ] == main.ERROR:
2949 getResults = main.FALSE
2950 utilities.assert_equals( expect=main.TRUE,
2951 actual=getResults,
2952 onpass="Set elements are correct",
2953 onfail="Set elements are incorrect" )
2954
2955 main.step( "Distributed Set size" )
2956 sizeResponses = []
2957 threads = []
2958 for i in range( numControllers ):
2959 t = main.Thread( target=CLIs[i].setTestSize,
2960 name="setTestSize-" + str( i ),
2961 args=[ onosSetName ] )
2962 threads.append( t )
2963 t.start()
2964 for t in threads:
2965 t.join()
2966 sizeResponses.append( t.result )
2967
2968 sizeResults = main.TRUE
2969 for i in range( numControllers ):
2970 if size != sizeResponses[ i ]:
2971 sizeResults = main.FALSE
2972 main.log.error( "ONOS" + str( i + 1 ) +
2973 " expected a size of " + str( size ) +
2974 " for set " + onosSetName +
2975 " but got " + str( sizeResponses[ i ] ) )
2976 utilities.assert_equals( expect=main.TRUE,
2977 actual=sizeResults,
2978 onpass="Set sizes are correct",
2979 onfail="Set sizes are incorrect" )
2980
2981 main.step( "Distributed Set add()" )
2982 onosSet.add( addValue )
2983 addResponses = []
2984 threads = []
2985 for i in range( numControllers ):
2986 t = main.Thread( target=CLIs[i].setTestAdd,
2987 name="setTestAdd-" + str( i ),
2988 args=[ onosSetName, addValue ] )
2989 threads.append( t )
2990 t.start()
2991 for t in threads:
2992 t.join()
2993 addResponses.append( t.result )
2994
2995 # main.TRUE = successfully changed the set
2996 # main.FALSE = action resulted in no change in set
2997 # main.ERROR - Some error in executing the function
2998 addResults = main.TRUE
2999 for i in range( numControllers ):
3000 if addResponses[ i ] == main.TRUE:
3001 # All is well
3002 pass
3003 elif addResponses[ i ] == main.FALSE:
3004 # Already in set, probably fine
3005 pass
3006 elif addResponses[ i ] == main.ERROR:
3007 # Error in execution
3008 addResults = main.FALSE
3009 else:
3010 # unexpected result
3011 addResults = main.FALSE
3012 if addResults != main.TRUE:
3013 main.log.error( "Error executing set add" )
3014
3015 # Check if set is still correct
3016 size = len( onosSet )
3017 getResponses = []
3018 threads = []
3019 for i in range( numControllers ):
3020 t = main.Thread( target=CLIs[i].setTestGet,
3021 name="setTestGet-" + str( i ),
3022 args=[ onosSetName ] )
3023 threads.append( t )
3024 t.start()
3025 for t in threads:
3026 t.join()
3027 getResponses.append( t.result )
3028 getResults = main.TRUE
3029 for i in range( numControllers ):
3030 if isinstance( getResponses[ i ], list):
3031 current = set( getResponses[ i ] )
3032 if len( current ) == len( getResponses[ i ] ):
3033 # no repeats
3034 if onosSet != current:
3035 main.log.error( "ONOS" + str( i + 1 ) +
3036 " has incorrect view" +
3037 " of set " + onosSetName + ":\n" +
3038 str( getResponses[ i ] ) )
3039 main.log.debug( "Expected: " + str( onosSet ) )
3040 main.log.debug( "Actual: " + str( current ) )
3041 getResults = main.FALSE
3042 else:
3043 # error, set is not a set
3044 main.log.error( "ONOS" + str( i + 1 ) +
3045 " has repeat elements in" +
3046 " set " + onosSetName + ":\n" +
3047 str( getResponses[ i ] ) )
3048 getResults = main.FALSE
3049 elif getResponses[ i ] == main.ERROR:
3050 getResults = main.FALSE
3051 sizeResponses = []
3052 threads = []
3053 for i in range( numControllers ):
3054 t = main.Thread( target=CLIs[i].setTestSize,
3055 name="setTestSize-" + str( i ),
3056 args=[ onosSetName ] )
3057 threads.append( t )
3058 t.start()
3059 for t in threads:
3060 t.join()
3061 sizeResponses.append( t.result )
3062 sizeResults = main.TRUE
3063 for i in range( numControllers ):
3064 if size != sizeResponses[ i ]:
3065 sizeResults = main.FALSE
3066 main.log.error( "ONOS" + str( i + 1 ) +
3067 " expected a size of " + str( size ) +
3068 " for set " + onosSetName +
3069 " but got " + str( sizeResponses[ i ] ) )
3070 addResults = addResults and getResults and sizeResults
3071 utilities.assert_equals( expect=main.TRUE,
3072 actual=addResults,
3073 onpass="Set add correct",
3074 onfail="Set add was incorrect" )
3075
3076 main.step( "Distributed Set addAll()" )
3077 onosSet.update( addAllValue.split() )
3078 addResponses = []
3079 threads = []
3080 for i in range( numControllers ):
3081 t = main.Thread( target=CLIs[i].setTestAdd,
3082 name="setTestAddAll-" + str( i ),
3083 args=[ onosSetName, addAllValue ] )
3084 threads.append( t )
3085 t.start()
3086 for t in threads:
3087 t.join()
3088 addResponses.append( t.result )
3089
3090 # main.TRUE = successfully changed the set
3091 # main.FALSE = action resulted in no change in set
3092 # main.ERROR - Some error in executing the function
3093 addAllResults = main.TRUE
3094 for i in range( numControllers ):
3095 if addResponses[ i ] == main.TRUE:
3096 # All is well
3097 pass
3098 elif addResponses[ i ] == main.FALSE:
3099 # Already in set, probably fine
3100 pass
3101 elif addResponses[ i ] == main.ERROR:
3102 # Error in execution
3103 addAllResults = main.FALSE
3104 else:
3105 # unexpected result
3106 addAllResults = main.FALSE
3107 if addAllResults != main.TRUE:
3108 main.log.error( "Error executing set addAll" )
3109
3110 # Check if set is still correct
3111 size = len( onosSet )
3112 getResponses = []
3113 threads = []
3114 for i in range( numControllers ):
3115 t = main.Thread( target=CLIs[i].setTestGet,
3116 name="setTestGet-" + str( i ),
3117 args=[ onosSetName ] )
3118 threads.append( t )
3119 t.start()
3120 for t in threads:
3121 t.join()
3122 getResponses.append( t.result )
3123 getResults = main.TRUE
3124 for i in range( numControllers ):
3125 if isinstance( getResponses[ i ], list):
3126 current = set( getResponses[ i ] )
3127 if len( current ) == len( getResponses[ i ] ):
3128 # no repeats
3129 if onosSet != current:
3130 main.log.error( "ONOS" + str( i + 1 ) +
3131 " has incorrect view" +
3132 " of set " + onosSetName + ":\n" +
3133 str( getResponses[ i ] ) )
3134 main.log.debug( "Expected: " + str( onosSet ) )
3135 main.log.debug( "Actual: " + str( current ) )
3136 getResults = main.FALSE
3137 else:
3138 # error, set is not a set
3139 main.log.error( "ONOS" + str( i + 1 ) +
3140 " has repeat elements in" +
3141 " set " + onosSetName + ":\n" +
3142 str( getResponses[ i ] ) )
3143 getResults = main.FALSE
3144 elif getResponses[ i ] == main.ERROR:
3145 getResults = main.FALSE
3146 sizeResponses = []
3147 threads = []
3148 for i in range( numControllers ):
3149 t = main.Thread( target=CLIs[i].setTestSize,
3150 name="setTestSize-" + str( i ),
3151 args=[ onosSetName ] )
3152 threads.append( t )
3153 t.start()
3154 for t in threads:
3155 t.join()
3156 sizeResponses.append( t.result )
3157 sizeResults = main.TRUE
3158 for i in range( numControllers ):
3159 if size != sizeResponses[ i ]:
3160 sizeResults = main.FALSE
3161 main.log.error( "ONOS" + str( i + 1 ) +
3162 " expected a size of " + str( size ) +
3163 " for set " + onosSetName +
3164 " but got " + str( sizeResponses[ i ] ) )
3165 addAllResults = addAllResults and getResults and sizeResults
3166 utilities.assert_equals( expect=main.TRUE,
3167 actual=addAllResults,
3168 onpass="Set addAll correct",
3169 onfail="Set addAll was incorrect" )
3170
3171 main.step( "Distributed Set contains()" )
3172 containsResponses = []
3173 threads = []
3174 for i in range( numControllers ):
3175 t = main.Thread( target=CLIs[i].setTestGet,
3176 name="setContains-" + str( i ),
3177 args=[ onosSetName ],
3178 kwargs={ "values": addValue } )
3179 threads.append( t )
3180 t.start()
3181 for t in threads:
3182 t.join()
3183 # NOTE: This is the tuple
3184 containsResponses.append( t.result )
3185
3186 containsResults = main.TRUE
3187 for i in range( numControllers ):
3188 if containsResponses[ i ] == main.ERROR:
3189 containsResults = main.FALSE
3190 else:
3191 containsResults = containsResults and\
3192 containsResponses[ i ][ 1 ]
3193 utilities.assert_equals( expect=main.TRUE,
3194 actual=containsResults,
3195 onpass="Set contains is functional",
3196 onfail="Set contains failed" )
3197
3198 main.step( "Distributed Set containsAll()" )
3199 containsAllResponses = []
3200 threads = []
3201 for i in range( numControllers ):
3202 t = main.Thread( target=CLIs[i].setTestGet,
3203 name="setContainsAll-" + str( i ),
3204 args=[ onosSetName ],
3205 kwargs={ "values": addAllValue } )
3206 threads.append( t )
3207 t.start()
3208 for t in threads:
3209 t.join()
3210 # NOTE: This is the tuple
3211 containsAllResponses.append( t.result )
3212
3213 containsAllResults = main.TRUE
3214 for i in range( numControllers ):
3215 if containsResponses[ i ] == main.ERROR:
3216 containsResults = main.FALSE
3217 else:
3218 containsResults = containsResults and\
3219 containsResponses[ i ][ 1 ]
3220 utilities.assert_equals( expect=main.TRUE,
3221 actual=containsAllResults,
3222 onpass="Set containsAll is functional",
3223 onfail="Set containsAll failed" )
3224
3225 main.step( "Distributed Set remove()" )
3226 onosSet.remove( addValue )
3227 removeResponses = []
3228 threads = []
3229 for i in range( numControllers ):
3230 t = main.Thread( target=CLIs[i].setTestRemove,
3231 name="setTestRemove-" + str( i ),
3232 args=[ onosSetName, addValue ] )
3233 threads.append( t )
3234 t.start()
3235 for t in threads:
3236 t.join()
3237 removeResponses.append( t.result )
3238
3239 # main.TRUE = successfully changed the set
3240 # main.FALSE = action resulted in no change in set
3241 # main.ERROR - Some error in executing the function
3242 removeResults = main.TRUE
3243 for i in range( numControllers ):
3244 if removeResponses[ i ] == main.TRUE:
3245 # All is well
3246 pass
3247 elif removeResponses[ i ] == main.FALSE:
3248 # not in set, probably fine
3249 pass
3250 elif removeResponses[ i ] == main.ERROR:
3251 # Error in execution
3252 removeResults = main.FALSE
3253 else:
3254 # unexpected result
3255 removeResults = main.FALSE
3256 if removeResults != main.TRUE:
3257 main.log.error( "Error executing set remove" )
3258
3259 # Check if set is still correct
3260 size = len( onosSet )
3261 getResponses = []
3262 threads = []
3263 for i in range( numControllers ):
3264 t = main.Thread( target=CLIs[i].setTestGet,
3265 name="setTestGet-" + str( i ),
3266 args=[ onosSetName ] )
3267 threads.append( t )
3268 t.start()
3269 for t in threads:
3270 t.join()
3271 getResponses.append( t.result )
3272 getResults = main.TRUE
3273 for i in range( numControllers ):
3274 if isinstance( getResponses[ i ], list):
3275 current = set( getResponses[ i ] )
3276 if len( current ) == len( getResponses[ i ] ):
3277 # no repeats
3278 if onosSet != current:
3279 main.log.error( "ONOS" + str( i + 1 ) +
3280 " has incorrect view" +
3281 " of set " + onosSetName + ":\n" +
3282 str( getResponses[ i ] ) )
3283 main.log.debug( "Expected: " + str( onosSet ) )
3284 main.log.debug( "Actual: " + str( current ) )
3285 getResults = main.FALSE
3286 else:
3287 # error, set is not a set
3288 main.log.error( "ONOS" + str( i + 1 ) +
3289 " has repeat elements in" +
3290 " set " + onosSetName + ":\n" +
3291 str( getResponses[ i ] ) )
3292 getResults = main.FALSE
3293 elif getResponses[ i ] == main.ERROR:
3294 getResults = main.FALSE
3295 sizeResponses = []
3296 threads = []
3297 for i in range( numControllers ):
3298 t = main.Thread( target=CLIs[i].setTestSize,
3299 name="setTestSize-" + str( i ),
3300 args=[ onosSetName ] )
3301 threads.append( t )
3302 t.start()
3303 for t in threads:
3304 t.join()
3305 sizeResponses.append( t.result )
3306 sizeResults = main.TRUE
3307 for i in range( numControllers ):
3308 if size != sizeResponses[ i ]:
3309 sizeResults = main.FALSE
3310 main.log.error( "ONOS" + str( i + 1 ) +
3311 " expected a size of " + str( size ) +
3312 " for set " + onosSetName +
3313 " but got " + str( sizeResponses[ i ] ) )
3314 removeResults = removeResults and getResults and sizeResults
3315 utilities.assert_equals( expect=main.TRUE,
3316 actual=removeResults,
3317 onpass="Set remove correct",
3318 onfail="Set remove was incorrect" )
3319
3320 main.step( "Distributed Set removeAll()" )
3321 onosSet.difference_update( addAllValue.split() )
3322 removeAllResponses = []
3323 threads = []
3324 try:
3325 for i in range( numControllers ):
3326 t = main.Thread( target=CLIs[i].setTestRemove,
3327 name="setTestRemoveAll-" + str( i ),
3328 args=[ onosSetName, addAllValue ] )
3329 threads.append( t )
3330 t.start()
3331 for t in threads:
3332 t.join()
3333 removeAllResponses.append( t.result )
3334 except Exception, e:
3335 main.log.exception(e)
3336
3337 # main.TRUE = successfully changed the set
3338 # main.FALSE = action resulted in no change in set
3339 # main.ERROR - Some error in executing the function
3340 removeAllResults = main.TRUE
3341 for i in range( numControllers ):
3342 if removeAllResponses[ i ] == main.TRUE:
3343 # All is well
3344 pass
3345 elif removeAllResponses[ i ] == main.FALSE:
3346 # not in set, probably fine
3347 pass
3348 elif removeAllResponses[ i ] == main.ERROR:
3349 # Error in execution
3350 removeAllResults = main.FALSE
3351 else:
3352 # unexpected result
3353 removeAllResults = main.FALSE
3354 if removeAllResults != main.TRUE:
3355 main.log.error( "Error executing set removeAll" )
3356
3357 # Check if set is still correct
3358 size = len( onosSet )
3359 getResponses = []
3360 threads = []
3361 for i in range( numControllers ):
3362 t = main.Thread( target=CLIs[i].setTestGet,
3363 name="setTestGet-" + str( i ),
3364 args=[ onosSetName ] )
3365 threads.append( t )
3366 t.start()
3367 for t in threads:
3368 t.join()
3369 getResponses.append( t.result )
3370 getResults = main.TRUE
3371 for i in range( numControllers ):
3372 if isinstance( getResponses[ i ], list):
3373 current = set( getResponses[ i ] )
3374 if len( current ) == len( getResponses[ i ] ):
3375 # no repeats
3376 if onosSet != current:
3377 main.log.error( "ONOS" + str( i + 1 ) +
3378 " has incorrect view" +
3379 " of set " + onosSetName + ":\n" +
3380 str( getResponses[ i ] ) )
3381 main.log.debug( "Expected: " + str( onosSet ) )
3382 main.log.debug( "Actual: " + str( current ) )
3383 getResults = main.FALSE
3384 else:
3385 # error, set is not a set
3386 main.log.error( "ONOS" + str( i + 1 ) +
3387 " has repeat elements in" +
3388 " set " + onosSetName + ":\n" +
3389 str( getResponses[ i ] ) )
3390 getResults = main.FALSE
3391 elif getResponses[ i ] == main.ERROR:
3392 getResults = main.FALSE
3393 sizeResponses = []
3394 threads = []
3395 for i in range( numControllers ):
3396 t = main.Thread( target=CLIs[i].setTestSize,
3397 name="setTestSize-" + str( i ),
3398 args=[ onosSetName ] )
3399 threads.append( t )
3400 t.start()
3401 for t in threads:
3402 t.join()
3403 sizeResponses.append( t.result )
3404 sizeResults = main.TRUE
3405 for i in range( numControllers ):
3406 if size != sizeResponses[ i ]:
3407 sizeResults = main.FALSE
3408 main.log.error( "ONOS" + str( i + 1 ) +
3409 " expected a size of " + str( size ) +
3410 " for set " + onosSetName +
3411 " but got " + str( sizeResponses[ i ] ) )
3412 removeAllResults = removeAllResults and getResults and sizeResults
3413 utilities.assert_equals( expect=main.TRUE,
3414 actual=removeAllResults,
3415 onpass="Set removeAll correct",
3416 onfail="Set removeAll was incorrect" )
3417
3418 main.step( "Distributed Set addAll()" )
3419 onosSet.update( addAllValue.split() )
3420 addResponses = []
3421 threads = []
3422 for i in range( numControllers ):
3423 t = main.Thread( target=CLIs[i].setTestAdd,
3424 name="setTestAddAll-" + str( i ),
3425 args=[ onosSetName, addAllValue ] )
3426 threads.append( t )
3427 t.start()
3428 for t in threads:
3429 t.join()
3430 addResponses.append( t.result )
3431
3432 # main.TRUE = successfully changed the set
3433 # main.FALSE = action resulted in no change in set
3434 # main.ERROR - Some error in executing the function
3435 addAllResults = main.TRUE
3436 for i in range( numControllers ):
3437 if addResponses[ i ] == main.TRUE:
3438 # All is well
3439 pass
3440 elif addResponses[ i ] == main.FALSE:
3441 # Already in set, probably fine
3442 pass
3443 elif addResponses[ i ] == main.ERROR:
3444 # Error in execution
3445 addAllResults = main.FALSE
3446 else:
3447 # unexpected result
3448 addAllResults = main.FALSE
3449 if addAllResults != main.TRUE:
3450 main.log.error( "Error executing set addAll" )
3451
3452 # Check if set is still correct
3453 size = len( onosSet )
3454 getResponses = []
3455 threads = []
3456 for i in range( numControllers ):
3457 t = main.Thread( target=CLIs[i].setTestGet,
3458 name="setTestGet-" + str( i ),
3459 args=[ onosSetName ] )
3460 threads.append( t )
3461 t.start()
3462 for t in threads:
3463 t.join()
3464 getResponses.append( t.result )
3465 getResults = main.TRUE
3466 for i in range( numControllers ):
3467 if isinstance( getResponses[ i ], list):
3468 current = set( getResponses[ i ] )
3469 if len( current ) == len( getResponses[ i ] ):
3470 # no repeats
3471 if onosSet != current:
3472 main.log.error( "ONOS" + str( i + 1 ) +
3473 " has incorrect view" +
3474 " of set " + onosSetName + ":\n" +
3475 str( getResponses[ i ] ) )
3476 main.log.debug( "Expected: " + str( onosSet ) )
3477 main.log.debug( "Actual: " + str( current ) )
3478 getResults = main.FALSE
3479 else:
3480 # error, set is not a set
3481 main.log.error( "ONOS" + str( i + 1 ) +
3482 " has repeat elements in" +
3483 " set " + onosSetName + ":\n" +
3484 str( getResponses[ i ] ) )
3485 getResults = main.FALSE
3486 elif getResponses[ i ] == main.ERROR:
3487 getResults = main.FALSE
3488 sizeResponses = []
3489 threads = []
3490 for i in range( numControllers ):
3491 t = main.Thread( target=CLIs[i].setTestSize,
3492 name="setTestSize-" + str( i ),
3493 args=[ onosSetName ] )
3494 threads.append( t )
3495 t.start()
3496 for t in threads:
3497 t.join()
3498 sizeResponses.append( t.result )
3499 sizeResults = main.TRUE
3500 for i in range( numControllers ):
3501 if size != sizeResponses[ i ]:
3502 sizeResults = main.FALSE
3503 main.log.error( "ONOS" + str( i + 1 ) +
3504 " expected a size of " + str( size ) +
3505 " for set " + onosSetName +
3506 " but got " + str( sizeResponses[ i ] ) )
3507 addAllResults = addAllResults and getResults and sizeResults
3508 utilities.assert_equals( expect=main.TRUE,
3509 actual=addAllResults,
3510 onpass="Set addAll correct",
3511 onfail="Set addAll was incorrect" )
3512
3513 main.step( "Distributed Set clear()" )
3514 onosSet.clear()
3515 clearResponses = []
3516 threads = []
3517 for i in range( numControllers ):
3518 t = main.Thread( target=CLIs[i].setTestRemove,
3519 name="setTestClear-" + str( i ),
3520 args=[ onosSetName, " "], # Values doesn't matter
3521 kwargs={ "clear": True } )
3522 threads.append( t )
3523 t.start()
3524 for t in threads:
3525 t.join()
3526 clearResponses.append( t.result )
3527
3528 # main.TRUE = successfully changed the set
3529 # main.FALSE = action resulted in no change in set
3530 # main.ERROR - Some error in executing the function
3531 clearResults = main.TRUE
3532 for i in range( numControllers ):
3533 if clearResponses[ i ] == main.TRUE:
3534 # All is well
3535 pass
3536 elif clearResponses[ i ] == main.FALSE:
3537 # Nothing set, probably fine
3538 pass
3539 elif clearResponses[ i ] == main.ERROR:
3540 # Error in execution
3541 clearResults = main.FALSE
3542 else:
3543 # unexpected result
3544 clearResults = main.FALSE
3545 if clearResults != main.TRUE:
3546 main.log.error( "Error executing set clear" )
3547
3548 # Check if set is still correct
3549 size = len( onosSet )
3550 getResponses = []
3551 threads = []
3552 for i in range( numControllers ):
3553 t = main.Thread( target=CLIs[i].setTestGet,
3554 name="setTestGet-" + str( i ),
3555 args=[ onosSetName ] )
3556 threads.append( t )
3557 t.start()
3558 for t in threads:
3559 t.join()
3560 getResponses.append( t.result )
3561 getResults = main.TRUE
3562 for i in range( numControllers ):
3563 if isinstance( getResponses[ i ], list):
3564 current = set( getResponses[ i ] )
3565 if len( current ) == len( getResponses[ i ] ):
3566 # no repeats
3567 if onosSet != current:
3568 main.log.error( "ONOS" + str( i + 1 ) +
3569 " has incorrect view" +
3570 " of set " + onosSetName + ":\n" +
3571 str( getResponses[ i ] ) )
3572 main.log.debug( "Expected: " + str( onosSet ) )
3573 main.log.debug( "Actual: " + str( current ) )
3574 getResults = main.FALSE
3575 else:
3576 # error, set is not a set
3577 main.log.error( "ONOS" + str( i + 1 ) +
3578 " has repeat elements in" +
3579 " set " + onosSetName + ":\n" +
3580 str( getResponses[ i ] ) )
3581 getResults = main.FALSE
3582 elif getResponses[ i ] == main.ERROR:
3583 getResults = main.FALSE
3584 sizeResponses = []
3585 threads = []
3586 for i in range( numControllers ):
3587 t = main.Thread( target=CLIs[i].setTestSize,
3588 name="setTestSize-" + str( i ),
3589 args=[ onosSetName ] )
3590 threads.append( t )
3591 t.start()
3592 for t in threads:
3593 t.join()
3594 sizeResponses.append( t.result )
3595 sizeResults = main.TRUE
3596 for i in range( numControllers ):
3597 if size != sizeResponses[ i ]:
3598 sizeResults = main.FALSE
3599 main.log.error( "ONOS" + str( i + 1 ) +
3600 " expected a size of " + str( size ) +
3601 " for set " + onosSetName +
3602 " but got " + str( sizeResponses[ i ] ) )
3603 clearResults = clearResults and getResults and sizeResults
3604 utilities.assert_equals( expect=main.TRUE,
3605 actual=clearResults,
3606 onpass="Set clear correct",
3607 onfail="Set clear was incorrect" )
3608
3609 main.step( "Distributed Set addAll()" )
3610 onosSet.update( addAllValue.split() )
3611 addResponses = []
3612 threads = []
3613 for i in range( numControllers ):
3614 t = main.Thread( target=CLIs[i].setTestAdd,
3615 name="setTestAddAll-" + str( i ),
3616 args=[ onosSetName, addAllValue ] )
3617 threads.append( t )
3618 t.start()
3619 for t in threads:
3620 t.join()
3621 addResponses.append( t.result )
3622
3623 # main.TRUE = successfully changed the set
3624 # main.FALSE = action resulted in no change in set
3625 # main.ERROR - Some error in executing the function
3626 addAllResults = main.TRUE
3627 for i in range( numControllers ):
3628 if addResponses[ i ] == main.TRUE:
3629 # All is well
3630 pass
3631 elif addResponses[ i ] == main.FALSE:
3632 # Already in set, probably fine
3633 pass
3634 elif addResponses[ i ] == main.ERROR:
3635 # Error in execution
3636 addAllResults = main.FALSE
3637 else:
3638 # unexpected result
3639 addAllResults = main.FALSE
3640 if addAllResults != main.TRUE:
3641 main.log.error( "Error executing set addAll" )
3642
3643 # Check if set is still correct
3644 size = len( onosSet )
3645 getResponses = []
3646 threads = []
3647 for i in range( numControllers ):
3648 t = main.Thread( target=CLIs[i].setTestGet,
3649 name="setTestGet-" + str( i ),
3650 args=[ onosSetName ] )
3651 threads.append( t )
3652 t.start()
3653 for t in threads:
3654 t.join()
3655 getResponses.append( t.result )
3656 getResults = main.TRUE
3657 for i in range( numControllers ):
3658 if isinstance( getResponses[ i ], list):
3659 current = set( getResponses[ i ] )
3660 if len( current ) == len( getResponses[ i ] ):
3661 # no repeats
3662 if onosSet != current:
3663 main.log.error( "ONOS" + str( i + 1 ) +
3664 " has incorrect view" +
3665 " of set " + onosSetName + ":\n" +
3666 str( getResponses[ i ] ) )
3667 main.log.debug( "Expected: " + str( onosSet ) )
3668 main.log.debug( "Actual: " + str( current ) )
3669 getResults = main.FALSE
3670 else:
3671 # error, set is not a set
3672 main.log.error( "ONOS" + str( i + 1 ) +
3673 " has repeat elements in" +
3674 " set " + onosSetName + ":\n" +
3675 str( getResponses[ i ] ) )
3676 getResults = main.FALSE
3677 elif getResponses[ i ] == main.ERROR:
3678 getResults = main.FALSE
3679 sizeResponses = []
3680 threads = []
3681 for i in range( numControllers ):
3682 t = main.Thread( target=CLIs[i].setTestSize,
3683 name="setTestSize-" + str( i ),
3684 args=[ onosSetName ] )
3685 threads.append( t )
3686 t.start()
3687 for t in threads:
3688 t.join()
3689 sizeResponses.append( t.result )
3690 sizeResults = main.TRUE
3691 for i in range( numControllers ):
3692 if size != sizeResponses[ i ]:
3693 sizeResults = main.FALSE
3694 main.log.error( "ONOS" + str( i + 1 ) +
3695 " expected a size of " + str( size ) +
3696 " for set " + onosSetName +
3697 " but got " + str( sizeResponses[ i ] ) )
3698 addAllResults = addAllResults and getResults and sizeResults
3699 utilities.assert_equals( expect=main.TRUE,
3700 actual=addAllResults,
3701 onpass="Set addAll correct",
3702 onfail="Set addAll was incorrect" )
3703
3704 main.step( "Distributed Set retain()" )
3705 onosSet.intersection_update( retainValue.split() )
3706 retainResponses = []
3707 threads = []
3708 for i in range( numControllers ):
3709 t = main.Thread( target=CLIs[i].setTestRemove,
3710 name="setTestRetain-" + str( i ),
3711 args=[ onosSetName, retainValue ],
3712 kwargs={ "retain": True } )
3713 threads.append( t )
3714 t.start()
3715 for t in threads:
3716 t.join()
3717 retainResponses.append( t.result )
3718
3719 # main.TRUE = successfully changed the set
3720 # main.FALSE = action resulted in no change in set
3721 # main.ERROR - Some error in executing the function
3722 retainResults = main.TRUE
3723 for i in range( numControllers ):
3724 if retainResponses[ i ] == main.TRUE:
3725 # All is well
3726 pass
3727 elif retainResponses[ i ] == main.FALSE:
3728 # Already in set, probably fine
3729 pass
3730 elif retainResponses[ i ] == main.ERROR:
3731 # Error in execution
3732 retainResults = main.FALSE
3733 else:
3734 # unexpected result
3735 retainResults = main.FALSE
3736 if retainResults != main.TRUE:
3737 main.log.error( "Error executing set retain" )
3738
3739 # Check if set is still correct
3740 size = len( onosSet )
3741 getResponses = []
3742 threads = []
3743 for i in range( numControllers ):
3744 t = main.Thread( target=CLIs[i].setTestGet,
3745 name="setTestGet-" + str( i ),
3746 args=[ onosSetName ] )
3747 threads.append( t )
3748 t.start()
3749 for t in threads:
3750 t.join()
3751 getResponses.append( t.result )
3752 getResults = main.TRUE
3753 for i in range( numControllers ):
3754 if isinstance( getResponses[ i ], list):
3755 current = set( getResponses[ i ] )
3756 if len( current ) == len( getResponses[ i ] ):
3757 # no repeats
3758 if onosSet != current:
3759 main.log.error( "ONOS" + str( i + 1 ) +
3760 " has incorrect view" +
3761 " of set " + onosSetName + ":\n" +
3762 str( getResponses[ i ] ) )
3763 main.log.debug( "Expected: " + str( onosSet ) )
3764 main.log.debug( "Actual: " + str( current ) )
3765 getResults = main.FALSE
3766 else:
3767 # error, set is not a set
3768 main.log.error( "ONOS" + str( i + 1 ) +
3769 " has repeat elements in" +
3770 " set " + onosSetName + ":\n" +
3771 str( getResponses[ i ] ) )
3772 getResults = main.FALSE
3773 elif getResponses[ i ] == main.ERROR:
3774 getResults = main.FALSE
3775 sizeResponses = []
3776 threads = []
3777 for i in range( numControllers ):
3778 t = main.Thread( target=CLIs[i].setTestSize,
3779 name="setTestSize-" + str( i ),
3780 args=[ onosSetName ] )
3781 threads.append( t )
3782 t.start()
3783 for t in threads:
3784 t.join()
3785 sizeResponses.append( t.result )
3786 sizeResults = main.TRUE
3787 for i in range( numControllers ):
3788 if size != sizeResponses[ i ]:
3789 sizeResults = main.FALSE
3790 main.log.error( "ONOS" + str( i + 1 ) +
3791 " expected a size of " +
3792 str( size ) + " for set " + onosSetName +
3793 " but got " + str( sizeResponses[ i ] ) )
3794 retainResults = retainResults and getResults and sizeResults
3795 utilities.assert_equals( expect=main.TRUE,
3796 actual=retainResults,
3797 onpass="Set retain correct",
3798 onfail="Set retain was incorrect" )
3799