blob: 50bf06fc63ae209b885f0fd864450364cae317ba [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070021CASE16: Install Distributed Primitives app
22CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080023"""
Jon Hall8f89dda2015-01-22 16:03:33 -080024
25
Jon Hall73cf9cc2014-11-20 22:28:38 -080026class HATestClusterRestart:
27
Jon Hall6aec96b2015-01-19 14:49:31 -080028 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080029 self.default = ''
30
Jon Hall6aec96b2015-01-19 14:49:31 -080031 def CASE1( self, main ):
32 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080033 CASE1 is to compile ONOS and push it to the test machines
34
35 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080036 cell <name>
37 onos-verify-cell
38 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080039 onos-uninstall
40 start mininet
41 git pull
42 mvn clean install
43 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080044 onos-install -f
45 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080046 start cli sessions
47 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080048 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070049 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
Jon Hall6aec96b2015-01-19 14:49:31 -080050 "initialization" )
51 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070052 main.caseExplaination = "Setup the test environment including " +\
53 "installing ONOS, starting Mininet and ONOS" +\
54 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080055 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080056
Jon Hall5cfd23c2015-03-19 11:40:57 -070057 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080058 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080059 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080060 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080061 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080062 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080063
64 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS7Port
72 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080073 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080074
Jon Hall5cfd23c2015-03-19 11:40:57 -070075 # FIXME: just get controller port from params?
76 # TODO: do we really need all these?
77 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
78 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
79 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
80 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
81 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
82 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
83 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
84
85 global CLIs
86 CLIs = []
87 global nodes
88 nodes = []
89 for i in range( 1, numControllers + 1 ):
90 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
91 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
92
Jon Hall6aec96b2015-01-19 14:49:31 -080093 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080094 cellResult = main.ONOSbench.setCell( cellName )
95 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080096
Jon Hall6aec96b2015-01-19 14:49:31 -080097 # FIXME:this is short term fix
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 Hall1b8f54a2015-02-04 13:24:20 -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 = "HAClusterRestart"
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 Hall58c76b72015-02-23 11:09:24 -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 Hallfeff3082015-05-19 10:23:26 -0700405 # NOTE: we must reinstall intents until we have a persistant intent
406 # datastore!
Jon Hall6aec96b2015-01-19 14:49:31 -0800407 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700408 main.caseExplaination = "Discover hosts by using pingall then " +\
409 "assign predetermined host-to-host intents." +\
410 " After installation, check that the intent" +\
411 " is distributed to all nodes and the state" +\
412 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800413
Jon Hall6aec96b2015-01-19 14:49:31 -0800414 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700415 main.step( "Install reactive forwarding app" )
416 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
417 utilities.assert_equals( expect=main.TRUE, actual=installResults,
418 onpass="Install fwd successful",
419 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700420
Jon Hallfeff3082015-05-19 10:23:26 -0700421 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700422 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700423 threads = []
424 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700425 t = main.Thread( target=CLIs[i].appToIDCheck,
426 name="appToIDCheck-" + str( i ),
427 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700428 threads.append( t )
429 t.start()
430
431 for t in threads:
432 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700433 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700434 if appCheck != main.TRUE:
435 main.log.warn( CLIs[0].apps() )
436 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700437 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
438 onpass="App Ids seem to be correct",
439 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800440
Jon Hallfeff3082015-05-19 10:23:26 -0700441 main.step( "Discovering Hosts( Via pingall for now )" )
442 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800443 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800444 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700445 for i in range(2): # Retry if pingall fails first time
446 time1 = time.time()
447 pingResult = main.Mininet1.pingall()
448 utilities.assert_equals(
449 expect=main.TRUE,
450 actual=pingResult,
451 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700452 onfail="Reactive Pingall failed, " +
453 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700454 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700455 main.log.info( "Time for pingall: %2f seconds" %
456 ( time2 - time1 ) )
457 # timeout for fwd flows
458 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800459 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700460 main.step( "Uninstall reactive forwarding app" )
461 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
462 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
463 onpass="Uninstall fwd successful",
464 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700465
466 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700467 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700468 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700469 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700470 t = main.Thread( target=CLIs[i].appToIDCheck,
471 name="appToIDCheck-" + str( i ),
472 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700473 threads.append( t )
474 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800475
Jon Hall5cfd23c2015-03-19 11:40:57 -0700476 for t in threads:
477 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700478 appCheck2 = appCheck2 and t.result
479 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700480 main.log.warn( CLIs[0].apps() )
481 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700482 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700483 onpass="App Ids seem to be correct",
484 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700485
Jon Hallfeff3082015-05-19 10:23:26 -0700486 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800487 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800488 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800489 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800490 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800491 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800492 for i in range( 8, 18 ):
493 main.log.info( "Adding host intent between h" + str( i ) +
494 " and h" + str( i + 10 ) )
495 host1 = "00:00:00:00:00:" + \
496 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
497 host2 = "00:00:00:00:00:" + \
498 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800499 # NOTE: getHost can return None
500 host1Dict = main.ONOScli1.getHost( host1 )
501 host2Dict = main.ONOScli1.getHost( host2 )
502 host1Id = None
503 host2Id = None
504 if host1Dict and host2Dict:
505 host1Id = host1Dict.get( 'id', None )
506 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800507 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700508 nodeNum = ( i % 7 )
509 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800510 if tmpId:
511 main.log.info( "Added intent with id: " + tmpId )
512 intentIds.append( tmpId )
513 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700514 main.log.error( "addHostIntent returned: " +
515 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800516 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700517 main.log.error( "Error, getHost() failed for h" + str( i ) +
518 " and/or h" + str( i + 10 ) )
519 hosts = CLIs[ 0 ].hosts()
520 main.log.warn( "Hosts output: " )
521 try:
522 main.log.warn( json.dumps( json.loads( hosts ),
523 sort_keys=True,
524 indent=4,
525 separators=( ',', ': ' ) ) )
526 except ( ValueError, TypeError ):
527 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800528 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700529 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
530 onpass="Found a host id for each host",
531 onfail="Error looking up host ids" )
532
Jon Halla9d26da2015-03-30 16:45:32 -0700533 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800534 onosIds = main.ONOScli1.getAllIntentsId()
535 main.log.info( "Submitted intents: " + str( intentIds ) )
536 main.log.info( "Intents in ONOS: " + str( onosIds ) )
537 for intent in intentIds:
538 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700539 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800540 else:
541 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700542 if intentAddResult:
543 intentStop = time.time()
544 else:
545 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800546 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800547 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800548 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800549 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800550 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
551 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700552 try:
553 for intent in json.loads( intents ):
554 state = intent.get( 'state', None )
555 if "INSTALLED" not in state:
556 installedCheck = False
557 intentId = intent.get( 'id', None )
558 intentStates.append( ( intentId, state ) )
559 except ( ValueError, TypeError ):
560 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800561 # add submitted intents not in the store
562 tmplist = [ i for i, s in intentStates ]
563 missingIntents = False
564 for i in intentIds:
565 if i not in tmplist:
566 intentStates.append( ( i, " - " ) )
567 missingIntents = True
568 intentStates.sort()
569 for i, s in intentStates:
570 count += 1
571 main.log.info( "%-6s%-15s%-15s" %
572 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700573 leaders = main.ONOScli1.leaders()
574 try:
575 if leaders:
576 parsedLeaders = json.loads( leaders )
577 main.log.warn( json.dumps( parsedLeaders,
578 sort_keys=True,
579 indent=4,
580 separators=( ',', ': ' ) ) )
581 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700582 topics = []
583 for i in range( 14 ):
584 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700585 main.log.debug( topics )
586 ONOStopics = [ j['topic'] for j in parsedLeaders ]
587 for topic in topics:
588 if topic not in ONOStopics:
589 main.log.error( "Error: " + topic +
590 " not in leaders" )
591 else:
592 main.log.error( "leaders() returned None" )
593 except ( ValueError, TypeError ):
594 main.log.exception( "Error parsing leaders" )
595 main.log.error( repr( leaders ) )
596 partitions = main.ONOScli1.partitions()
597 try:
598 if partitions :
599 parsedPartitions = json.loads( partitions )
600 main.log.warn( json.dumps( parsedPartitions,
601 sort_keys=True,
602 indent=4,
603 separators=( ',', ': ' ) ) )
604 # TODO check for a leader in all paritions
605 # TODO check for consistency among nodes
606 else:
607 main.log.error( "partitions() returned None" )
608 except ( ValueError, TypeError ):
609 main.log.exception( "Error parsing partitions" )
610 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800611 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700612 try:
613 if pendingMap :
614 parsedPending = json.loads( pendingMap )
615 main.log.warn( json.dumps( parsedPending,
616 sort_keys=True,
617 indent=4,
618 separators=( ',', ': ' ) ) )
619 # TODO check something here?
620 else:
621 main.log.error( "pendingMap() returned None" )
622 except ( ValueError, TypeError ):
623 main.log.exception( "Error parsing pending map" )
624 main.log.error( repr( pendingMap ) )
625
Jon Hallfeff3082015-05-19 10:23:26 -0700626 intentAddResult = bool( intentAddResult and not missingIntents and
627 installedCheck )
628 if not intentAddResult:
629 main.log.error( "Error in pushing host intents to ONOS" )
630
Jon Hall390696c2015-05-05 17:13:41 -0700631 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700632 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700633 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700634 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700635 for cli in CLIs:
636 onosIds = []
637 ids = cli.getAllIntentsId()
638 onosIds.append( ids )
639 main.log.debug( "Intents in " + cli.name + ": " +
640 str( sorted( onosIds ) ) )
641 if sorted( ids ) != sorted( intentIds ):
Jon Hall40d2cbd2015-06-03 16:24:29 -0700642 # IF intents are missing
Jon Hall390696c2015-05-05 17:13:41 -0700643 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700644 break
645 else:
646 intents = json.loads( cli.intents() )
647 for intent in intents:
648 if intent[ 'state' ] != "INSTALLED":
649 correct = False
650 break
Jon Hall390696c2015-05-05 17:13:41 -0700651 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700652 break
653 else:
654 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700655 if not intentStop:
656 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700657 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700658 gossipTime = intentStop - intentStart
659 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700660 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700661 # FIXME: make this time configurable/calculate based off of number of
662 # nodes and gossip rounds
663 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700664 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700665 onpass="ECM anti-entropy for intents worked within " +
666 "expected time",
667 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700668 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700669 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800670
Jon Hall63604932015-02-26 17:09:50 -0800671 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800672 import time
Jon Hall63604932015-02-26 17:09:50 -0800673 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800674 main.log.info( "Sleeping 60 seconds to see if intents are found" )
675 time.sleep( 60 )
676 onosIds = main.ONOScli1.getAllIntentsId()
677 main.log.info( "Submitted intents: " + str( intentIds ) )
678 main.log.info( "Intents in ONOS: " + str( onosIds ) )
679 # Print the intent states
680 intents = main.ONOScli1.intents()
681 intentStates = []
682 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
683 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700684 try:
685 for intent in json.loads( intents ):
686 # Iter through intents of a node
687 state = intent.get( 'state', None )
688 if "INSTALLED" not in state:
689 installedCheck = False
690 intentId = intent.get( 'id', None )
691 intentStates.append( ( intentId, state ) )
692 except ( ValueError, TypeError ):
693 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800694 # add submitted intents not in the store
695 tmplist = [ i for i, s in intentStates ]
696 for i in intentIds:
697 if i not in tmplist:
698 intentStates.append( ( i, " - " ) )
699 intentStates.sort()
700 for i, s in intentStates:
701 count += 1
702 main.log.info( "%-6s%-15s%-15s" %
703 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700704 leaders = main.ONOScli1.leaders()
705 try:
706 if leaders:
707 parsedLeaders = json.loads( leaders )
708 main.log.warn( json.dumps( parsedLeaders,
709 sort_keys=True,
710 indent=4,
711 separators=( ',', ': ' ) ) )
712 # check for all intent partitions
713 # check for election
714 topics = []
715 for i in range( 14 ):
716 topics.append( "intent-partition-" + str( i ) )
717 # FIXME: this should only be after we start the app
718 topics.append( "org.onosproject.election" )
719 main.log.debug( topics )
720 ONOStopics = [ j['topic'] for j in parsedLeaders ]
721 for topic in topics:
722 if topic not in ONOStopics:
723 main.log.error( "Error: " + topic +
724 " not in leaders" )
725 else:
726 main.log.error( "leaders() returned None" )
727 except ( ValueError, TypeError ):
728 main.log.exception( "Error parsing leaders" )
729 main.log.error( repr( leaders ) )
730 partitions = main.ONOScli1.partitions()
731 try:
732 if partitions :
733 parsedPartitions = json.loads( partitions )
734 main.log.warn( json.dumps( parsedPartitions,
735 sort_keys=True,
736 indent=4,
737 separators=( ',', ': ' ) ) )
738 # TODO check for a leader in all paritions
739 # TODO check for consistency among nodes
740 else:
741 main.log.error( "partitions() returned None" )
742 except ( ValueError, TypeError ):
743 main.log.exception( "Error parsing partitions" )
744 main.log.error( repr( partitions ) )
745 pendingMap = main.ONOScli1.pendingMap()
746 try:
747 if pendingMap :
748 parsedPending = json.loads( pendingMap )
749 main.log.warn( json.dumps( parsedPending,
750 sort_keys=True,
751 indent=4,
752 separators=( ',', ': ' ) ) )
753 # TODO check something here?
754 else:
755 main.log.error( "pendingMap() returned None" )
756 except ( ValueError, TypeError ):
757 main.log.exception( "Error parsing pending map" )
758 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800759
Jon Hall6aec96b2015-01-19 14:49:31 -0800760 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800761 """
762 Ping across added host intents
763 """
Jon Hall58c76b72015-02-23 11:09:24 -0800764 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700765 import time
766 assert numControllers, "numControllers not defined"
767 assert main, "main not defined"
768 assert utilities.assert_equals, "utilities.assert_equals not defined"
769 assert CLIs, "CLIs not defined"
770 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700771 main.case( "Verify connectivity by sendind traffic across Intents" )
772 main.caseExplaination = "Ping across added host intents to check " +\
773 "functionality and check the state of " +\
774 "the intent"
775 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800776 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800777 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800778 ping = main.Mininet1.pingHost( src="h" + str( i ),
779 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800780 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800781 if ping == main.FALSE:
782 main.log.warn( "Ping failed between h" + str( i ) +
783 " and h" + str( i + 10 ) )
784 elif ping == main.TRUE:
785 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800786 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800787 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700788 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800789 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800790 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700791 main.log.warn( "ONOS1 intents: " )
792 try:
793 tmpIntents = main.ONOScli1.intents()
794 main.log.warn( json.dumps( json.loads( tmpIntents ),
795 sort_keys=True,
796 indent=4,
797 separators=( ',', ': ' ) ) )
798 except ( ValueError, TypeError ):
799 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800800 utilities.assert_equals(
801 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800802 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800803 onpass="Intents have been installed correctly and pings work",
804 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800805
Jon Hallfeff3082015-05-19 10:23:26 -0700806 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700807 installedCheck = False
Jon Hallfeff3082015-05-19 10:23:26 -0700808 count = 0
Jon Hall40d2cbd2015-06-03 16:24:29 -0700809 while not installedCheck and count < 40:
810 installedCheck = True
811 # Print the intent states
812 intents = main.ONOScli1.intents()
813 intentStates = []
814 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
815 count = 0
816 # Iter through intents of a node
817 try:
818 for intent in json.loads( intents ):
819 state = intent.get( 'state', None )
820 if "INSTALLED" not in state:
821 installedCheck = False
822 intentId = intent.get( 'id', None )
823 intentStates.append( ( intentId, state ) )
824 except ( ValueError, TypeError ):
825 main.log.exception( "Error parsing intents." )
826 # Print states
827 intentStates.sort()
828 for i, s in intentStates:
829 count += 1
830 main.log.info( "%-6s%-15s%-15s" %
831 ( str( count ), str( i ), str( s ) ) )
832 if not installedCheck:
833 time.sleep( 1 )
834 count += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700835 utilities.assert_equals( expect=True, actual=installedCheck,
836 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700837 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700838 "INSTALLED state" )
839
840 main.step( "Check leadership of topics" )
841 leaders = main.ONOScli1.leaders()
842 topicCheck = main.TRUE
843 try:
844 if leaders:
845 parsedLeaders = json.loads( leaders )
846 main.log.warn( json.dumps( parsedLeaders,
847 sort_keys=True,
848 indent=4,
849 separators=( ',', ': ' ) ) )
850 # check for all intent partitions
851 # check for election
852 # TODO: Look at Devices as topics now that it uses this system
853 topics = []
854 for i in range( 14 ):
855 topics.append( "intent-partition-" + str( i ) )
856 # FIXME: this should only be after we start the app
857 # FIXME: topics.append( "org.onosproject.election" )
858 # Print leaders output
859 main.log.debug( topics )
860 ONOStopics = [ j['topic'] for j in parsedLeaders ]
861 for topic in topics:
862 if topic not in ONOStopics:
863 main.log.error( "Error: " + topic +
864 " not in leaders" )
865 topicCheck = main.FALSE
866 else:
867 main.log.error( "leaders() returned None" )
868 topicCheck = main.FALSE
869 except ( ValueError, TypeError ):
870 topicCheck = main.FALSE
871 main.log.exception( "Error parsing leaders" )
872 main.log.error( repr( leaders ) )
873 # TODO: Check for a leader of these topics
874 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
875 onpass="intent Partitions is in leaders",
876 onfail="Some topics were lost " )
877 # Print partitions
878 partitions = main.ONOScli1.partitions()
879 try:
880 if partitions :
881 parsedPartitions = json.loads( partitions )
882 main.log.warn( json.dumps( parsedPartitions,
883 sort_keys=True,
884 indent=4,
885 separators=( ',', ': ' ) ) )
886 # TODO check for a leader in all paritions
887 # TODO check for consistency among nodes
888 else:
889 main.log.error( "partitions() returned None" )
890 except ( ValueError, TypeError ):
891 main.log.exception( "Error parsing partitions" )
892 main.log.error( repr( partitions ) )
893 # Print Pending Map
894 pendingMap = main.ONOScli1.pendingMap()
895 try:
896 if pendingMap :
897 parsedPending = json.loads( pendingMap )
898 main.log.warn( json.dumps( parsedPending,
899 sort_keys=True,
900 indent=4,
901 separators=( ',', ': ' ) ) )
902 # TODO check something here?
903 else:
904 main.log.error( "pendingMap() returned None" )
905 except ( ValueError, TypeError ):
906 main.log.exception( "Error parsing pending map" )
907 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700908 main.log.info( "Waiting 60 seconds to see if the state of " +
909 "intents change" )
910 time.sleep( 60 )
Jon Hall63604932015-02-26 17:09:50 -0800911 if not installedCheck:
Jon Hall63604932015-02-26 17:09:50 -0800912 # Print the intent states
913 intents = main.ONOScli1.intents()
914 intentStates = []
915 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
916 count = 0
917 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700918 try:
919 for intent in json.loads( intents ):
920 state = intent.get( 'state', None )
921 if "INSTALLED" not in state:
922 installedCheck = False
923 intentId = intent.get( 'id', None )
924 intentStates.append( ( intentId, state ) )
925 except ( ValueError, TypeError ):
926 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800927 intentStates.sort()
928 for i, s in intentStates:
929 count += 1
930 main.log.info( "%-6s%-15s%-15s" %
931 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700932 leaders = main.ONOScli1.leaders()
933 try:
934 if leaders:
935 parsedLeaders = json.loads( leaders )
936 main.log.warn( json.dumps( parsedLeaders,
937 sort_keys=True,
938 indent=4,
939 separators=( ',', ': ' ) ) )
940 # check for all intent partitions
941 # check for election
942 topics = []
943 for i in range( 14 ):
944 topics.append( "intent-partition-" + str( i ) )
945 # FIXME: this should only be after we start the app
946 topics.append( "org.onosproject.election" )
947 main.log.debug( topics )
948 ONOStopics = [ j['topic'] for j in parsedLeaders ]
949 for topic in topics:
950 if topic not in ONOStopics:
951 main.log.error( "Error: " + topic +
952 " not in leaders" )
953 else:
954 main.log.error( "leaders() returned None" )
955 except ( ValueError, TypeError ):
956 main.log.exception( "Error parsing leaders" )
957 main.log.error( repr( leaders ) )
958 partitions = main.ONOScli1.partitions()
959 try:
960 if partitions :
961 parsedPartitions = json.loads( partitions )
962 main.log.warn( json.dumps( parsedPartitions,
963 sort_keys=True,
964 indent=4,
965 separators=( ',', ': ' ) ) )
966 # TODO check for a leader in all paritions
967 # TODO check for consistency among nodes
968 else:
969 main.log.error( "partitions() returned None" )
970 except ( ValueError, TypeError ):
971 main.log.exception( "Error parsing partitions" )
972 main.log.error( repr( partitions ) )
973 pendingMap = main.ONOScli1.pendingMap()
974 try:
975 if pendingMap :
976 parsedPending = json.loads( pendingMap )
977 main.log.warn( json.dumps( parsedPending,
978 sort_keys=True,
979 indent=4,
980 separators=( ',', ': ' ) ) )
981 # TODO check something here?
982 else:
983 main.log.error( "pendingMap() returned None" )
984 except ( ValueError, TypeError ):
985 main.log.exception( "Error parsing pending map" )
986 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700987 # Print flowrules
988 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -0700989 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700990 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -0700991 PingResult = main.TRUE
992 for i in range( 8, 18 ):
993 ping = main.Mininet1.pingHost( src="h" + str( i ),
994 target="h" + str( i + 10 ) )
995 PingResult = PingResult and ping
996 if ping == main.FALSE:
997 main.log.warn( "Ping failed between h" + str( i ) +
998 " and h" + str( i + 10 ) )
999 elif ping == main.TRUE:
1000 main.log.info( "Ping test passed!" )
1001 # Don't set PingResult or you'd override failures
1002 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001003 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001004 "Intents have not been installed correctly, pings failed." )
1005 # TODO: pretty print
1006 main.log.warn( "ONOS1 intents: " )
1007 try:
1008 tmpIntents = main.ONOScli1.intents()
1009 main.log.warn( json.dumps( json.loads( tmpIntents ),
1010 sort_keys=True,
1011 indent=4,
1012 separators=( ',', ': ' ) ) )
1013 except ( ValueError, TypeError ):
1014 main.log.warn( repr( tmpIntents ) )
1015 utilities.assert_equals(
1016 expect=main.TRUE,
1017 actual=PingResult,
1018 onpass="Intents have been installed correctly and pings work",
1019 onfail="Intents have not been installed correctly, pings failed." )
1020
Jon Hall6aec96b2015-01-19 14:49:31 -08001021 def CASE5( self, main ):
1022 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001023 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001024 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001025 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001026 import time
1027 assert numControllers, "numControllers not defined"
1028 assert main, "main not defined"
1029 assert utilities.assert_equals, "utilities.assert_equals not defined"
1030 assert CLIs, "CLIs not defined"
1031 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001032 # assumes that sts is already in you PYTHONPATH
1033 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001034
Jon Hall6aec96b2015-01-19 14:49:31 -08001035 main.case( "Setting up and gathering data for current state" )
1036 # The general idea for this test case is to pull the state of
1037 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001038 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001039
Jon Hall5cfd23c2015-03-19 11:40:57 -07001040 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001041 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001042 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001043
Jon Hall6aec96b2015-01-19 14:49:31 -08001044 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001045 rolesNotNull = main.TRUE
1046 threads = []
1047 for i in range( numControllers ):
1048 t = main.Thread( target=CLIs[i].rolesNotNull,
1049 name="rolesNotNull-" + str( i ),
1050 args=[] )
1051 threads.append( t )
1052 t.start()
1053
1054 for t in threads:
1055 t.join()
1056 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001057 utilities.assert_equals(
1058 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001059 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001060 onpass="Each device has a master",
1061 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001062
Jon Hall5cfd23c2015-03-19 11:40:57 -07001063 main.step( "Get the Mastership of each switch from each controller" )
1064 ONOSMastership = []
1065 mastershipCheck = main.FALSE
1066 consistentMastership = True
1067 rolesResults = True
1068 threads = []
1069 for i in range( numControllers ):
1070 t = main.Thread( target=CLIs[i].roles,
1071 name="roles-" + str( i ),
1072 args=[] )
1073 threads.append( t )
1074 t.start()
1075
1076 for t in threads:
1077 t.join()
1078 ONOSMastership.append( t.result )
1079
1080 for i in range( numControllers ):
1081 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001082 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001083 " roles" )
1084 main.log.warn(
1085 "ONOS" + str( i + 1 ) + " mastership response: " +
1086 repr( ONOSMastership[i] ) )
1087 rolesResults = False
1088 utilities.assert_equals(
1089 expect=True,
1090 actual=rolesResults,
1091 onpass="No error in reading roles output",
1092 onfail="Error in reading roles from ONOS" )
1093
1094 main.step( "Check for consistency in roles from each controller" )
1095 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001096 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001097 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001098 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001099 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001100 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001101 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001102 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001103 onpass="Switch roles are consistent across all ONOS nodes",
1104 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001105
Jon Hall5cfd23c2015-03-19 11:40:57 -07001106 if rolesResults and not consistentMastership:
1107 for i in range( numControllers ):
1108 try:
1109 main.log.warn(
1110 "ONOS" + str( i + 1 ) + " roles: ",
1111 json.dumps(
1112 json.loads( ONOSMastership[ i ] ),
1113 sort_keys=True,
1114 indent=4,
1115 separators=( ',', ': ' ) ) )
1116 except ( ValueError, TypeError ):
1117 main.log.warn( repr( ONOSMastership[ i ] ) )
1118 elif rolesResults and consistentMastership:
1119 mastershipCheck = main.TRUE
1120 mastershipState = ONOSMastership[ 0 ]
1121
Jon Hall6aec96b2015-01-19 14:49:31 -08001122 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001123 global intentState
1124 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001125 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001126 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001127 consistentIntents = True
1128 intentsResults = True
1129 threads = []
1130 for i in range( numControllers ):
1131 t = main.Thread( target=CLIs[i].intents,
1132 name="intents-" + str( i ),
1133 args=[],
1134 kwargs={ 'jsonFormat': True } )
1135 threads.append( t )
1136 t.start()
1137
1138 for t in threads:
1139 t.join()
1140 ONOSIntents.append( t.result )
1141
1142 for i in range( numControllers ):
1143 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001144 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001145 " intents" )
1146 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1147 repr( ONOSIntents[ i ] ) )
1148 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001149 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001150 expect=True,
1151 actual=intentsResults,
1152 onpass="No error in reading intents output",
1153 onfail="Error in reading intents from ONOS" )
1154
1155 main.step( "Check for consistency in Intents from each controller" )
1156 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001157 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001158 "nodes" )
1159 else:
1160 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001161 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001162 utilities.assert_equals(
1163 expect=True,
1164 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001165 onpass="Intents are consistent across all ONOS nodes",
1166 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001167
Jon Hall390696c2015-05-05 17:13:41 -07001168 if intentsResults:
1169 # Try to make it easy to figure out what is happening
1170 #
1171 # Intent ONOS1 ONOS2 ...
1172 # 0x01 INSTALLED INSTALLING
1173 # ... ... ...
1174 # ... ... ...
1175 title = " Id"
1176 for n in range( numControllers ):
1177 title += " " * 10 + "ONOS" + str( n + 1 )
1178 main.log.warn( title )
1179 # get all intent keys in the cluster
1180 keys = []
1181 for nodeStr in ONOSIntents:
1182 node = json.loads( nodeStr )
1183 for intent in node:
1184 keys.append( intent.get( 'id' ) )
1185 keys = set( keys )
1186 for key in keys:
1187 row = "%-13s" % key
1188 for nodeStr in ONOSIntents:
1189 node = json.loads( nodeStr )
1190 for intent in node:
1191 if intent.get( 'id', "Error" ) == key:
1192 row += "%-15s" % intent.get( 'state' )
1193 main.log.warn( row )
1194 # End table view
1195
Jon Hall5cfd23c2015-03-19 11:40:57 -07001196 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001197 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001198 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001199 main.log.debug( "ONOS" + str( n ) + " intents: " )
1200 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1201 sort_keys=True,
1202 indent=4,
1203 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001204 for i in range( numControllers ):
1205 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001206 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1207 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1208 sort_keys=True,
1209 indent=4,
1210 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001211 else:
Jon Hall390696c2015-05-05 17:13:41 -07001212 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1213 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001214 elif intentsResults and consistentIntents:
1215 intentCheck = main.TRUE
1216 intentState = ONOSIntents[ 0 ]
1217
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001219 global flowState
1220 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001221 ONOSFlows = []
1222 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001223 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001224 consistentFlows = True
1225 flowsResults = True
1226 threads = []
1227 for i in range( numControllers ):
1228 t = main.Thread( target=CLIs[i].flows,
1229 name="flows-" + str( i ),
1230 args=[],
1231 kwargs={ 'jsonFormat': True } )
1232 threads.append( t )
1233 t.start()
1234
Jon Halla9d26da2015-03-30 16:45:32 -07001235 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001236 time.sleep(30)
1237 for t in threads:
1238 t.join()
1239 result = t.result
1240 ONOSFlows.append( result )
1241
1242 for i in range( numControllers ):
1243 num = str( i + 1 )
1244 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001245 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001246 main.log.warn( "ONOS" + num + " flows response: " +
1247 repr( ONOSFlows[ i ] ) )
1248 flowsResults = False
1249 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001250 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001251 try:
1252 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1253 except ( ValueError, TypeError ):
1254 # FIXME: change this to log.error?
1255 main.log.exception( "Error in parsing ONOS" + num +
1256 " response as json." )
1257 main.log.error( repr( ONOSFlows[ i ] ) )
1258 ONOSFlowsJson.append( None )
1259 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001260 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001261 expect=True,
1262 actual=flowsResults,
1263 onpass="No error in reading flows output",
1264 onfail="Error in reading flows from ONOS" )
1265
1266 main.step( "Check for consistency in Flows from each controller" )
1267 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1268 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001269 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001270 else:
1271 consistentFlows = False
1272 utilities.assert_equals(
1273 expect=True,
1274 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001275 onpass="The flow count is consistent across all ONOS nodes",
1276 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001277
Jon Hall5cfd23c2015-03-19 11:40:57 -07001278 if flowsResults and not consistentFlows:
1279 for i in range( numControllers ):
1280 try:
1281 main.log.warn(
1282 "ONOS" + str( i + 1 ) + " flows: " +
1283 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1284 indent=4, separators=( ',', ': ' ) ) )
1285 except ( ValueError, TypeError ):
1286 main.log.warn(
1287 "ONOS" + str( i + 1 ) + " flows: " +
1288 repr( ONOSFlows[ i ] ) )
1289 elif flowsResults and consistentFlows:
1290 flowCheck = main.TRUE
1291 flowState = ONOSFlows[ 0 ]
1292
Jon Hall6aec96b2015-01-19 14:49:31 -08001293 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001294 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001295 flows = []
1296 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001297 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001298 if flowCheck == main.FALSE:
1299 for table in flows:
1300 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001301 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001302
Jon Hall6aec96b2015-01-19 14:49:31 -08001303 main.step( "Start continuous pings" )
1304 main.Mininet2.pingLong(
1305 src=main.params[ 'PING' ][ 'source1' ],
1306 target=main.params[ 'PING' ][ 'target1' ],
1307 pingTime=500 )
1308 main.Mininet2.pingLong(
1309 src=main.params[ 'PING' ][ 'source2' ],
1310 target=main.params[ 'PING' ][ 'target2' ],
1311 pingTime=500 )
1312 main.Mininet2.pingLong(
1313 src=main.params[ 'PING' ][ 'source3' ],
1314 target=main.params[ 'PING' ][ 'target3' ],
1315 pingTime=500 )
1316 main.Mininet2.pingLong(
1317 src=main.params[ 'PING' ][ 'source4' ],
1318 target=main.params[ 'PING' ][ 'target4' ],
1319 pingTime=500 )
1320 main.Mininet2.pingLong(
1321 src=main.params[ 'PING' ][ 'source5' ],
1322 target=main.params[ 'PING' ][ 'target5' ],
1323 pingTime=500 )
1324 main.Mininet2.pingLong(
1325 src=main.params[ 'PING' ][ 'source6' ],
1326 target=main.params[ 'PING' ][ 'target6' ],
1327 pingTime=500 )
1328 main.Mininet2.pingLong(
1329 src=main.params[ 'PING' ][ 'source7' ],
1330 target=main.params[ 'PING' ][ 'target7' ],
1331 pingTime=500 )
1332 main.Mininet2.pingLong(
1333 src=main.params[ 'PING' ][ 'source8' ],
1334 target=main.params[ 'PING' ][ 'target8' ],
1335 pingTime=500 )
1336 main.Mininet2.pingLong(
1337 src=main.params[ 'PING' ][ 'source9' ],
1338 target=main.params[ 'PING' ][ 'target9' ],
1339 pingTime=500 )
1340 main.Mininet2.pingLong(
1341 src=main.params[ 'PING' ][ 'source10' ],
1342 target=main.params[ 'PING' ][ 'target10' ],
1343 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001344
Jon Hall6aec96b2015-01-19 14:49:31 -08001345 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001346 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001347 for node in nodes:
1348 temp = ( node, node.name, node.ip_address, 6633 )
1349 ctrls.append( temp )
1350 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001351
Jon Hall6aec96b2015-01-19 14:49:31 -08001352 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001353 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001354 threads = []
1355 for i in range( numControllers ):
1356 t = main.Thread( target=CLIs[i].devices,
1357 name="devices-" + str( i ),
1358 args=[ ] )
1359 threads.append( t )
1360 t.start()
1361
1362 for t in threads:
1363 t.join()
1364 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001365 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001366 threads = []
1367 for i in range( numControllers ):
1368 t = main.Thread( target=CLIs[i].hosts,
1369 name="hosts-" + str( i ),
1370 args=[ ] )
1371 threads.append( t )
1372 t.start()
1373
1374 for t in threads:
1375 t.join()
1376 try:
1377 hosts.append( json.loads( t.result ) )
1378 except ( ValueError, TypeError ):
1379 # FIXME: better handling of this, print which node
1380 # Maybe use thread name?
1381 main.log.exception( "Error parsing json output of hosts" )
1382 # FIXME: should this be an empty json object instead?
1383 hosts.append( None )
1384
Jon Hall73cf9cc2014-11-20 22:28:38 -08001385 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001386 threads = []
1387 for i in range( numControllers ):
1388 t = main.Thread( target=CLIs[i].ports,
1389 name="ports-" + str( i ),
1390 args=[ ] )
1391 threads.append( t )
1392 t.start()
1393
1394 for t in threads:
1395 t.join()
1396 ports.append( t.result )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001397 try:
1398 # FIXME: DEBUG
1399 main.log.debug( json.dumps( json.loads( t.result ),
1400 sort_keys=True,
1401 indent=4,
1402 separators=( ',', ': ' ) ) )
1403 except:
1404 main.log.debug( repr( t.result ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001405 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001406 threads = []
1407 for i in range( numControllers ):
1408 t = main.Thread( target=CLIs[i].links,
1409 name="links-" + str( i ),
1410 args=[ ] )
1411 threads.append( t )
1412 t.start()
1413
1414 for t in threads:
1415 t.join()
1416 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001417 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001418 threads = []
1419 for i in range( numControllers ):
1420 t = main.Thread( target=CLIs[i].clusters,
1421 name="clusters-" + str( i ),
1422 args=[ ] )
1423 threads.append( t )
1424 t.start()
1425
1426 for t in threads:
1427 t.join()
1428 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001429 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001430
Jon Hall6aec96b2015-01-19 14:49:31 -08001431 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001432 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001433 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001434 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001435 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001436 if "Error" not in hosts[ controller ]:
1437 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001438 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001439 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001440 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001441 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001442 " is inconsistent with ONOS1" )
1443 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001444 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001445
1446 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001447 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001448 controllerStr )
1449 consistentHostsResult = main.FALSE
1450 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 " hosts response: " +
1452 repr( hosts[ controller ] ) )
1453 utilities.assert_equals(
1454 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001455 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001456 onpass="Hosts view is consistent across all ONOS nodes",
1457 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001458
Jon Hall390696c2015-05-05 17:13:41 -07001459 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001460 ipResult = main.TRUE
1461 for controller in range( 0, len( hosts ) ):
1462 controllerStr = str( controller + 1 )
1463 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001464 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001465 main.log.error( "DEBUG:Error with host ips on controller" +
1466 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001467 ipResult = main.FALSE
1468 utilities.assert_equals(
1469 expect=main.TRUE,
1470 actual=ipResult,
1471 onpass="The ips of the hosts aren't empty",
1472 onfail="The ip of at least one host is missing" )
1473
Jon Hall6aec96b2015-01-19 14:49:31 -08001474 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001475 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001476 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001477 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001478 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001479 if "Error" not in clusters[ controller ]:
1480 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001481 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001482 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001483 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001484 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001485 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001486
1487 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001488 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001489 "from ONOS" + controllerStr )
1490 consistentClustersResult = main.FALSE
1491 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001492 " clusters response: " +
1493 repr( clusters[ controller ] ) )
1494 utilities.assert_equals(
1495 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001496 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001497 onpass="Clusters view is consistent across all ONOS nodes",
1498 onfail="ONOS nodes have different views of clusters" )
1499 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001500 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001501 try:
1502 numClusters = len( json.loads( clusters[ 0 ] ) )
1503 except ( ValueError, TypeError ):
1504 main.log.exception( "Error parsing clusters[0]: " +
1505 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001506 clusterResults = main.FALSE
1507 if numClusters == 1:
1508 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001509 utilities.assert_equals(
1510 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001511 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001513 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001514
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001516 devicesResults = main.TRUE
1517 portsResults = main.TRUE
1518 linksResults = main.TRUE
1519 for controller in range( numControllers ):
1520 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001521 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001522 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001523 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001524 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001525 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001526 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001527 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001528 actual=currentDevicesResult,
1529 onpass="ONOS" + controllerStr +
1530 " Switches view is correct",
1531 onfail="ONOS" + controllerStr +
1532 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001533
Jon Hall6aec96b2015-01-19 14:49:31 -08001534 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001535 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001536 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001537 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001538 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001539 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001540 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001541 actual=currentPortsResult,
1542 onpass="ONOS" + controllerStr +
1543 " ports view is correct",
1544 onfail="ONOS" + controllerStr +
1545 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001546
Jon Hall6aec96b2015-01-19 14:49:31 -08001547 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001548 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001549 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001550 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001551 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001552 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001553 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001554 actual=currentLinksResult,
1555 onpass="ONOS" + controllerStr +
1556 " links view is correct",
1557 onfail="ONOS" + controllerStr +
1558 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001559
Jon Hall8f89dda2015-01-22 16:03:33 -08001560 devicesResults = devicesResults and currentDevicesResult
1561 portsResults = portsResults and currentPortsResult
1562 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001563
Jon Hall5cfd23c2015-03-19 11:40:57 -07001564 topoResult = ( devicesResults and portsResults and linksResults
1565 and consistentHostsResult and consistentClustersResult
1566 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001567 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001568 onpass="Topology Check Test successful",
1569 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001570
Jon Hall6aec96b2015-01-19 14:49:31 -08001571 def CASE6( self, main ):
1572 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001573 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001574 """
Jon Hallfeff3082015-05-19 10:23:26 -07001575 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001576 assert numControllers, "numControllers not defined"
1577 assert main, "main not defined"
1578 assert utilities.assert_equals, "utilities.assert_equals not defined"
1579 assert CLIs, "CLIs not defined"
1580 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001581
1582 # Reset non-persistent variables
1583 try:
1584 iCounterValue = 0
1585 except NameError:
1586 main.log.error( "iCounterValue not defined, setting to 0" )
1587 iCounterValue = 0
1588
Jon Hall5cfd23c2015-03-19 11:40:57 -07001589 main.case( "Restart entire ONOS cluster" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001590 # FIXME: DEBUG
1591 main.step( "Start Packet Capture MN" )
1592 main.Mininet2.startTcpdump(
1593 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
1594 + "-MN.pcap",
1595 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
1596 port=main.params[ 'MNtcpdump' ][ 'port' ] )
1597 # FIXME: DEBUG
1598
Jon Hall5cfd23c2015-03-19 11:40:57 -07001599 main.step( "Killing ONOS nodes" )
1600 killResults = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001601 killTime = time.time()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001602 for node in nodes:
1603 killed = main.ONOSbench.onosKill( node.ip_address )
1604 killResults = killResults and killed
Jon Hall390696c2015-05-05 17:13:41 -07001605 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1606 onpass="ONOS nodes killed",
1607 onfail="ONOS kill unsuccessful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001608
Jon Hall6aec96b2015-01-19 14:49:31 -08001609 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001610 for i in range( 2 ):
1611 onosIsupResult = main.TRUE
1612 for node in nodes:
1613 started = main.ONOSbench.isup( node.ip_address )
1614 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001615 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001616 onosIsupResult = onosIsupResult and started
1617 if onosIsupResult == main.TRUE:
1618 break
Jon Hall390696c2015-05-05 17:13:41 -07001619 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1620 onpass="ONOS restarted",
1621 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001622
Jon Hall5cfd23c2015-03-19 11:40:57 -07001623 main.log.step( "Starting ONOS CLI sessions" )
1624 cliResults = main.TRUE
1625 threads = []
1626 for i in range( numControllers ):
1627 t = main.Thread( target=CLIs[i].startOnosCli,
1628 name="startOnosCli-" + str( i ),
1629 args=[nodes[i].ip_address] )
1630 threads.append( t )
1631 t.start()
1632
1633 for t in threads:
1634 t.join()
1635 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -07001636 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1637 onpass="ONOS cli started",
1638 onfail="ONOS clis did not restart" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001639
Jon Hallfeff3082015-05-19 10:23:26 -07001640 # Grab the time of restart so we chan check how long the gossip
1641 # protocol has had time to work
1642 main.restartTime = time.time() - killTime
1643 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001644
Jon Hallfeff3082015-05-19 10:23:26 -07001645 # FIXME: revisit test plan for election with madan
1646 # Rerun for election on restarted nodes
Jon Hall40d2cbd2015-06-03 16:24:29 -07001647 runResults = main.TRUE
1648 for cli in CLIs:
1649 run = CLIs[0].electionTestRun()
1650 if run != main.TRUE:
1651 main.log.error( "Error running for election on " + cli.name )
1652 runResults = runResults and run
Jon Hallfeff3082015-05-19 10:23:26 -07001653 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1654 onpass="Reran for election",
1655 onfail="Failed to rerun for election" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001656
1657 # TODO: Make this configurable
Jon Hallfeff3082015-05-19 10:23:26 -07001658 time.sleep( 60 )
1659 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1660 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1661 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001662
Jon Hall6aec96b2015-01-19 14:49:31 -08001663 def CASE7( self, main ):
1664 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001665 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001666 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001667 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001668 assert numControllers, "numControllers not defined"
1669 assert main, "main not defined"
1670 assert utilities.assert_equals, "utilities.assert_equals not defined"
1671 assert CLIs, "CLIs not defined"
1672 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001673 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001674
Jon Hall5cfd23c2015-03-19 11:40:57 -07001675 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001676 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001677 rolesNotNull = main.TRUE
1678 threads = []
1679 for i in range( numControllers ):
1680 t = main.Thread( target=CLIs[i].rolesNotNull,
1681 name="rolesNotNull-" + str( i ),
1682 args=[ ] )
1683 threads.append( t )
1684 t.start()
1685
1686 for t in threads:
1687 t.join()
1688 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001689 utilities.assert_equals(
1690 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001691 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001692 onpass="Each device has a master",
1693 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001694
Jon Hall390696c2015-05-05 17:13:41 -07001695 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001696 ONOSMastership = []
1697 mastershipCheck = main.FALSE
1698 consistentMastership = True
1699 rolesResults = True
1700 threads = []
1701 for i in range( numControllers ):
1702 t = main.Thread( target=CLIs[i].roles,
1703 name="roles-" + str( i ),
1704 args=[] )
1705 threads.append( t )
1706 t.start()
1707
1708 for t in threads:
1709 t.join()
1710 ONOSMastership.append( t.result )
1711
1712 for i in range( numControllers ):
1713 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001714 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001715 " roles" )
1716 main.log.warn(
1717 "ONOS" + str( i + 1 ) + " mastership response: " +
1718 repr( ONOSMastership[i] ) )
1719 rolesResults = False
1720 utilities.assert_equals(
1721 expect=True,
1722 actual=rolesResults,
1723 onpass="No error in reading roles output",
1724 onfail="Error in reading roles from ONOS" )
1725
1726 main.step( "Check for consistency in roles from each controller" )
1727 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001728 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001729 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001730 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001731 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001732 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001733 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001734 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001735 onpass="Switch roles are consistent across all ONOS nodes",
1736 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001737
Jon Hall5cfd23c2015-03-19 11:40:57 -07001738 if rolesResults and not consistentMastership:
1739 for i in range( numControllers ):
1740 main.log.warn(
1741 "ONOS" + str( i + 1 ) + " roles: ",
1742 json.dumps(
1743 json.loads( ONOSMastership[ i ] ),
1744 sort_keys=True,
1745 indent=4,
1746 separators=( ',', ': ' ) ) )
1747 elif rolesResults and not consistentMastership:
1748 mastershipCheck = main.TRUE
1749
Jon Hallfeff3082015-05-19 10:23:26 -07001750 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001751 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001752 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001753 try:
1754 currentJson = json.loads( ONOSMastership[0] )
1755 oldJson = json.loads( mastershipState )
1756 except ( ValueError, TypeError ):
1757 main.log.exception( "Something is wrong with parsing " +
1758 "ONOSMastership[0] or mastershipState" )
1759 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1760 main.log.error( "mastershipState" + repr( mastershipState ) )
1761 main.cleanup()
1762 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001763 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001764 for i in range( 1, 29 ):
1765 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001766 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001767 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001768 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001769 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001770 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001771 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001772 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001773 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001774 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001775 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001776 utilities.assert_equals(
1777 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001778 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001779 onpass="Mastership of Switches was not changed",
1780 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001781 '''
Jon Hall6aec96b2015-01-19 14:49:31 -08001782 # NOTE: we expect mastership to change on controller failure
Jon Hall73cf9cc2014-11-20 22:28:38 -08001783
Jon Hall6aec96b2015-01-19 14:49:31 -08001784 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001785 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001786 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001787 consistentIntents = True
1788 intentsResults = True
1789 threads = []
1790 for i in range( numControllers ):
1791 t = main.Thread( target=CLIs[i].intents,
1792 name="intents-" + str( i ),
1793 args=[],
1794 kwargs={ 'jsonFormat': True } )
1795 threads.append( t )
1796 t.start()
1797
1798 for t in threads:
1799 t.join()
1800 ONOSIntents.append( t.result )
1801
1802 for i in range( numControllers ):
1803 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001804 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001805 " intents" )
1806 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1807 repr( ONOSIntents[ i ] ) )
1808 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001809 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001810 expect=True,
1811 actual=intentsResults,
1812 onpass="No error in reading intents output",
1813 onfail="Error in reading intents from ONOS" )
1814
1815 main.step( "Check for consistency in Intents from each controller" )
1816 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001817 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001818 "nodes" )
1819 else:
1820 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001821
1822 # Try to make it easy to figure out what is happening
1823 #
1824 # Intent ONOS1 ONOS2 ...
1825 # 0x01 INSTALLED INSTALLING
1826 # ... ... ...
1827 # ... ... ...
1828 title = " ID"
1829 for n in range( numControllers ):
1830 title += " " * 10 + "ONOS" + str( n + 1 )
1831 main.log.warn( title )
1832 # get all intent keys in the cluster
1833 keys = []
1834 for nodeStr in ONOSIntents:
1835 node = json.loads( nodeStr )
1836 for intent in node:
1837 keys.append( intent.get( 'id' ) )
1838 keys = set( keys )
1839 for key in keys:
1840 row = "%-13s" % key
1841 for nodeStr in ONOSIntents:
1842 node = json.loads( nodeStr )
1843 for intent in node:
1844 if intent.get( 'id' ) == key:
1845 row += "%-15s" % intent.get( 'state' )
1846 main.log.warn( row )
1847 # End table view
1848
Jon Hall5cfd23c2015-03-19 11:40:57 -07001849 utilities.assert_equals(
1850 expect=True,
1851 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001852 onpass="Intents are consistent across all ONOS nodes",
1853 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001854 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001855 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001856 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001857 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001858 try:
1859 for intent in json.loads( node ):
1860 nodeStates.append( intent[ 'state' ] )
1861 except ( ValueError, TypeError ):
1862 main.log.exception( "Error in parsing intents" )
1863 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001864 intentStates.append( nodeStates )
1865 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1866 main.log.info( dict( out ) )
1867
Jon Hall5cfd23c2015-03-19 11:40:57 -07001868 if intentsResults and not consistentIntents:
1869 for i in range( numControllers ):
1870 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1871 main.log.warn( json.dumps(
1872 json.loads( ONOSIntents[ i ] ),
1873 sort_keys=True,
1874 indent=4,
1875 separators=( ',', ': ' ) ) )
1876 elif intentsResults and consistentIntents:
1877 intentCheck = main.TRUE
1878
Jon Hall58c76b72015-02-23 11:09:24 -08001879 # NOTE: Store has no durability, so intents are lost across system
1880 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001881 """
1882 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001883 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001884 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001885 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001886 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001887 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001888 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001890 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001891 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1892 sameIntents = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001893 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001894 before = json.loads( intentState )
1895 after = json.loads( ONOSIntents[ 0 ] )
1896 for intent in before:
1897 if intent not in after:
1898 sameIntents = main.FALSE
1899 main.log.debug( "Intent is not currently in ONOS " +\
1900 "(at least in the same form):" )
1901 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001902 except ( ValueError, TypeError ):
1903 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001904 main.log.debug( repr( ONOSIntents[0] ) )
1905 main.log.debug( repr( intentState ) )
1906 if sameIntents == main.FALSE:
1907 try:
1908 main.log.debug( "ONOS intents before: " )
1909 main.log.debug( json.dumps( json.loads( intentState ),
1910 sort_keys=True, indent=4,
1911 separators=( ',', ': ' ) ) )
1912 main.log.debug( "Current ONOS intents: " )
1913 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1914 sort_keys=True, indent=4,
1915 separators=( ',', ': ' ) ) )
1916 except ( ValueError, TypeError ):
1917 main.log.exception( "Exception printing intents" )
1918 main.log.debug( repr( ONOSIntents[0] ) )
1919 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001920 utilities.assert_equals(
1921 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001922 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001923 onpass="Intents are consistent with before failure",
1924 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001925 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08001926 """
1927 main.step( "Get the OF Table entries and compare to before " +
1928 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001929 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001930 flows2 = []
1931 for i in range( 28 ):
1932 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001933 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1934 flows2.append( tmpFlows )
1935 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001936 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001937 flow2=tmpFlows )
1938 FlowTables = FlowTables and tempResult
1939 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001940 main.log.info( "Differences in flow table for switch: s" +
1941 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001942 utilities.assert_equals(
1943 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001944 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001945 onpass="No changes were found in the flow tables",
1946 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001947
Jon Hall40d2cbd2015-06-03 16:24:29 -07001948 # main.step( "Check the continuous pings to ensure that no packets " +
1949 # "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001950 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1951 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001952 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001953 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1954 for i in range( 8, 18 ):
1955 main.log.info(
1956 "Checking for a loss in pings along flow from s" +
1957 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001958 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001959 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001960 str( i ) ) or LossInPings
1961 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001962 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001963 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001964 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001965 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001966 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001967 main.log.info( "No loss of dataplane connectivity" )
1968 # utilities.assert_equals(
1969 # expect=main.FALSE,
1970 # actual=LossInPings,
1971 # onpass="No Loss of connectivity",
1972 # onfail="Loss of dataplane connectivity detected" )
1973
Jon Hall58c76b72015-02-23 11:09:24 -08001974 # NOTE: Since intents are not persisted with IntnentStore,
1975 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08001976 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001977
Jon Hall390696c2015-05-05 17:13:41 -07001978 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001979 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001980 leaderList = []
1981 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001982 for cli in CLIs:
1983 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001984 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001985 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07001986 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001987 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001988 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001989 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001992 main.log.error( cli.name +
1993 " shows no leader for the election-app." )
Jon Hall8f89dda2015-01-22 16:03:33 -08001994 leaderResult = main.FALSE
1995 if len( set( leaderList ) ) != 1:
1996 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001997 main.log.error(
1998 "Inconsistent view of leader for the election test app" )
1999 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 utilities.assert_equals(
2001 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002002 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 onpass="Leadership election passed",
2004 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002005
Jon Hall6aec96b2015-01-19 14:49:31 -08002006 def CASE8( self, main ):
2007 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002008 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002009 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002010 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08002011 # FIXME add this path to params
2012 sys.path.append( "/home/admin/sts" )
2013 # assumes that sts is already in you PYTHONPATH
2014 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08002015 import json
2016 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002017 assert numControllers, "numControllers not defined"
2018 assert main, "main not defined"
2019 assert utilities.assert_equals, "utilities.assert_equals not defined"
2020 assert CLIs, "CLIs not defined"
2021 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002022
Jon Hallfeff3082015-05-19 10:23:26 -07002023 main.case( "Compare ONOS Topology view to Mininet topology" )
2024 main.caseExplaination = "Compare topology objects between Mininet" +\
2025 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08002026 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07002027 try:
2028 ctrls = []
2029 for node in nodes:
2030 temp = ( node, node.name, node.ip_address, 6633 )
2031 ctrls.append( temp )
2032 MNTopo = TestONTopology( main.Mininet1, ctrls )
2033 except Exception:
2034 objResult = main.FALSE
2035 else:
2036 objResult = main.TRUE
2037 utilities.assert_equals( expect=main.TRUE, actual=objResult,
2038 onpass="Created TestONTopology object",
2039 onfail="Exception while creating " +
2040 "TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002041
Jon Hallfeff3082015-05-19 10:23:26 -07002042 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002043 devicesResults = main.TRUE
2044 portsResults = main.TRUE
2045 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002046 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002047 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002048 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002049 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002050 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002051 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002052 # Give time for Gossip to work
Jon Hall40d2cbd2015-06-03 16:24:29 -07002053 while topoResult == main.FALSE and elapsed < 120:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002054 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08002055 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002056 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08002057 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002058 time.sleep( 1 )
Jon Hall8f89dda2015-01-22 16:03:33 -08002059 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002060 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002061 threads = []
2062 for i in range( numControllers ):
2063 t = main.Thread( target=CLIs[i].devices,
2064 name="devices-" + str( i ),
2065 args=[ ] )
2066 threads.append( t )
2067 t.start()
2068
2069 for t in threads:
2070 t.join()
2071 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002072 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002073 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002074 threads = []
2075 for i in range( numControllers ):
2076 t = main.Thread( target=CLIs[i].hosts,
2077 name="hosts-" + str( i ),
2078 args=[ ] )
2079 threads.append( t )
2080 t.start()
2081
2082 for t in threads:
2083 t.join()
2084 try:
2085 hosts.append( json.loads( t.result ) )
2086 except ( ValueError, TypeError ):
2087 main.log.exception( "Error parsing hosts results" )
2088 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002089 for controller in range( 0, len( hosts ) ):
2090 controllerStr = str( controller + 1 )
2091 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002092 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002093 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07002094 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002095 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002096 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002097 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002098 threads = []
2099 for i in range( numControllers ):
2100 t = main.Thread( target=CLIs[i].ports,
2101 name="ports-" + str( i ),
2102 args=[ ] )
2103 threads.append( t )
2104 t.start()
2105
2106 for t in threads:
2107 t.join()
2108 ports.append( t.result )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002109 try:
2110 # FIXME: DEBUG
2111 main.log.debug( json.dumps( json.loads( t.result ),
2112 sort_keys=True,
2113 indent=4,
2114 separators=( ',', ': ' ) ) )
2115 except:
2116 main.log.debug( repr( t.result ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002117 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002118 threads = []
2119 for i in range( numControllers ):
2120 t = main.Thread( target=CLIs[i].links,
2121 name="links-" + str( i ),
2122 args=[ ] )
2123 threads.append( t )
2124 t.start()
2125
2126 for t in threads:
2127 t.join()
2128 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002129 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002130 threads = []
2131 for i in range( numControllers ):
2132 t = main.Thread( target=CLIs[i].clusters,
2133 name="clusters-" + str( i ),
2134 args=[ ] )
2135 threads.append( t )
2136 t.start()
2137
2138 for t in threads:
2139 t.join()
2140 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002141
Jon Hall8f89dda2015-01-22 16:03:33 -08002142 elapsed = time.time() - startTime
2143 cliTime = time.time() - cliStart
Jon Hall40d2cbd2015-06-03 16:24:29 -07002144 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002145 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002146
Jon Hall8f89dda2015-01-22 16:03:33 -08002147 for controller in range( numControllers ):
2148 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002149 if devices[ controller ] or "Error" not in devices[
2150 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002151 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002152 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002153 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002154 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002155 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002156 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002157 actual=currentDevicesResult,
2158 onpass="ONOS" + controllerStr +
2159 " Switches view is correct",
2160 onfail="ONOS" + controllerStr +
2161 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002162
Jon Hall6aec96b2015-01-19 14:49:31 -08002163 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002164 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002165 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002166 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002167 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002168 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002169 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002170 actual=currentPortsResult,
2171 onpass="ONOS" + controllerStr +
2172 " ports view is correct",
2173 onfail="ONOS" + controllerStr +
2174 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002175
Jon Hall6aec96b2015-01-19 14:49:31 -08002176 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002177 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002178 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002179 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002180 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002181 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002182 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002183 actual=currentLinksResult,
2184 onpass="ONOS" + controllerStr +
2185 " links view is correct",
2186 onfail="ONOS" + controllerStr +
2187 " links view is incorrect" )
2188
2189 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2190 currentHostsResult = main.Mininet1.compareHosts(
2191 MNTopo, hosts[ controller ] )
2192 else:
2193 currentHostsResult = main.FALSE
2194 utilities.assert_equals( expect=main.TRUE,
2195 actual=currentHostsResult,
2196 onpass="ONOS" + controllerStr +
2197 " hosts exist in Mininet",
2198 onfail="ONOS" + controllerStr +
2199 " hosts don't match Mininet" )
2200
2201 devicesResults = devicesResults and currentDevicesResult
2202 portsResults = portsResults and currentPortsResult
2203 linksResults = linksResults and currentLinksResult
2204 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002205
Jon Hall529a37f2015-01-28 10:02:00 -08002206 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002207
Jon Hall6aec96b2015-01-19 14:49:31 -08002208 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002209 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002210 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002211 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002212 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002213 if "Error" not in hosts[ controller ]:
2214 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002215 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002216 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07002217 main.log.error( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002218 " is inconsistent with ONOS1" )
2219 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002220 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002221
2222 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002223 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002224 controllerStr )
2225 consistentHostsResult = main.FALSE
2226 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002227 " hosts response: " +
2228 repr( hosts[ controller ] ) )
2229 utilities.assert_equals(
2230 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002231 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002232 onpass="Hosts view is consistent across all ONOS nodes",
2233 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002234
Jon Hall6aec96b2015-01-19 14:49:31 -08002235 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002236 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002237 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002238 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002239 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002240 if "Error" not in clusters[ controller ]:
2241 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002242 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002243 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07002244 main.log.error( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002245 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002246 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002247 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002248
2249 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002250 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002251 "from ONOS" + controllerStr )
2252 consistentClustersResult = main.FALSE
2253 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002254 " clusters response: " +
2255 repr( clusters[ controller ] ) )
2256 utilities.assert_equals(
2257 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002258 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002259 onpass="Clusters view is consistent across all ONOS nodes",
2260 onfail="ONOS nodes have different views of clusters" )
2261 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002262 main.step( "Topology view is correct and consistent across all " +
2263 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002264 try:
2265 numClusters = len( json.loads( clusters[ 0 ] ) )
2266 except ( ValueError, TypeError ):
2267 main.log.exception( "Error parsing clusters[0]: " +
2268 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002269 clusterResults = main.FALSE
2270 if numClusters == 1:
2271 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002272 utilities.assert_equals(
2273 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002274 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002275 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002276 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002277
Jon Hall8f89dda2015-01-22 16:03:33 -08002278 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002279 and hostsResults and consistentHostsResult
2280 and consistentClustersResult and clusterResults
2281 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002282
Jon Hall8f89dda2015-01-22 16:03:33 -08002283 topoResult = topoResult and int( count <= 2 )
2284 note = "note it takes about " + str( int( cliTime ) ) + \
2285 " seconds for the test to make all the cli calls to fetch " +\
2286 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002287 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002288 "Very crass estimate for topology discovery/convergence( " +
2289 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002290 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002291 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002292 onpass="Topology Check Test successful",
2293 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002294
Jon Halla9d26da2015-03-30 16:45:32 -07002295 # FIXME: move this to an ONOS state case
2296 main.step( "Checking ONOS nodes" )
2297 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002298 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002299 threads = []
2300 for i in range( numControllers ):
2301 t = main.Thread( target=CLIs[i].nodes,
2302 name="nodes-" + str( i ),
2303 args=[ ] )
2304 threads.append( t )
2305 t.start()
2306
2307 for t in threads:
2308 t.join()
2309 nodesOutput.append( t.result )
2310 ips = [ node.ip_address for node in nodes ]
2311 for i in nodesOutput:
2312 try:
2313 current = json.loads( i )
2314 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002315 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002316 if node['ip'] in ips: # node in nodes() output is in cell
2317 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002318 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002319 else:
2320 main.log.error( "Error in ONOS node availability" )
2321 main.log.error(
2322 json.dumps( current,
2323 sort_keys=True,
2324 indent=4,
2325 separators=( ',', ': ' ) ) )
2326 break
Jon Hall390696c2015-05-05 17:13:41 -07002327 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002328 except ( ValueError, TypeError ):
2329 main.log.error( "Error parsing nodes output" )
2330 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002331 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2332 onpass="Nodes check successful",
2333 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002334
Jon Hall6aec96b2015-01-19 14:49:31 -08002335 def CASE9( self, main ):
2336 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002337 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002338 """
2339 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002340 assert numControllers, "numControllers not defined"
2341 assert main, "main not defined"
2342 assert utilities.assert_equals, "utilities.assert_equals not defined"
2343 assert CLIs, "CLIs not defined"
2344 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002345 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002346
Jon Hall8f89dda2015-01-22 16:03:33 -08002347 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002348
Jon Hall6aec96b2015-01-19 14:49:31 -08002349 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002350 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002351 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002352
Jon Hall6aec96b2015-01-19 14:49:31 -08002353 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002354 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002355 main.log.info( "Waiting " + str( linkSleep ) +
2356 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002357 time.sleep( linkSleep )
2358 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002359 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002360 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002361 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002362
Jon Hall6aec96b2015-01-19 14:49:31 -08002363 def CASE10( self, main ):
2364 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002365 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002366 """
2367 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002368 assert numControllers, "numControllers not defined"
2369 assert main, "main not defined"
2370 assert utilities.assert_equals, "utilities.assert_equals not defined"
2371 assert CLIs, "CLIs not defined"
2372 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002373 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002374
Jon Hall8f89dda2015-01-22 16:03:33 -08002375 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002376
Jon Hall6aec96b2015-01-19 14:49:31 -08002377 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002378 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002380
Jon Hall6aec96b2015-01-19 14:49:31 -08002381 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002382 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002383 main.log.info( "Waiting " + str( linkSleep ) +
2384 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002385 time.sleep( linkSleep )
2386 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002387 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002388 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002389 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002390
Jon Hall6aec96b2015-01-19 14:49:31 -08002391 def CASE11( self, main ):
2392 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002393 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002394 """
2395 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002396 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002397 assert numControllers, "numControllers not defined"
2398 assert main, "main not defined"
2399 assert utilities.assert_equals, "utilities.assert_equals not defined"
2400 assert CLIs, "CLIs not defined"
2401 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002402
Jon Hall8f89dda2015-01-22 16:03:33 -08002403 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002404
2405 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002406 main.case( description )
2407 switch = main.params[ 'kill' ][ 'switch' ]
2408 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002409
Jon Hall6aec96b2015-01-19 14:49:31 -08002410 # TODO: Make this switch parameterizable
2411 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002412 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002413 main.Mininet1.delSwitch( switch )
2414 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002415 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002416 time.sleep( switchSleep )
2417 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002418 # Peek at the deleted switch
2419 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002420 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002421 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002422 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002423 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002424 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002425 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002426
Jon Hall6aec96b2015-01-19 14:49:31 -08002427 def CASE12( self, main ):
2428 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002429 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002430 """
2431 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002432 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002433 assert numControllers, "numControllers not defined"
2434 assert main, "main not defined"
2435 assert utilities.assert_equals, "utilities.assert_equals not defined"
2436 assert CLIs, "CLIs not defined"
2437 assert nodes, "nodes not defined"
2438 assert ONOS1Port, "ONOS1Port not defined"
2439 assert ONOS2Port, "ONOS2Port not defined"
2440 assert ONOS3Port, "ONOS3Port not defined"
2441 assert ONOS4Port, "ONOS4Port not defined"
2442 assert ONOS5Port, "ONOS5Port not defined"
2443 assert ONOS6Port, "ONOS6Port not defined"
2444 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002445
Jon Hall8f89dda2015-01-22 16:03:33 -08002446 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002447 switch = main.params[ 'kill' ][ 'switch' ]
2448 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2449 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002450 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002451 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002452
Jon Hall6aec96b2015-01-19 14:49:31 -08002453 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002454 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002455 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002456 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002457 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2458 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002459 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002460 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002461 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002462 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002463 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002464 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002465 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002466 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002467 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002468 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002469 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002470 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002471 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002472 port7=ONOS7Port )
2473 main.log.info( "Waiting " + str( switchSleep ) +
2474 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002475 time.sleep( switchSleep )
2476 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002477 # Peek at the deleted switch
2478 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002479 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002480 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002481 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002482 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002483 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002484 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002485
Jon Hall6aec96b2015-01-19 14:49:31 -08002486 def CASE13( self, main ):
2487 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002488 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002489 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002490 import os
2491 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002492 assert numControllers, "numControllers not defined"
2493 assert main, "main not defined"
2494 assert utilities.assert_equals, "utilities.assert_equals not defined"
2495 assert CLIs, "CLIs not defined"
2496 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002497
2498 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002499 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2500 'blue': '\033[94m', 'green': '\033[92m',
2501 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002502 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002503 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002504 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002505
Jon Hall6aec96b2015-01-19 14:49:31 -08002506 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002507 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002508 teststationUser = main.params[ 'TESTONUSER' ]
2509 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002510 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002511 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002512 # FIXME: scp
2513 # mn files
2514 # TODO: Load these from params
2515 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002516 logFolder = "/opt/onos/log/"
2517 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002518 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002519 dstDir = "~/packet_captures/"
2520 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002521 for node in nodes:
2522 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2523 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002524 teststationUser + "@" +
2525 teststationIP + ":" +
2526 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002527 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002528 main.ONOSbench.handle.expect( "\$" )
2529
Jon Hall6aec96b2015-01-19 14:49:31 -08002530 # std*.log's
2531 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002532 logFolder = "/opt/onos/var/"
2533 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002534 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002535 dstDir = "~/packet_captures/"
2536 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002537 for node in nodes:
2538 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2539 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002540 teststationUser + "@" +
2541 teststationIP + ":" +
2542 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002543 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002544 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002545 # sleep so scp can finish
2546 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002547
2548 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002549 mnResult = main.Mininet1.stopNet()
2550 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2551 onpass="Mininet stopped",
2552 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002553
2554 main.step( "Checking ONOS Logs for errors" )
2555 for node in nodes:
2556 print colors[ 'purple' ] + "Checking logs for errors on " + \
2557 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002558 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002559
Jon Hall6aec96b2015-01-19 14:49:31 -08002560 main.step( "Packing and rotating pcap archives" )
2561 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002562
Jon Hallfeff3082015-05-19 10:23:26 -07002563 try:
2564 timerLog = open( main.logdir + "/Timers.csv", 'w')
2565 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002566 labels = "Gossip Intents, Restart"
2567 data = str( gossipTime ) + ", " + str( main.restartTime )
2568 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002569 timerLog.close()
2570 except NameError, e:
2571 main.log.exception(e)
2572
Jon Hall6aec96b2015-01-19 14:49:31 -08002573 def CASE14( self, main ):
2574 """
Jon Hall669173b2014-12-17 11:36:30 -08002575 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002576 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002577 assert numControllers, "numControllers not defined"
2578 assert main, "main not defined"
2579 assert utilities.assert_equals, "utilities.assert_equals not defined"
2580 assert CLIs, "CLIs not defined"
2581 assert nodes, "nodes not defined"
2582
Jon Hall390696c2015-05-05 17:13:41 -07002583 main.case("Start Leadership Election app")
2584 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002585 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2586 utilities.assert_equals(
2587 expect=main.TRUE,
2588 actual=appResult,
2589 onpass="Election app installed",
2590 onfail="Something went wrong with installing Leadership election" )
2591
2592 main.step( "Run for election on each node" )
2593 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002594 leaders = []
2595 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002596 cli.electionTestRun()
2597 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002598 leader = cli.electionTestLeader()
2599 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002600 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002601 "should be an ONOS node, instead got '" +
2602 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002603 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002604 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002605 utilities.assert_equals(
2606 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002607 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002608 onpass="Successfully ran for leadership",
2609 onfail="Failed to run for leadership" )
2610
2611 main.step( "Check that each node shows the same leader" )
2612 sameLeader = main.TRUE
2613 if len( set( leaders ) ) != 1:
2614 sameLeader = main.FALSE
2615 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2616 str( leaders ) )
2617 utilities.assert_equals(
2618 expect=main.TRUE,
2619 actual=sameLeader,
2620 onpass="Leadership is consistent for the election topic",
2621 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002622
Jon Hall6aec96b2015-01-19 14:49:31 -08002623 def CASE15( self, main ):
2624 """
Jon Hall669173b2014-12-17 11:36:30 -08002625 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002626 """
Jon Hall390696c2015-05-05 17:13:41 -07002627 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002628 assert numControllers, "numControllers not defined"
2629 assert main, "main not defined"
2630 assert utilities.assert_equals, "utilities.assert_equals not defined"
2631 assert CLIs, "CLIs not defined"
2632 assert nodes, "nodes not defined"
2633
Jon Hall8f89dda2015-01-22 16:03:33 -08002634 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002635 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002636 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002637 # NOTE: Need to re-run since being a canidate is not persistant
2638 main.step( "Run for election on each node" )
2639 leaderResult = main.TRUE
2640 leaders = []
2641 for cli in CLIs:
2642 cli.electionTestRun()
2643 for cli in CLIs:
2644 leader = cli.electionTestLeader()
2645 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002646 main.log.error( cli.name + ": Leader for the election app " +
Jon Hallfeff3082015-05-19 10:23:26 -07002647 "should be an ONOS node, instead got '" +
2648 str( leader ) + "'" )
2649 leaderResult = main.FALSE
2650 leaders.append( leader )
2651 utilities.assert_equals(
2652 expect=main.TRUE,
2653 actual=leaderResult,
2654 onpass="Successfully ran for leadership",
2655 onfail="Failed to run for leadership" )
2656
2657 main.step( "Check that each node shows the same leader" )
2658 sameLeader = main.TRUE
2659 if len( set( leaders ) ) != 1:
2660 sameLeader = main.FALSE
2661 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2662 str( leaders ) )
2663 utilities.assert_equals(
2664 expect=main.TRUE,
2665 actual=sameLeader,
2666 onpass="Leadership is consistent for the election topic",
2667 onfail="Nodes have different leaders" )
2668
Jon Hall6aec96b2015-01-19 14:49:31 -08002669 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002670 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002671 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002672 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002673 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002674 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002675 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002676 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002677 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002678 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002679 for i in range( len( CLIs ) ):
2680 if leader == nodes[ i ].ip_address:
2681 oldLeader = CLIs[ i ]
2682 break
Jon Halla9d26da2015-03-30 16:45:32 -07002683 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002684 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002685 if oldLeader:
2686 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002687 utilities.assert_equals(
2688 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002689 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002690 onpass="Node was withdrawn from election",
2691 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002692
Jon Hall6aec96b2015-01-19 14:49:31 -08002693 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002694 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002695 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002696 for cli in CLIs:
2697 leaderN = cli.electionTestLeader()
2698 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002699 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002700 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002701 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002702 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002703 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002704 # error in response
2705 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002706 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002707 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002708 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002709 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002710 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002711 elif leaderN is None:
2712 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002713 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002714 leaderN = cli.electionTestLeader()
2715 leaderList.pop()
2716 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002717 consistentLeader = main.FALSE
2718 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002719 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002720 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002721 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002722 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002723 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002724 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002725 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002726 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002727 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002728 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002729 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002730 utilities.assert_equals(
2731 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002732 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002733 onpass="Leadership election passed",
2734 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002735
Jon Hall58c76b72015-02-23 11:09:24 -08002736 main.step( "Run for election on old leader( just so everyone " +
2737 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002738 if oldLeader:
2739 runResult = oldLeader.electionTestRun()
2740 else:
2741 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002742 utilities.assert_equals(
2743 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002744 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002745 onpass="App re-ran for election",
2746 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002747
Jon Hallfeff3082015-05-19 10:23:26 -07002748 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002749 afterRun = main.ONOScli1.electionTestLeader()
2750 # verify leader didn't just change
2751 if afterRun == leaderList[ 0 ]:
2752 afterResult = main.TRUE
2753 else:
2754 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002755
Jon Hall6aec96b2015-01-19 14:49:31 -08002756 utilities.assert_equals(
2757 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002758 actual=afterResult,
2759 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002760 onfail="Something went wrong with Leadership election after " +
2761 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002762
Jon Hall390696c2015-05-05 17:13:41 -07002763 def CASE16( self, main ):
2764 """
2765 Install Distributed Primitives app
2766 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002767 import time
Jon Hall390696c2015-05-05 17:13:41 -07002768 assert numControllers, "numControllers not defined"
2769 assert main, "main not defined"
2770 assert utilities.assert_equals, "utilities.assert_equals not defined"
2771 assert CLIs, "CLIs not defined"
2772 assert nodes, "nodes not defined"
2773
2774 # Variables for the distributed primitives tests
2775 global pCounterName
2776 global iCounterName
2777 global pCounterValue
2778 global iCounterValue
2779 global onosSet
2780 global onosSetName
2781 pCounterName = "TestON-Partitions"
2782 iCounterName = "TestON-inMemory"
2783 pCounterValue = 0
2784 iCounterValue = 0
2785 onosSet = set([])
2786 onosSetName = "TestON-set"
2787
2788 description = "Install Primitives app"
2789 main.case( description )
2790 main.step( "Install Primitives app" )
2791 appName = "org.onosproject.distributedprimitives"
2792 appResults = CLIs[0].activateApp( appName )
2793 utilities.assert_equals( expect=main.TRUE,
2794 actual=appResults,
2795 onpass="Primitives app activated",
2796 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002797 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002798
2799 def CASE17( self, main ):
2800 """
2801 Check for basic functionality with distributed primitives
2802 """
2803 # Make sure variables are defined/set
2804 assert numControllers, "numControllers not defined"
2805 assert main, "main not defined"
2806 assert utilities.assert_equals, "utilities.assert_equals not defined"
2807 assert CLIs, "CLIs not defined"
2808 assert nodes, "nodes not defined"
2809 assert pCounterName, "pCounterName not defined"
2810 assert iCounterName, "iCounterName not defined"
2811 assert onosSetName, "onosSetName not defined"
2812 # NOTE: assert fails if value is 0/None/Empty/False
2813 try:
2814 pCounterValue
2815 except NameError:
2816 main.log.error( "pCounterValue not defined, setting to 0" )
2817 pCounterValue = 0
2818 try:
2819 iCounterValue
2820 except NameError:
2821 main.log.error( "iCounterValue not defined, setting to 0" )
2822 iCounterValue = 0
2823 try:
2824 onosSet
2825 except NameError:
2826 main.log.error( "onosSet not defined, setting to empty Set" )
2827 onosSet = set([])
2828 # Variables for the distributed primitives tests. These are local only
2829 addValue = "a"
2830 addAllValue = "a b c d e f"
2831 retainValue = "c d e f"
2832
2833 description = "Check for basic functionality with distributed " +\
2834 "primitives"
2835 main.case( description )
2836 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2837 # DISTRIBUTED ATOMIC COUNTERS
2838 main.step( "Increment and get a default counter on each node" )
2839 pCounters = []
2840 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002841 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002842 for i in range( numControllers ):
2843 t = main.Thread( target=CLIs[i].counterTestIncrement,
2844 name="counterIncrement-" + str( i ),
2845 args=[ pCounterName ] )
2846 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002847 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002848 threads.append( t )
2849 t.start()
2850
2851 for t in threads:
2852 t.join()
2853 pCounters.append( t.result )
2854 # Check that counter incremented numController times
2855 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002856 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002857 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002858 pCounterResults = pCounterResults and tmpResult
2859 if not tmpResult:
2860 main.log.error( str( i ) + " is not in partitioned "
2861 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002862 utilities.assert_equals( expect=True,
2863 actual=pCounterResults,
2864 onpass="Default counter incremented",
2865 onfail="Error incrementing default" +
2866 " counter" )
2867
2868 main.step( "Increment and get an in memory counter on each node" )
2869 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002870 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002871 threads = []
2872 for i in range( numControllers ):
2873 t = main.Thread( target=CLIs[i].counterTestIncrement,
2874 name="icounterIncrement-" + str( i ),
2875 args=[ iCounterName ],
2876 kwargs={ "inMemory": True } )
2877 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002878 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002879 threads.append( t )
2880 t.start()
2881
2882 for t in threads:
2883 t.join()
2884 iCounters.append( t.result )
2885 # Check that counter incremented numController times
2886 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002887 for i in addedIValues:
2888 tmpResult = i in iCounters
2889 iCounterResults = iCounterResults and tmpResult
2890 if not tmpResult:
2891 main.log.error( str( i ) + " is not in the in-memory "
2892 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002893 utilities.assert_equals( expect=True,
2894 actual=iCounterResults,
2895 onpass="In memory counter incremented",
2896 onfail="Error incrementing in memory" +
2897 " counter" )
2898
2899 main.step( "Check counters are consistant across nodes" )
2900 onosCounters = []
2901 threads = []
2902 for i in range( numControllers ):
2903 t = main.Thread( target=CLIs[i].counters,
2904 name="counters-" + str( i ) )
2905 threads.append( t )
2906 t.start()
2907 for t in threads:
2908 t.join()
2909 onosCounters.append( t.result )
2910 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2911 if all( tmp ):
2912 main.log.info( "Counters are consistent across all nodes" )
2913 consistentCounterResults = main.TRUE
2914 else:
2915 main.log.error( "Counters are not consistent across all nodes" )
2916 consistentCounterResults = main.FALSE
2917 utilities.assert_equals( expect=main.TRUE,
2918 actual=consistentCounterResults,
2919 onpass="ONOS counters are consistent " +
2920 "across nodes",
2921 onfail="ONOS Counters are inconsistent " +
2922 "across nodes" )
2923
2924 main.step( "Counters we added have the correct values" )
2925 correctResults = main.TRUE
2926 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002927 current = json.loads( onosCounters[i] )
2928 pValue = None
2929 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002930 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002931 for database in current:
2932 partitioned = database.get( 'partitionedDatabaseCounters' )
2933 if partitioned:
2934 for value in partitioned:
2935 if value.get( 'name' ) == pCounterName:
2936 pValue = value.get( 'value' )
2937 break
2938 inMemory = database.get( 'inMemoryDatabaseCounters' )
2939 if inMemory:
2940 for value in inMemory:
2941 if value.get( 'name' ) == iCounterName:
2942 iValue = value.get( 'value' )
2943 break
Jon Hall390696c2015-05-05 17:13:41 -07002944 except AttributeError, e:
2945 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2946 "is not as expected" )
2947 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07002948 if pValue == pCounterValue:
2949 main.log.info( "Partitioned counter value is correct" )
2950 else:
2951 main.log.error( "Partitioned counter value is incorrect," +
2952 " expected value: " + str( pCounterValue )
2953 + " current value: " + str( pValue ) )
2954 correctResults = main.FALSE
2955 if iValue == iCounterValue:
2956 main.log.info( "In memory counter value is correct" )
2957 else:
2958 main.log.error( "In memory counter value is incorrect, " +
2959 "expected value: " + str( iCounterValue ) +
2960 " current value: " + str( iValue ) )
2961 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07002962 utilities.assert_equals( expect=main.TRUE,
2963 actual=correctResults,
2964 onpass="Added counters are correct",
2965 onfail="Added counters are incorrect" )
2966 # DISTRIBUTED SETS
2967 main.step( "Distributed Set get" )
2968 size = len( onosSet )
2969 getResponses = []
2970 threads = []
2971 for i in range( numControllers ):
2972 t = main.Thread( target=CLIs[i].setTestGet,
2973 name="setTestGet-" + str( i ),
2974 args=[ onosSetName ] )
2975 threads.append( t )
2976 t.start()
2977 for t in threads:
2978 t.join()
2979 getResponses.append( t.result )
2980
2981 getResults = main.TRUE
2982 for i in range( numControllers ):
2983 if isinstance( getResponses[ i ], list):
2984 current = set( getResponses[ i ] )
2985 if len( current ) == len( getResponses[ i ] ):
2986 # no repeats
2987 if onosSet != current:
2988 main.log.error( "ONOS" + str( i + 1 ) +
2989 " has incorrect view" +
2990 " of set " + onosSetName + ":\n" +
2991 str( getResponses[ i ] ) )
2992 main.log.debug( "Expected: " + str( onosSet ) )
2993 main.log.debug( "Actual: " + str( current ) )
2994 getResults = main.FALSE
2995 else:
2996 # error, set is not a set
2997 main.log.error( "ONOS" + str( i + 1 ) +
2998 " has repeat elements in" +
2999 " set " + onosSetName + ":\n" +
3000 str( getResponses[ i ] ) )
3001 getResults = main.FALSE
3002 elif getResponses[ i ] == main.ERROR:
3003 getResults = main.FALSE
3004 utilities.assert_equals( expect=main.TRUE,
3005 actual=getResults,
3006 onpass="Set elements are correct",
3007 onfail="Set elements are incorrect" )
3008
3009 main.step( "Distributed Set size" )
3010 sizeResponses = []
3011 threads = []
3012 for i in range( numControllers ):
3013 t = main.Thread( target=CLIs[i].setTestSize,
3014 name="setTestSize-" + str( i ),
3015 args=[ onosSetName ] )
3016 threads.append( t )
3017 t.start()
3018 for t in threads:
3019 t.join()
3020 sizeResponses.append( t.result )
3021
3022 sizeResults = main.TRUE
3023 for i in range( numControllers ):
3024 if size != sizeResponses[ i ]:
3025 sizeResults = main.FALSE
3026 main.log.error( "ONOS" + str( i + 1 ) +
3027 " expected a size of " + str( size ) +
3028 " for set " + onosSetName +
3029 " but got " + str( sizeResponses[ i ] ) )
3030 utilities.assert_equals( expect=main.TRUE,
3031 actual=sizeResults,
3032 onpass="Set sizes are correct",
3033 onfail="Set sizes are incorrect" )
3034
3035 main.step( "Distributed Set add()" )
3036 onosSet.add( addValue )
3037 addResponses = []
3038 threads = []
3039 for i in range( numControllers ):
3040 t = main.Thread( target=CLIs[i].setTestAdd,
3041 name="setTestAdd-" + str( i ),
3042 args=[ onosSetName, addValue ] )
3043 threads.append( t )
3044 t.start()
3045 for t in threads:
3046 t.join()
3047 addResponses.append( t.result )
3048
3049 # main.TRUE = successfully changed the set
3050 # main.FALSE = action resulted in no change in set
3051 # main.ERROR - Some error in executing the function
3052 addResults = main.TRUE
3053 for i in range( numControllers ):
3054 if addResponses[ i ] == main.TRUE:
3055 # All is well
3056 pass
3057 elif addResponses[ i ] == main.FALSE:
3058 # Already in set, probably fine
3059 pass
3060 elif addResponses[ i ] == main.ERROR:
3061 # Error in execution
3062 addResults = main.FALSE
3063 else:
3064 # unexpected result
3065 addResults = main.FALSE
3066 if addResults != main.TRUE:
3067 main.log.error( "Error executing set add" )
3068
3069 # Check if set is still correct
3070 size = len( onosSet )
3071 getResponses = []
3072 threads = []
3073 for i in range( numControllers ):
3074 t = main.Thread( target=CLIs[i].setTestGet,
3075 name="setTestGet-" + str( i ),
3076 args=[ onosSetName ] )
3077 threads.append( t )
3078 t.start()
3079 for t in threads:
3080 t.join()
3081 getResponses.append( t.result )
3082 getResults = main.TRUE
3083 for i in range( numControllers ):
3084 if isinstance( getResponses[ i ], list):
3085 current = set( getResponses[ i ] )
3086 if len( current ) == len( getResponses[ i ] ):
3087 # no repeats
3088 if onosSet != current:
3089 main.log.error( "ONOS" + str( i + 1 ) +
3090 " has incorrect view" +
3091 " of set " + onosSetName + ":\n" +
3092 str( getResponses[ i ] ) )
3093 main.log.debug( "Expected: " + str( onosSet ) )
3094 main.log.debug( "Actual: " + str( current ) )
3095 getResults = main.FALSE
3096 else:
3097 # error, set is not a set
3098 main.log.error( "ONOS" + str( i + 1 ) +
3099 " has repeat elements in" +
3100 " set " + onosSetName + ":\n" +
3101 str( getResponses[ i ] ) )
3102 getResults = main.FALSE
3103 elif getResponses[ i ] == main.ERROR:
3104 getResults = main.FALSE
3105 sizeResponses = []
3106 threads = []
3107 for i in range( numControllers ):
3108 t = main.Thread( target=CLIs[i].setTestSize,
3109 name="setTestSize-" + str( i ),
3110 args=[ onosSetName ] )
3111 threads.append( t )
3112 t.start()
3113 for t in threads:
3114 t.join()
3115 sizeResponses.append( t.result )
3116 sizeResults = main.TRUE
3117 for i in range( numControllers ):
3118 if size != sizeResponses[ i ]:
3119 sizeResults = main.FALSE
3120 main.log.error( "ONOS" + str( i + 1 ) +
3121 " expected a size of " + str( size ) +
3122 " for set " + onosSetName +
3123 " but got " + str( sizeResponses[ i ] ) )
3124 addResults = addResults and getResults and sizeResults
3125 utilities.assert_equals( expect=main.TRUE,
3126 actual=addResults,
3127 onpass="Set add correct",
3128 onfail="Set add was incorrect" )
3129
3130 main.step( "Distributed Set addAll()" )
3131 onosSet.update( addAllValue.split() )
3132 addResponses = []
3133 threads = []
3134 for i in range( numControllers ):
3135 t = main.Thread( target=CLIs[i].setTestAdd,
3136 name="setTestAddAll-" + str( i ),
3137 args=[ onosSetName, addAllValue ] )
3138 threads.append( t )
3139 t.start()
3140 for t in threads:
3141 t.join()
3142 addResponses.append( t.result )
3143
3144 # main.TRUE = successfully changed the set
3145 # main.FALSE = action resulted in no change in set
3146 # main.ERROR - Some error in executing the function
3147 addAllResults = main.TRUE
3148 for i in range( numControllers ):
3149 if addResponses[ i ] == main.TRUE:
3150 # All is well
3151 pass
3152 elif addResponses[ i ] == main.FALSE:
3153 # Already in set, probably fine
3154 pass
3155 elif addResponses[ i ] == main.ERROR:
3156 # Error in execution
3157 addAllResults = main.FALSE
3158 else:
3159 # unexpected result
3160 addAllResults = main.FALSE
3161 if addAllResults != main.TRUE:
3162 main.log.error( "Error executing set addAll" )
3163
3164 # Check if set is still correct
3165 size = len( onosSet )
3166 getResponses = []
3167 threads = []
3168 for i in range( numControllers ):
3169 t = main.Thread( target=CLIs[i].setTestGet,
3170 name="setTestGet-" + str( i ),
3171 args=[ onosSetName ] )
3172 threads.append( t )
3173 t.start()
3174 for t in threads:
3175 t.join()
3176 getResponses.append( t.result )
3177 getResults = main.TRUE
3178 for i in range( numControllers ):
3179 if isinstance( getResponses[ i ], list):
3180 current = set( getResponses[ i ] )
3181 if len( current ) == len( getResponses[ i ] ):
3182 # no repeats
3183 if onosSet != current:
3184 main.log.error( "ONOS" + str( i + 1 ) +
3185 " has incorrect view" +
3186 " of set " + onosSetName + ":\n" +
3187 str( getResponses[ i ] ) )
3188 main.log.debug( "Expected: " + str( onosSet ) )
3189 main.log.debug( "Actual: " + str( current ) )
3190 getResults = main.FALSE
3191 else:
3192 # error, set is not a set
3193 main.log.error( "ONOS" + str( i + 1 ) +
3194 " has repeat elements in" +
3195 " set " + onosSetName + ":\n" +
3196 str( getResponses[ i ] ) )
3197 getResults = main.FALSE
3198 elif getResponses[ i ] == main.ERROR:
3199 getResults = main.FALSE
3200 sizeResponses = []
3201 threads = []
3202 for i in range( numControllers ):
3203 t = main.Thread( target=CLIs[i].setTestSize,
3204 name="setTestSize-" + str( i ),
3205 args=[ onosSetName ] )
3206 threads.append( t )
3207 t.start()
3208 for t in threads:
3209 t.join()
3210 sizeResponses.append( t.result )
3211 sizeResults = main.TRUE
3212 for i in range( numControllers ):
3213 if size != sizeResponses[ i ]:
3214 sizeResults = main.FALSE
3215 main.log.error( "ONOS" + str( i + 1 ) +
3216 " expected a size of " + str( size ) +
3217 " for set " + onosSetName +
3218 " but got " + str( sizeResponses[ i ] ) )
3219 addAllResults = addAllResults and getResults and sizeResults
3220 utilities.assert_equals( expect=main.TRUE,
3221 actual=addAllResults,
3222 onpass="Set addAll correct",
3223 onfail="Set addAll was incorrect" )
3224
3225 main.step( "Distributed Set contains()" )
3226 containsResponses = []
3227 threads = []
3228 for i in range( numControllers ):
3229 t = main.Thread( target=CLIs[i].setTestGet,
3230 name="setContains-" + str( i ),
3231 args=[ onosSetName ],
3232 kwargs={ "values": addValue } )
3233 threads.append( t )
3234 t.start()
3235 for t in threads:
3236 t.join()
3237 # NOTE: This is the tuple
3238 containsResponses.append( t.result )
3239
3240 containsResults = main.TRUE
3241 for i in range( numControllers ):
3242 if containsResponses[ i ] == main.ERROR:
3243 containsResults = main.FALSE
3244 else:
3245 containsResults = containsResults and\
3246 containsResponses[ i ][ 1 ]
3247 utilities.assert_equals( expect=main.TRUE,
3248 actual=containsResults,
3249 onpass="Set contains is functional",
3250 onfail="Set contains failed" )
3251
3252 main.step( "Distributed Set containsAll()" )
3253 containsAllResponses = []
3254 threads = []
3255 for i in range( numControllers ):
3256 t = main.Thread( target=CLIs[i].setTestGet,
3257 name="setContainsAll-" + str( i ),
3258 args=[ onosSetName ],
3259 kwargs={ "values": addAllValue } )
3260 threads.append( t )
3261 t.start()
3262 for t in threads:
3263 t.join()
3264 # NOTE: This is the tuple
3265 containsAllResponses.append( t.result )
3266
3267 containsAllResults = main.TRUE
3268 for i in range( numControllers ):
3269 if containsResponses[ i ] == main.ERROR:
3270 containsResults = main.FALSE
3271 else:
3272 containsResults = containsResults and\
3273 containsResponses[ i ][ 1 ]
3274 utilities.assert_equals( expect=main.TRUE,
3275 actual=containsAllResults,
3276 onpass="Set containsAll is functional",
3277 onfail="Set containsAll failed" )
3278
3279 main.step( "Distributed Set remove()" )
3280 onosSet.remove( addValue )
3281 removeResponses = []
3282 threads = []
3283 for i in range( numControllers ):
3284 t = main.Thread( target=CLIs[i].setTestRemove,
3285 name="setTestRemove-" + str( i ),
3286 args=[ onosSetName, addValue ] )
3287 threads.append( t )
3288 t.start()
3289 for t in threads:
3290 t.join()
3291 removeResponses.append( t.result )
3292
3293 # main.TRUE = successfully changed the set
3294 # main.FALSE = action resulted in no change in set
3295 # main.ERROR - Some error in executing the function
3296 removeResults = main.TRUE
3297 for i in range( numControllers ):
3298 if removeResponses[ i ] == main.TRUE:
3299 # All is well
3300 pass
3301 elif removeResponses[ i ] == main.FALSE:
3302 # not in set, probably fine
3303 pass
3304 elif removeResponses[ i ] == main.ERROR:
3305 # Error in execution
3306 removeResults = main.FALSE
3307 else:
3308 # unexpected result
3309 removeResults = main.FALSE
3310 if removeResults != main.TRUE:
3311 main.log.error( "Error executing set remove" )
3312
3313 # Check if set is still correct
3314 size = len( onosSet )
3315 getResponses = []
3316 threads = []
3317 for i in range( numControllers ):
3318 t = main.Thread( target=CLIs[i].setTestGet,
3319 name="setTestGet-" + str( i ),
3320 args=[ onosSetName ] )
3321 threads.append( t )
3322 t.start()
3323 for t in threads:
3324 t.join()
3325 getResponses.append( t.result )
3326 getResults = main.TRUE
3327 for i in range( numControllers ):
3328 if isinstance( getResponses[ i ], list):
3329 current = set( getResponses[ i ] )
3330 if len( current ) == len( getResponses[ i ] ):
3331 # no repeats
3332 if onosSet != current:
3333 main.log.error( "ONOS" + str( i + 1 ) +
3334 " has incorrect view" +
3335 " of set " + onosSetName + ":\n" +
3336 str( getResponses[ i ] ) )
3337 main.log.debug( "Expected: " + str( onosSet ) )
3338 main.log.debug( "Actual: " + str( current ) )
3339 getResults = main.FALSE
3340 else:
3341 # error, set is not a set
3342 main.log.error( "ONOS" + str( i + 1 ) +
3343 " has repeat elements in" +
3344 " set " + onosSetName + ":\n" +
3345 str( getResponses[ i ] ) )
3346 getResults = main.FALSE
3347 elif getResponses[ i ] == main.ERROR:
3348 getResults = main.FALSE
3349 sizeResponses = []
3350 threads = []
3351 for i in range( numControllers ):
3352 t = main.Thread( target=CLIs[i].setTestSize,
3353 name="setTestSize-" + str( i ),
3354 args=[ onosSetName ] )
3355 threads.append( t )
3356 t.start()
3357 for t in threads:
3358 t.join()
3359 sizeResponses.append( t.result )
3360 sizeResults = main.TRUE
3361 for i in range( numControllers ):
3362 if size != sizeResponses[ i ]:
3363 sizeResults = main.FALSE
3364 main.log.error( "ONOS" + str( i + 1 ) +
3365 " expected a size of " + str( size ) +
3366 " for set " + onosSetName +
3367 " but got " + str( sizeResponses[ i ] ) )
3368 removeResults = removeResults and getResults and sizeResults
3369 utilities.assert_equals( expect=main.TRUE,
3370 actual=removeResults,
3371 onpass="Set remove correct",
3372 onfail="Set remove was incorrect" )
3373
3374 main.step( "Distributed Set removeAll()" )
3375 onosSet.difference_update( addAllValue.split() )
3376 removeAllResponses = []
3377 threads = []
3378 try:
3379 for i in range( numControllers ):
3380 t = main.Thread( target=CLIs[i].setTestRemove,
3381 name="setTestRemoveAll-" + str( i ),
3382 args=[ onosSetName, addAllValue ] )
3383 threads.append( t )
3384 t.start()
3385 for t in threads:
3386 t.join()
3387 removeAllResponses.append( t.result )
3388 except Exception, e:
3389 main.log.exception(e)
3390
3391 # main.TRUE = successfully changed the set
3392 # main.FALSE = action resulted in no change in set
3393 # main.ERROR - Some error in executing the function
3394 removeAllResults = main.TRUE
3395 for i in range( numControllers ):
3396 if removeAllResponses[ i ] == main.TRUE:
3397 # All is well
3398 pass
3399 elif removeAllResponses[ i ] == main.FALSE:
3400 # not in set, probably fine
3401 pass
3402 elif removeAllResponses[ i ] == main.ERROR:
3403 # Error in execution
3404 removeAllResults = main.FALSE
3405 else:
3406 # unexpected result
3407 removeAllResults = main.FALSE
3408 if removeAllResults != main.TRUE:
3409 main.log.error( "Error executing set removeAll" )
3410
3411 # Check if set is still correct
3412 size = len( onosSet )
3413 getResponses = []
3414 threads = []
3415 for i in range( numControllers ):
3416 t = main.Thread( target=CLIs[i].setTestGet,
3417 name="setTestGet-" + str( i ),
3418 args=[ onosSetName ] )
3419 threads.append( t )
3420 t.start()
3421 for t in threads:
3422 t.join()
3423 getResponses.append( t.result )
3424 getResults = main.TRUE
3425 for i in range( numControllers ):
3426 if isinstance( getResponses[ i ], list):
3427 current = set( getResponses[ i ] )
3428 if len( current ) == len( getResponses[ i ] ):
3429 # no repeats
3430 if onosSet != current:
3431 main.log.error( "ONOS" + str( i + 1 ) +
3432 " has incorrect view" +
3433 " of set " + onosSetName + ":\n" +
3434 str( getResponses[ i ] ) )
3435 main.log.debug( "Expected: " + str( onosSet ) )
3436 main.log.debug( "Actual: " + str( current ) )
3437 getResults = main.FALSE
3438 else:
3439 # error, set is not a set
3440 main.log.error( "ONOS" + str( i + 1 ) +
3441 " has repeat elements in" +
3442 " set " + onosSetName + ":\n" +
3443 str( getResponses[ i ] ) )
3444 getResults = main.FALSE
3445 elif getResponses[ i ] == main.ERROR:
3446 getResults = main.FALSE
3447 sizeResponses = []
3448 threads = []
3449 for i in range( numControllers ):
3450 t = main.Thread( target=CLIs[i].setTestSize,
3451 name="setTestSize-" + str( i ),
3452 args=[ onosSetName ] )
3453 threads.append( t )
3454 t.start()
3455 for t in threads:
3456 t.join()
3457 sizeResponses.append( t.result )
3458 sizeResults = main.TRUE
3459 for i in range( numControllers ):
3460 if size != sizeResponses[ i ]:
3461 sizeResults = main.FALSE
3462 main.log.error( "ONOS" + str( i + 1 ) +
3463 " expected a size of " + str( size ) +
3464 " for set " + onosSetName +
3465 " but got " + str( sizeResponses[ i ] ) )
3466 removeAllResults = removeAllResults and getResults and sizeResults
3467 utilities.assert_equals( expect=main.TRUE,
3468 actual=removeAllResults,
3469 onpass="Set removeAll correct",
3470 onfail="Set removeAll was incorrect" )
3471
3472 main.step( "Distributed Set addAll()" )
3473 onosSet.update( addAllValue.split() )
3474 addResponses = []
3475 threads = []
3476 for i in range( numControllers ):
3477 t = main.Thread( target=CLIs[i].setTestAdd,
3478 name="setTestAddAll-" + str( i ),
3479 args=[ onosSetName, addAllValue ] )
3480 threads.append( t )
3481 t.start()
3482 for t in threads:
3483 t.join()
3484 addResponses.append( t.result )
3485
3486 # main.TRUE = successfully changed the set
3487 # main.FALSE = action resulted in no change in set
3488 # main.ERROR - Some error in executing the function
3489 addAllResults = main.TRUE
3490 for i in range( numControllers ):
3491 if addResponses[ i ] == main.TRUE:
3492 # All is well
3493 pass
3494 elif addResponses[ i ] == main.FALSE:
3495 # Already in set, probably fine
3496 pass
3497 elif addResponses[ i ] == main.ERROR:
3498 # Error in execution
3499 addAllResults = main.FALSE
3500 else:
3501 # unexpected result
3502 addAllResults = main.FALSE
3503 if addAllResults != main.TRUE:
3504 main.log.error( "Error executing set addAll" )
3505
3506 # Check if set is still correct
3507 size = len( onosSet )
3508 getResponses = []
3509 threads = []
3510 for i in range( numControllers ):
3511 t = main.Thread( target=CLIs[i].setTestGet,
3512 name="setTestGet-" + str( i ),
3513 args=[ onosSetName ] )
3514 threads.append( t )
3515 t.start()
3516 for t in threads:
3517 t.join()
3518 getResponses.append( t.result )
3519 getResults = main.TRUE
3520 for i in range( numControllers ):
3521 if isinstance( getResponses[ i ], list):
3522 current = set( getResponses[ i ] )
3523 if len( current ) == len( getResponses[ i ] ):
3524 # no repeats
3525 if onosSet != current:
3526 main.log.error( "ONOS" + str( i + 1 ) +
3527 " has incorrect view" +
3528 " of set " + onosSetName + ":\n" +
3529 str( getResponses[ i ] ) )
3530 main.log.debug( "Expected: " + str( onosSet ) )
3531 main.log.debug( "Actual: " + str( current ) )
3532 getResults = main.FALSE
3533 else:
3534 # error, set is not a set
3535 main.log.error( "ONOS" + str( i + 1 ) +
3536 " has repeat elements in" +
3537 " set " + onosSetName + ":\n" +
3538 str( getResponses[ i ] ) )
3539 getResults = main.FALSE
3540 elif getResponses[ i ] == main.ERROR:
3541 getResults = main.FALSE
3542 sizeResponses = []
3543 threads = []
3544 for i in range( numControllers ):
3545 t = main.Thread( target=CLIs[i].setTestSize,
3546 name="setTestSize-" + str( i ),
3547 args=[ onosSetName ] )
3548 threads.append( t )
3549 t.start()
3550 for t in threads:
3551 t.join()
3552 sizeResponses.append( t.result )
3553 sizeResults = main.TRUE
3554 for i in range( numControllers ):
3555 if size != sizeResponses[ i ]:
3556 sizeResults = main.FALSE
3557 main.log.error( "ONOS" + str( i + 1 ) +
3558 " expected a size of " + str( size ) +
3559 " for set " + onosSetName +
3560 " but got " + str( sizeResponses[ i ] ) )
3561 addAllResults = addAllResults and getResults and sizeResults
3562 utilities.assert_equals( expect=main.TRUE,
3563 actual=addAllResults,
3564 onpass="Set addAll correct",
3565 onfail="Set addAll was incorrect" )
3566
3567 main.step( "Distributed Set clear()" )
3568 onosSet.clear()
3569 clearResponses = []
3570 threads = []
3571 for i in range( numControllers ):
3572 t = main.Thread( target=CLIs[i].setTestRemove,
3573 name="setTestClear-" + str( i ),
3574 args=[ onosSetName, " "], # Values doesn't matter
3575 kwargs={ "clear": True } )
3576 threads.append( t )
3577 t.start()
3578 for t in threads:
3579 t.join()
3580 clearResponses.append( t.result )
3581
3582 # main.TRUE = successfully changed the set
3583 # main.FALSE = action resulted in no change in set
3584 # main.ERROR - Some error in executing the function
3585 clearResults = main.TRUE
3586 for i in range( numControllers ):
3587 if clearResponses[ i ] == main.TRUE:
3588 # All is well
3589 pass
3590 elif clearResponses[ i ] == main.FALSE:
3591 # Nothing set, probably fine
3592 pass
3593 elif clearResponses[ i ] == main.ERROR:
3594 # Error in execution
3595 clearResults = main.FALSE
3596 else:
3597 # unexpected result
3598 clearResults = main.FALSE
3599 if clearResults != main.TRUE:
3600 main.log.error( "Error executing set clear" )
3601
3602 # Check if set is still correct
3603 size = len( onosSet )
3604 getResponses = []
3605 threads = []
3606 for i in range( numControllers ):
3607 t = main.Thread( target=CLIs[i].setTestGet,
3608 name="setTestGet-" + str( i ),
3609 args=[ onosSetName ] )
3610 threads.append( t )
3611 t.start()
3612 for t in threads:
3613 t.join()
3614 getResponses.append( t.result )
3615 getResults = main.TRUE
3616 for i in range( numControllers ):
3617 if isinstance( getResponses[ i ], list):
3618 current = set( getResponses[ i ] )
3619 if len( current ) == len( getResponses[ i ] ):
3620 # no repeats
3621 if onosSet != current:
3622 main.log.error( "ONOS" + str( i + 1 ) +
3623 " has incorrect view" +
3624 " of set " + onosSetName + ":\n" +
3625 str( getResponses[ i ] ) )
3626 main.log.debug( "Expected: " + str( onosSet ) )
3627 main.log.debug( "Actual: " + str( current ) )
3628 getResults = main.FALSE
3629 else:
3630 # error, set is not a set
3631 main.log.error( "ONOS" + str( i + 1 ) +
3632 " has repeat elements in" +
3633 " set " + onosSetName + ":\n" +
3634 str( getResponses[ i ] ) )
3635 getResults = main.FALSE
3636 elif getResponses[ i ] == main.ERROR:
3637 getResults = main.FALSE
3638 sizeResponses = []
3639 threads = []
3640 for i in range( numControllers ):
3641 t = main.Thread( target=CLIs[i].setTestSize,
3642 name="setTestSize-" + str( i ),
3643 args=[ onosSetName ] )
3644 threads.append( t )
3645 t.start()
3646 for t in threads:
3647 t.join()
3648 sizeResponses.append( t.result )
3649 sizeResults = main.TRUE
3650 for i in range( numControllers ):
3651 if size != sizeResponses[ i ]:
3652 sizeResults = main.FALSE
3653 main.log.error( "ONOS" + str( i + 1 ) +
3654 " expected a size of " + str( size ) +
3655 " for set " + onosSetName +
3656 " but got " + str( sizeResponses[ i ] ) )
3657 clearResults = clearResults and getResults and sizeResults
3658 utilities.assert_equals( expect=main.TRUE,
3659 actual=clearResults,
3660 onpass="Set clear correct",
3661 onfail="Set clear was incorrect" )
3662
3663 main.step( "Distributed Set addAll()" )
3664 onosSet.update( addAllValue.split() )
3665 addResponses = []
3666 threads = []
3667 for i in range( numControllers ):
3668 t = main.Thread( target=CLIs[i].setTestAdd,
3669 name="setTestAddAll-" + str( i ),
3670 args=[ onosSetName, addAllValue ] )
3671 threads.append( t )
3672 t.start()
3673 for t in threads:
3674 t.join()
3675 addResponses.append( t.result )
3676
3677 # main.TRUE = successfully changed the set
3678 # main.FALSE = action resulted in no change in set
3679 # main.ERROR - Some error in executing the function
3680 addAllResults = main.TRUE
3681 for i in range( numControllers ):
3682 if addResponses[ i ] == main.TRUE:
3683 # All is well
3684 pass
3685 elif addResponses[ i ] == main.FALSE:
3686 # Already in set, probably fine
3687 pass
3688 elif addResponses[ i ] == main.ERROR:
3689 # Error in execution
3690 addAllResults = main.FALSE
3691 else:
3692 # unexpected result
3693 addAllResults = main.FALSE
3694 if addAllResults != main.TRUE:
3695 main.log.error( "Error executing set addAll" )
3696
3697 # Check if set is still correct
3698 size = len( onosSet )
3699 getResponses = []
3700 threads = []
3701 for i in range( numControllers ):
3702 t = main.Thread( target=CLIs[i].setTestGet,
3703 name="setTestGet-" + str( i ),
3704 args=[ onosSetName ] )
3705 threads.append( t )
3706 t.start()
3707 for t in threads:
3708 t.join()
3709 getResponses.append( t.result )
3710 getResults = main.TRUE
3711 for i in range( numControllers ):
3712 if isinstance( getResponses[ i ], list):
3713 current = set( getResponses[ i ] )
3714 if len( current ) == len( getResponses[ i ] ):
3715 # no repeats
3716 if onosSet != current:
3717 main.log.error( "ONOS" + str( i + 1 ) +
3718 " has incorrect view" +
3719 " of set " + onosSetName + ":\n" +
3720 str( getResponses[ i ] ) )
3721 main.log.debug( "Expected: " + str( onosSet ) )
3722 main.log.debug( "Actual: " + str( current ) )
3723 getResults = main.FALSE
3724 else:
3725 # error, set is not a set
3726 main.log.error( "ONOS" + str( i + 1 ) +
3727 " has repeat elements in" +
3728 " set " + onosSetName + ":\n" +
3729 str( getResponses[ i ] ) )
3730 getResults = main.FALSE
3731 elif getResponses[ i ] == main.ERROR:
3732 getResults = main.FALSE
3733 sizeResponses = []
3734 threads = []
3735 for i in range( numControllers ):
3736 t = main.Thread( target=CLIs[i].setTestSize,
3737 name="setTestSize-" + str( i ),
3738 args=[ onosSetName ] )
3739 threads.append( t )
3740 t.start()
3741 for t in threads:
3742 t.join()
3743 sizeResponses.append( t.result )
3744 sizeResults = main.TRUE
3745 for i in range( numControllers ):
3746 if size != sizeResponses[ i ]:
3747 sizeResults = main.FALSE
3748 main.log.error( "ONOS" + str( i + 1 ) +
3749 " expected a size of " + str( size ) +
3750 " for set " + onosSetName +
3751 " but got " + str( sizeResponses[ i ] ) )
3752 addAllResults = addAllResults and getResults and sizeResults
3753 utilities.assert_equals( expect=main.TRUE,
3754 actual=addAllResults,
3755 onpass="Set addAll correct",
3756 onfail="Set addAll was incorrect" )
3757
3758 main.step( "Distributed Set retain()" )
3759 onosSet.intersection_update( retainValue.split() )
3760 retainResponses = []
3761 threads = []
3762 for i in range( numControllers ):
3763 t = main.Thread( target=CLIs[i].setTestRemove,
3764 name="setTestRetain-" + str( i ),
3765 args=[ onosSetName, retainValue ],
3766 kwargs={ "retain": True } )
3767 threads.append( t )
3768 t.start()
3769 for t in threads:
3770 t.join()
3771 retainResponses.append( t.result )
3772
3773 # main.TRUE = successfully changed the set
3774 # main.FALSE = action resulted in no change in set
3775 # main.ERROR - Some error in executing the function
3776 retainResults = main.TRUE
3777 for i in range( numControllers ):
3778 if retainResponses[ i ] == main.TRUE:
3779 # All is well
3780 pass
3781 elif retainResponses[ i ] == main.FALSE:
3782 # Already in set, probably fine
3783 pass
3784 elif retainResponses[ i ] == main.ERROR:
3785 # Error in execution
3786 retainResults = main.FALSE
3787 else:
3788 # unexpected result
3789 retainResults = main.FALSE
3790 if retainResults != main.TRUE:
3791 main.log.error( "Error executing set retain" )
3792
3793 # Check if set is still correct
3794 size = len( onosSet )
3795 getResponses = []
3796 threads = []
3797 for i in range( numControllers ):
3798 t = main.Thread( target=CLIs[i].setTestGet,
3799 name="setTestGet-" + str( i ),
3800 args=[ onosSetName ] )
3801 threads.append( t )
3802 t.start()
3803 for t in threads:
3804 t.join()
3805 getResponses.append( t.result )
3806 getResults = main.TRUE
3807 for i in range( numControllers ):
3808 if isinstance( getResponses[ i ], list):
3809 current = set( getResponses[ i ] )
3810 if len( current ) == len( getResponses[ i ] ):
3811 # no repeats
3812 if onosSet != current:
3813 main.log.error( "ONOS" + str( i + 1 ) +
3814 " has incorrect view" +
3815 " of set " + onosSetName + ":\n" +
3816 str( getResponses[ i ] ) )
3817 main.log.debug( "Expected: " + str( onosSet ) )
3818 main.log.debug( "Actual: " + str( current ) )
3819 getResults = main.FALSE
3820 else:
3821 # error, set is not a set
3822 main.log.error( "ONOS" + str( i + 1 ) +
3823 " has repeat elements in" +
3824 " set " + onosSetName + ":\n" +
3825 str( getResponses[ i ] ) )
3826 getResults = main.FALSE
3827 elif getResponses[ i ] == main.ERROR:
3828 getResults = main.FALSE
3829 sizeResponses = []
3830 threads = []
3831 for i in range( numControllers ):
3832 t = main.Thread( target=CLIs[i].setTestSize,
3833 name="setTestSize-" + str( i ),
3834 args=[ onosSetName ] )
3835 threads.append( t )
3836 t.start()
3837 for t in threads:
3838 t.join()
3839 sizeResponses.append( t.result )
3840 sizeResults = main.TRUE
3841 for i in range( numControllers ):
3842 if size != sizeResponses[ i ]:
3843 sizeResults = main.FALSE
3844 main.log.error( "ONOS" + str( i + 1 ) +
3845 " expected a size of " +
3846 str( size ) + " for set " + onosSetName +
3847 " but got " + str( sizeResponses[ i ] ) )
3848 retainResults = retainResults and getResults and sizeResults
3849 utilities.assert_equals( expect=main.TRUE,
3850 actual=retainResults,
3851 onpass="Set retain correct",
3852 onfail="Set retain was incorrect" )
3853