blob: c1bd2f01a7256ec1ff83dc50df9c7a71a996799c [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
Jon Hallc9eabec2015-06-10 14:33:14 -07007CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
Jon Hall73cf9cc2014-11-20 22:28:38 -08009CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080020CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070022CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080024"""
Jon Hall8f89dda2015-01-22 16:03:33 -080025
26
Jon Hall73cf9cc2014-11-20 22:28:38 -080027class HATestClusterRestart:
28
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080030 self.default = ''
31
Jon Hall6aec96b2015-01-19 14:49:31 -080032 def CASE1( self, main ):
33 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080034 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080037 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080040 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080045 onos-install -f
46 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080047 start cli sessions
48 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080049 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070050 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
Jon Hall6aec96b2015-01-19 14:49:31 -080051 "initialization" )
52 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070053 main.caseExplaination = "Setup the test environment including " +\
54 "installing ONOS, starting Mininet and ONOS" +\
55 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080056 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080057
Jon Hall5cfd23c2015-03-19 11:40:57 -070058 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080059 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080060 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080061 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080062 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080063 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080064
65 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080072 global ONOS7Port
73 global numControllers
Jon Hallc9eabec2015-06-10 14:33:14 -070074 # These are for csv plotting in jenkins
75 global labels
76 global data
77 labels = []
78 data = []
Jon Hall8f89dda2015-01-22 16:03:33 -080079 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080080
Jon Hall5cfd23c2015-03-19 11:40:57 -070081 # FIXME: just get controller port from params?
82 # TODO: do we really need all these?
83 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
84 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
85 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
86 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
87 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
88 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
89 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
90
91 global CLIs
92 CLIs = []
93 global nodes
94 nodes = []
95 for i in range( 1, numControllers + 1 ):
96 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
97 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
98
Jon Hall6aec96b2015-01-19 14:49:31 -080099 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 cellResult = main.ONOSbench.setCell( cellName )
101 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800102
Jon Hall6aec96b2015-01-19 14:49:31 -0800103 # FIXME:this is short term fix
Jon Hall40d2cbd2015-06-03 16:24:29 -0700104 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800105 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700106
Jon Hall40d2cbd2015-06-03 16:24:29 -0700107 main.log.info( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700108 for node in nodes:
109 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800110
Jon Hall390696c2015-05-05 17:13:41 -0700111 # Make sure ONOS is DEAD
Jon Hall40d2cbd2015-06-03 16:24:29 -0700112 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700113 killResults = main.TRUE
114 for node in nodes:
115 killed = main.ONOSbench.onosKill( node.ip_address )
116 killResults = killResults and killed
117
Jon Hall8f89dda2015-01-22 16:03:33 -0800118 cleanInstallResult = main.TRUE
119 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800120
Jon Hall97f31752015-02-04 12:01:04 -0800121 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700122 mnResult = main.Mininet1.startNet( )
123 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
124 onpass="Mininet Started",
125 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800126
Jon Hallfeff3082015-05-19 10:23:26 -0700127 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800128 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800129 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700131 # values of 1 or 3 are good
132 utilities.assert_lesser( expect=0, actual=gitPullResult,
133 onpass="Git pull successful",
134 onfail="Git pull failed" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800135 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700136
137 main.step( "Using mvn clean install" )
138 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700139 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700140 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700141 else:
142 main.log.warn( "Did not pull new code so skipping mvn " +
143 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700144 utilities.assert_equals( expect=main.TRUE,
145 actual=cleanInstallResult,
146 onpass="MCI successful",
147 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700148 # GRAPHS
149 # NOTE: important params here:
150 # job = name of Jenkins job
151 # Plot Name = Plot-HA, only can be used if multiple plots
152 # index = The number of the graph under plot name
153 job = "HAClusterRestart"
Jon Hall40d2cbd2015-06-03 16:24:29 -0700154 plotName = "Plot-HA"
Jon Hall390696c2015-05-05 17:13:41 -0700155 graphs = '<ac:structured-macro ac:name="html">\n'
156 graphs += '<ac:plain-text-body><![CDATA[\n'
157 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Hall40d2cbd2015-06-03 16:24:29 -0700158 '/plot/' + plotName + '/getPlot?index=0' +\
159 '&width=500&height=300"' +\
Jon Hall390696c2015-05-05 17:13:41 -0700160 'noborder="0" width="500" height="300" scrolling="yes" ' +\
161 'seamless="seamless"></iframe>\n'
162 graphs += ']]></ac:plain-text-body>\n'
163 graphs += '</ac:structured-macro>\n'
164 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800165
Jon Hall6aec96b2015-01-19 14:49:31 -0800166 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800167 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700168 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
169 onpass="ONOS package successful",
170 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800171
Jon Hall6aec96b2015-01-19 14:49:31 -0800172 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700173 onosInstallResult = main.TRUE
174 for node in nodes:
175 tmpResult = main.ONOSbench.onosInstall( options="-f",
176 node=node.ip_address )
177 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700178 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
179 onpass="ONOS install successful",
180 onfail="ONOS install failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800181
Jon Hall6aec96b2015-01-19 14:49:31 -0800182 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800183 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700184 onosIsupResult = main.TRUE
185 for node in nodes:
186 started = main.ONOSbench.isup( node.ip_address )
187 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700188 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700189 main.ONOSbench.onosStop( node.ip_address )
190 main.ONOSbench.onosStart( node.ip_address )
191 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800192 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800193 break
Jon Hall390696c2015-05-05 17:13:41 -0700194 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
195 onpass="ONOS startup successful",
196 onfail="ONOS startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800197
Jon Hall5cfd23c2015-03-19 11:40:57 -0700198 main.log.step( "Starting ONOS CLI sessions" )
199 cliResults = main.TRUE
200 threads = []
201 for i in range( numControllers ):
202 t = main.Thread( target=CLIs[i].startOnosCli,
203 name="startOnosCli-" + str( i ),
204 args=[nodes[i].ip_address] )
205 threads.append( t )
206 t.start()
207
208 for t in threads:
209 t.join()
210 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700211 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
212 onpass="ONOS cli startup successful",
213 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800214
Jon Hall40d2cbd2015-06-03 16:24:29 -0700215 if main.params[ 'tcpdump' ].lower() == "true":
216 main.step( "Start Packet Capture MN" )
217 main.Mininet2.startTcpdump(
218 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
219 + "-MN.pcap",
220 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
221 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800222
Jon Hall390696c2015-05-05 17:13:41 -0700223 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700224 appCheck = main.TRUE
225 threads = []
226 for i in range( numControllers ):
227 t = main.Thread( target=CLIs[i].appToIDCheck,
228 name="appToIDCheck-" + str( i ),
229 args=[] )
230 threads.append( t )
231 t.start()
232
233 for t in threads:
234 t.join()
235 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700236 if appCheck != main.TRUE:
237 main.log.warn( CLIs[0].apps() )
238 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700239 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
240 onpass="App Ids seem to be correct",
241 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700242
Jon Hallfeff3082015-05-19 10:23:26 -0700243 if cliResults == main.FALSE:
244 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hall94fd0472014-12-08 11:52:42 -0800245 main.cleanup()
246 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800247
Jon Hall6aec96b2015-01-19 14:49:31 -0800248 def CASE2( self, main ):
249 """
Jon Hallc9eabec2015-06-10 14:33:14 -0700250 Assign devices to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800251 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800252 import re
Jon Hall390696c2015-05-05 17:13:41 -0700253 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700254 assert numControllers, "numControllers not defined"
255 assert main, "main not defined"
256 assert utilities.assert_equals, "utilities.assert_equals not defined"
257 assert CLIs, "CLIs not defined"
258 assert nodes, "nodes not defined"
259 assert ONOS1Port, "ONOS1Port not defined"
260 assert ONOS2Port, "ONOS2Port not defined"
261 assert ONOS3Port, "ONOS3Port not defined"
262 assert ONOS4Port, "ONOS4Port not defined"
263 assert ONOS5Port, "ONOS5Port not defined"
264 assert ONOS6Port, "ONOS6Port not defined"
265 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800266
Jon Hallc9eabec2015-06-10 14:33:14 -0700267 main.case( "Assigning devices to controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700268 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
269 "and check that an ONOS node becomes the " +\
Jon Hallc9eabec2015-06-10 14:33:14 -0700270 "master of the device."
Jon Hall6aec96b2015-01-19 14:49:31 -0800271 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800272
Jon Hall5cfd23c2015-03-19 11:40:57 -0700273 # TODO: rewrite this function to take lists of ips and ports?
274 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800275 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800276 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800277 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800278 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700279 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
280 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
281 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
282 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
283 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
284 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
285 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800286
Jon Hall8f89dda2015-01-22 16:03:33 -0800287 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800288 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800289 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800290 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800291 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800292 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800293 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700294 for node in nodes:
295 if re.search( "tcp:" + node.ip_address, response ):
296 mastershipCheck = mastershipCheck and main.TRUE
297 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700298 main.log.error( "Error, node " + node.ip_address + " is " +
299 "not in the list of controllers s" +
300 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700301 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800302 utilities.assert_equals(
303 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800304 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800305 onpass="Switch mastership assigned correctly",
306 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700307
Jon Hallc9eabec2015-06-10 14:33:14 -0700308 def CASE21( self, main ):
309 """
310 Assign mastership to controllers
311 """
312 import re
313 import time
314 assert numControllers, "numControllers not defined"
315 assert main, "main not defined"
316 assert utilities.assert_equals, "utilities.assert_equals not defined"
317 assert CLIs, "CLIs not defined"
318 assert nodes, "nodes not defined"
319 assert ONOS1Port, "ONOS1Port not defined"
320 assert ONOS2Port, "ONOS2Port not defined"
321 assert ONOS3Port, "ONOS3Port not defined"
322 assert ONOS4Port, "ONOS4Port not defined"
323 assert ONOS5Port, "ONOS5Port not defined"
324 assert ONOS6Port, "ONOS6Port not defined"
325 assert ONOS7Port, "ONOS7Port not defined"
326
327 main.case( "Assigning Controller roles for switches" )
328 main.caseExplaination = "Check that ONOS is connected to each " +\
329 "device. Then manually assign" +\
330 " mastership to specific ONOS nodes using" +\
331 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700332 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800333 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800334 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700335
336 ipList = [ ]
337 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800338 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700339 for i in range( 1, 29 ): # switches 1 through 28
340 # set up correct variables:
341 if i == 1:
342 ip = nodes[ 0 ].ip_address # ONOS1
343 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
344 elif i == 2:
345 ip = nodes[ 1 ].ip_address # ONOS2
346 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
347 elif i == 3:
348 ip = nodes[ 1 ].ip_address # ONOS2
349 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
350 elif i == 4:
351 ip = nodes[ 3 ].ip_address # ONOS4
352 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
353 elif i == 5:
354 ip = nodes[ 2 ].ip_address # ONOS3
355 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
356 elif i == 6:
357 ip = nodes[ 2 ].ip_address # ONOS3
358 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
359 elif i == 7:
360 ip = nodes[ 5 ].ip_address # ONOS6
361 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
362 elif i >= 8 and i <= 17:
363 ip = nodes[ 4 ].ip_address # ONOS5
364 dpid = '3' + str( i ).zfill( 3 )
365 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
366 elif i >= 18 and i <= 27:
367 ip = nodes[ 6 ].ip_address # ONOS7
368 dpid = '6' + str( i ).zfill( 3 )
369 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
370 elif i == 28:
371 ip = nodes[ 0 ].ip_address # ONOS1
372 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
373 else:
374 main.log.error( "You didn't write an else statement for " +
375 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700376 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700377 # Assign switch
378 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
379 # TODO: make this controller dynamic
380 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
381 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700382 ipList.append( ip )
383 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800384 except ( AttributeError, AssertionError ):
385 main.log.exception( "Something is wrong with ONOS device view" )
386 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800387 utilities.assert_equals(
388 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800389 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800390 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800391 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800392
Jon Hall390696c2015-05-05 17:13:41 -0700393 main.step( "Check mastership was correctly assigned" )
394 roleCheck = main.TRUE
395 # NOTE: This is due to the fact that device mastership change is not
396 # atomic and is actually a multi step process
397 time.sleep( 5 )
398 for i in range( len( ipList ) ):
399 ip = ipList[i]
400 deviceId = deviceList[i]
401 # Check assignment
402 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
403 if ip in master:
404 roleCheck = roleCheck and main.TRUE
405 else:
406 roleCheck = roleCheck and main.FALSE
407 main.log.error( "Error, controller " + ip + " is not" +
408 " master " + "of device " +
409 str( deviceId ) + ". Master is " +
410 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800411 utilities.assert_equals(
412 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800413 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800414 onpass="Switches were successfully reassigned to designated " +
415 "controller",
416 onfail="Switches were not successfully reassigned" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800417
Jon Hall6aec96b2015-01-19 14:49:31 -0800418 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800419 """
420 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800421 """
422 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800423 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700424 assert numControllers, "numControllers not defined"
425 assert main, "main not defined"
426 assert utilities.assert_equals, "utilities.assert_equals not defined"
427 assert CLIs, "CLIs not defined"
428 assert nodes, "nodes not defined"
Jon Hallc9eabec2015-06-10 14:33:14 -0700429 try:
430 labels
431 except NameError:
432 main.log.error( "labels not defined, setting to []" )
433 labels = []
434 try:
435 data
436 except NameError:
437 main.log.error( "data not defined, setting to []" )
438 data = []
Jon Hallfeff3082015-05-19 10:23:26 -0700439 # NOTE: we must reinstall intents until we have a persistant intent
440 # datastore!
Jon Hall6aec96b2015-01-19 14:49:31 -0800441 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700442 main.caseExplaination = "Discover hosts by using pingall then " +\
443 "assign predetermined host-to-host intents." +\
444 " After installation, check that the intent" +\
445 " is distributed to all nodes and the state" +\
446 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800447
Jon Hall6aec96b2015-01-19 14:49:31 -0800448 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700449 main.step( "Install reactive forwarding app" )
450 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
451 utilities.assert_equals( expect=main.TRUE, actual=installResults,
452 onpass="Install fwd successful",
453 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700454
Jon Hallfeff3082015-05-19 10:23:26 -0700455 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700456 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700457 threads = []
458 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700459 t = main.Thread( target=CLIs[i].appToIDCheck,
460 name="appToIDCheck-" + str( i ),
461 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700462 threads.append( t )
463 t.start()
464
465 for t in threads:
466 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700467 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700468 if appCheck != main.TRUE:
469 main.log.warn( CLIs[0].apps() )
470 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700471 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
472 onpass="App Ids seem to be correct",
473 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800474
Jon Hallfeff3082015-05-19 10:23:26 -0700475 main.step( "Discovering Hosts( Via pingall for now )" )
476 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800477 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800478 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700479 for i in range(2): # Retry if pingall fails first time
480 time1 = time.time()
481 pingResult = main.Mininet1.pingall()
482 utilities.assert_equals(
483 expect=main.TRUE,
484 actual=pingResult,
485 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700486 onfail="Reactive Pingall failed, " +
487 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700488 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700489 main.log.info( "Time for pingall: %2f seconds" %
490 ( time2 - time1 ) )
491 # timeout for fwd flows
492 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800493 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700494 main.step( "Uninstall reactive forwarding app" )
495 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
496 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
497 onpass="Uninstall fwd successful",
498 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700499
500 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700501 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700502 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700503 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700504 t = main.Thread( target=CLIs[i].appToIDCheck,
505 name="appToIDCheck-" + str( i ),
506 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700507 threads.append( t )
508 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800509
Jon Hall5cfd23c2015-03-19 11:40:57 -0700510 for t in threads:
511 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700512 appCheck2 = appCheck2 and t.result
513 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700514 main.log.warn( CLIs[0].apps() )
515 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700516 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700517 onpass="App Ids seem to be correct",
518 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700519
Jon Hallfeff3082015-05-19 10:23:26 -0700520 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800521 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800522 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800523 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800524 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800525 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800526 for i in range( 8, 18 ):
527 main.log.info( "Adding host intent between h" + str( i ) +
528 " and h" + str( i + 10 ) )
529 host1 = "00:00:00:00:00:" + \
530 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
531 host2 = "00:00:00:00:00:" + \
532 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800533 # NOTE: getHost can return None
534 host1Dict = main.ONOScli1.getHost( host1 )
535 host2Dict = main.ONOScli1.getHost( host2 )
536 host1Id = None
537 host2Id = None
538 if host1Dict and host2Dict:
539 host1Id = host1Dict.get( 'id', None )
540 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800541 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700542 nodeNum = ( i % 7 )
543 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800544 if tmpId:
545 main.log.info( "Added intent with id: " + tmpId )
546 intentIds.append( tmpId )
547 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700548 main.log.error( "addHostIntent returned: " +
549 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800550 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700551 main.log.error( "Error, getHost() failed for h" + str( i ) +
552 " and/or h" + str( i + 10 ) )
553 hosts = CLIs[ 0 ].hosts()
554 main.log.warn( "Hosts output: " )
555 try:
556 main.log.warn( json.dumps( json.loads( hosts ),
557 sort_keys=True,
558 indent=4,
559 separators=( ',', ': ' ) ) )
560 except ( ValueError, TypeError ):
561 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800562 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700563 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
564 onpass="Found a host id for each host",
565 onfail="Error looking up host ids" )
566
Jon Halla9d26da2015-03-30 16:45:32 -0700567 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800568 onosIds = main.ONOScli1.getAllIntentsId()
569 main.log.info( "Submitted intents: " + str( intentIds ) )
570 main.log.info( "Intents in ONOS: " + str( onosIds ) )
571 for intent in intentIds:
572 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700573 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800574 else:
575 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700576 if intentAddResult:
577 intentStop = time.time()
578 else:
579 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800580 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800581 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800582 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800583 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800584 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
585 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700586 try:
587 for intent in json.loads( intents ):
588 state = intent.get( 'state', None )
589 if "INSTALLED" not in state:
590 installedCheck = False
591 intentId = intent.get( 'id', None )
592 intentStates.append( ( intentId, state ) )
593 except ( ValueError, TypeError ):
594 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800595 # add submitted intents not in the store
596 tmplist = [ i for i, s in intentStates ]
597 missingIntents = False
598 for i in intentIds:
599 if i not in tmplist:
600 intentStates.append( ( i, " - " ) )
601 missingIntents = True
602 intentStates.sort()
603 for i, s in intentStates:
604 count += 1
605 main.log.info( "%-6s%-15s%-15s" %
606 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700607 leaders = main.ONOScli1.leaders()
608 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700609 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700610 if leaders:
611 parsedLeaders = json.loads( leaders )
612 main.log.warn( json.dumps( parsedLeaders,
613 sort_keys=True,
614 indent=4,
615 separators=( ',', ': ' ) ) )
616 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700617 topics = []
618 for i in range( 14 ):
619 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700620 main.log.debug( topics )
621 ONOStopics = [ j['topic'] for j in parsedLeaders ]
622 for topic in topics:
623 if topic not in ONOStopics:
624 main.log.error( "Error: " + topic +
625 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700626 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700627 else:
628 main.log.error( "leaders() returned None" )
629 except ( ValueError, TypeError ):
630 main.log.exception( "Error parsing leaders" )
631 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700632 # Check all nodes
633 if missing:
634 for node in CLIs:
635 response = node.leaders( jsonFormat=False)
636 main.log.warn( str( node.name ) + " leaders output: \n" +
637 str( response ) )
638
Jon Hall5cfd23c2015-03-19 11:40:57 -0700639 partitions = main.ONOScli1.partitions()
640 try:
641 if partitions :
642 parsedPartitions = json.loads( partitions )
643 main.log.warn( json.dumps( parsedPartitions,
644 sort_keys=True,
645 indent=4,
646 separators=( ',', ': ' ) ) )
647 # TODO check for a leader in all paritions
648 # TODO check for consistency among nodes
649 else:
650 main.log.error( "partitions() returned None" )
651 except ( ValueError, TypeError ):
652 main.log.exception( "Error parsing partitions" )
653 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800654 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700655 try:
656 if pendingMap :
657 parsedPending = json.loads( pendingMap )
658 main.log.warn( json.dumps( parsedPending,
659 sort_keys=True,
660 indent=4,
661 separators=( ',', ': ' ) ) )
662 # TODO check something here?
663 else:
664 main.log.error( "pendingMap() returned None" )
665 except ( ValueError, TypeError ):
666 main.log.exception( "Error parsing pending map" )
667 main.log.error( repr( pendingMap ) )
668
Jon Hallfeff3082015-05-19 10:23:26 -0700669 intentAddResult = bool( intentAddResult and not missingIntents and
670 installedCheck )
671 if not intentAddResult:
672 main.log.error( "Error in pushing host intents to ONOS" )
673
Jon Hall390696c2015-05-05 17:13:41 -0700674 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700675 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700676 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700677 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700678 for cli in CLIs:
679 onosIds = []
680 ids = cli.getAllIntentsId()
681 onosIds.append( ids )
682 main.log.debug( "Intents in " + cli.name + ": " +
683 str( sorted( onosIds ) ) )
684 if sorted( ids ) != sorted( intentIds ):
Jon Hallc9eabec2015-06-10 14:33:14 -0700685 main.log.debug( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700686 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700687 break
688 else:
689 intents = json.loads( cli.intents() )
690 for intent in intents:
691 if intent[ 'state' ] != "INSTALLED":
Jon Hallc9eabec2015-06-10 14:33:14 -0700692 main.log.warn( "Intent " + intent[ 'id' ] +
693 " is " + intent[ 'state' ] )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700694 correct = False
695 break
Jon Hall390696c2015-05-05 17:13:41 -0700696 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700697 break
698 else:
699 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700700 if not intentStop:
701 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700702 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700703 gossipTime = intentStop - intentStart
704 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700705 " seconds for all intents to appear in each node" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700706 append = False
707 title = "Gossip Intents"
708 count = 1
709 while append is False:
710 curTitle = title + str( count )
711 if curTitle not in labels:
712 labels.append( curTitle )
713 data.append( str( gossipTime ) )
714 append = True
715 else:
716 count += 1
Jon Halla9d26da2015-03-30 16:45:32 -0700717 # FIXME: make this time configurable/calculate based off of number of
718 # nodes and gossip rounds
719 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700720 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700721 onpass="ECM anti-entropy for intents worked within " +
722 "expected time",
723 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700724 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700725 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800726
Jon Hall63604932015-02-26 17:09:50 -0800727 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800728 import time
Jon Hall63604932015-02-26 17:09:50 -0800729 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800730 main.log.info( "Sleeping 60 seconds to see if intents are found" )
731 time.sleep( 60 )
732 onosIds = main.ONOScli1.getAllIntentsId()
733 main.log.info( "Submitted intents: " + str( intentIds ) )
734 main.log.info( "Intents in ONOS: " + str( onosIds ) )
735 # Print the intent states
736 intents = main.ONOScli1.intents()
737 intentStates = []
738 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
739 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700740 try:
741 for intent in json.loads( intents ):
742 # Iter through intents of a node
743 state = intent.get( 'state', None )
744 if "INSTALLED" not in state:
745 installedCheck = False
746 intentId = intent.get( 'id', None )
747 intentStates.append( ( intentId, state ) )
748 except ( ValueError, TypeError ):
749 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800750 # add submitted intents not in the store
751 tmplist = [ i for i, s in intentStates ]
752 for i in intentIds:
753 if i not in tmplist:
754 intentStates.append( ( i, " - " ) )
755 intentStates.sort()
756 for i, s in intentStates:
757 count += 1
758 main.log.info( "%-6s%-15s%-15s" %
759 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700760 leaders = main.ONOScli1.leaders()
761 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700762 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700763 if leaders:
764 parsedLeaders = json.loads( leaders )
765 main.log.warn( json.dumps( parsedLeaders,
766 sort_keys=True,
767 indent=4,
768 separators=( ',', ': ' ) ) )
769 # check for all intent partitions
770 # check for election
771 topics = []
772 for i in range( 14 ):
773 topics.append( "intent-partition-" + str( i ) )
774 # FIXME: this should only be after we start the app
775 topics.append( "org.onosproject.election" )
776 main.log.debug( topics )
777 ONOStopics = [ j['topic'] for j in parsedLeaders ]
778 for topic in topics:
779 if topic not in ONOStopics:
780 main.log.error( "Error: " + topic +
781 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700782 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700783 else:
784 main.log.error( "leaders() returned None" )
785 except ( ValueError, TypeError ):
786 main.log.exception( "Error parsing leaders" )
787 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700788 # Check all nodes
789 if missing:
790 for node in CLIs:
791 response = node.leaders( jsonFormat=False)
792 main.log.warn( str( node.name ) + " leaders output: \n" +
793 str( response ) )
794
Jon Hall5cfd23c2015-03-19 11:40:57 -0700795 partitions = main.ONOScli1.partitions()
796 try:
797 if partitions :
798 parsedPartitions = json.loads( partitions )
799 main.log.warn( json.dumps( parsedPartitions,
800 sort_keys=True,
801 indent=4,
802 separators=( ',', ': ' ) ) )
803 # TODO check for a leader in all paritions
804 # TODO check for consistency among nodes
805 else:
806 main.log.error( "partitions() returned None" )
807 except ( ValueError, TypeError ):
808 main.log.exception( "Error parsing partitions" )
809 main.log.error( repr( partitions ) )
810 pendingMap = main.ONOScli1.pendingMap()
811 try:
812 if pendingMap :
813 parsedPending = json.loads( pendingMap )
814 main.log.warn( json.dumps( parsedPending,
815 sort_keys=True,
816 indent=4,
817 separators=( ',', ': ' ) ) )
818 # TODO check something here?
819 else:
820 main.log.error( "pendingMap() returned None" )
821 except ( ValueError, TypeError ):
822 main.log.exception( "Error parsing pending map" )
823 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800824
Jon Hall6aec96b2015-01-19 14:49:31 -0800825 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800826 """
827 Ping across added host intents
828 """
Jon Hall58c76b72015-02-23 11:09:24 -0800829 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700830 import time
831 assert numControllers, "numControllers not defined"
832 assert main, "main not defined"
833 assert utilities.assert_equals, "utilities.assert_equals not defined"
834 assert CLIs, "CLIs not defined"
835 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700836 main.case( "Verify connectivity by sendind traffic across Intents" )
837 main.caseExplaination = "Ping across added host intents to check " +\
838 "functionality and check the state of " +\
839 "the intent"
840 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800841 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800842 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800843 ping = main.Mininet1.pingHost( src="h" + str( i ),
844 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800845 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800846 if ping == main.FALSE:
847 main.log.warn( "Ping failed between h" + str( i ) +
848 " and h" + str( i + 10 ) )
849 elif ping == main.TRUE:
850 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800851 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800852 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700853 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800854 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800855 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700856 main.log.warn( "ONOS1 intents: " )
857 try:
858 tmpIntents = main.ONOScli1.intents()
859 main.log.warn( json.dumps( json.loads( tmpIntents ),
860 sort_keys=True,
861 indent=4,
862 separators=( ',', ': ' ) ) )
863 except ( ValueError, TypeError ):
864 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800865 utilities.assert_equals(
866 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800867 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800868 onpass="Intents have been installed correctly and pings work",
869 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800870
Jon Hallfeff3082015-05-19 10:23:26 -0700871 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700872 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700873 loopCount = 0
874 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700875 installedCheck = True
876 # Print the intent states
877 intents = main.ONOScli1.intents()
878 intentStates = []
879 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700880 # Iter through intents of a node
881 try:
882 for intent in json.loads( intents ):
883 state = intent.get( 'state', None )
884 if "INSTALLED" not in state:
885 installedCheck = False
886 intentId = intent.get( 'id', None )
887 intentStates.append( ( intentId, state ) )
888 except ( ValueError, TypeError ):
889 main.log.exception( "Error parsing intents." )
890 # Print states
891 intentStates.sort()
892 for i, s in intentStates:
893 count += 1
894 main.log.info( "%-6s%-15s%-15s" %
895 ( str( count ), str( i ), str( s ) ) )
896 if not installedCheck:
897 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700898 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700899 utilities.assert_equals( expect=True, actual=installedCheck,
900 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700901 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700902 "INSTALLED state" )
903
904 main.step( "Check leadership of topics" )
905 leaders = main.ONOScli1.leaders()
906 topicCheck = main.TRUE
907 try:
908 if leaders:
909 parsedLeaders = json.loads( leaders )
910 main.log.warn( json.dumps( parsedLeaders,
911 sort_keys=True,
912 indent=4,
913 separators=( ',', ': ' ) ) )
914 # check for all intent partitions
915 # check for election
916 # TODO: Look at Devices as topics now that it uses this system
917 topics = []
918 for i in range( 14 ):
919 topics.append( "intent-partition-" + str( i ) )
920 # FIXME: this should only be after we start the app
921 # FIXME: topics.append( "org.onosproject.election" )
922 # Print leaders output
923 main.log.debug( topics )
924 ONOStopics = [ j['topic'] for j in parsedLeaders ]
925 for topic in topics:
926 if topic not in ONOStopics:
927 main.log.error( "Error: " + topic +
928 " not in leaders" )
929 topicCheck = main.FALSE
930 else:
931 main.log.error( "leaders() returned None" )
932 topicCheck = main.FALSE
933 except ( ValueError, TypeError ):
934 topicCheck = main.FALSE
935 main.log.exception( "Error parsing leaders" )
936 main.log.error( repr( leaders ) )
937 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700938 # Check all nodes
939 if topicCheck:
940 for node in CLIs:
941 response = node.leaders( jsonFormat=False)
942 main.log.warn( str( node.name ) + " leaders output: \n" +
943 str( response ) )
944
Jon Hallfeff3082015-05-19 10:23:26 -0700945 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
946 onpass="intent Partitions is in leaders",
947 onfail="Some topics were lost " )
948 # Print partitions
949 partitions = main.ONOScli1.partitions()
950 try:
951 if partitions :
952 parsedPartitions = json.loads( partitions )
953 main.log.warn( json.dumps( parsedPartitions,
954 sort_keys=True,
955 indent=4,
956 separators=( ',', ': ' ) ) )
957 # TODO check for a leader in all paritions
958 # TODO check for consistency among nodes
959 else:
960 main.log.error( "partitions() returned None" )
961 except ( ValueError, TypeError ):
962 main.log.exception( "Error parsing partitions" )
963 main.log.error( repr( partitions ) )
964 # Print Pending Map
965 pendingMap = main.ONOScli1.pendingMap()
966 try:
967 if pendingMap :
968 parsedPending = json.loads( pendingMap )
969 main.log.warn( json.dumps( parsedPending,
970 sort_keys=True,
971 indent=4,
972 separators=( ',', ': ' ) ) )
973 # TODO check something here?
974 else:
975 main.log.error( "pendingMap() returned None" )
976 except ( ValueError, TypeError ):
977 main.log.exception( "Error parsing pending map" )
978 main.log.error( repr( pendingMap ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700979
Jon Hall63604932015-02-26 17:09:50 -0800980 if not installedCheck:
Jon Hallc9eabec2015-06-10 14:33:14 -0700981 main.log.info( "Waiting 60 seconds to see if the state of " +
982 "intents change" )
983 time.sleep( 60 )
Jon Hall63604932015-02-26 17:09:50 -0800984 # Print the intent states
985 intents = main.ONOScli1.intents()
986 intentStates = []
987 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
988 count = 0
989 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700990 try:
991 for intent in json.loads( intents ):
992 state = intent.get( 'state', None )
993 if "INSTALLED" not in state:
994 installedCheck = False
995 intentId = intent.get( 'id', None )
996 intentStates.append( ( intentId, state ) )
997 except ( ValueError, TypeError ):
998 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800999 intentStates.sort()
1000 for i, s in intentStates:
1001 count += 1
1002 main.log.info( "%-6s%-15s%-15s" %
1003 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001004 leaders = main.ONOScli1.leaders()
1005 try:
Jon Hallc9eabec2015-06-10 14:33:14 -07001006 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -07001007 if leaders:
1008 parsedLeaders = json.loads( leaders )
1009 main.log.warn( json.dumps( parsedLeaders,
1010 sort_keys=True,
1011 indent=4,
1012 separators=( ',', ': ' ) ) )
1013 # check for all intent partitions
1014 # check for election
1015 topics = []
1016 for i in range( 14 ):
1017 topics.append( "intent-partition-" + str( i ) )
1018 # FIXME: this should only be after we start the app
1019 topics.append( "org.onosproject.election" )
1020 main.log.debug( topics )
1021 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1022 for topic in topics:
1023 if topic not in ONOStopics:
1024 main.log.error( "Error: " + topic +
1025 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -07001026 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -07001027 else:
1028 main.log.error( "leaders() returned None" )
1029 except ( ValueError, TypeError ):
1030 main.log.exception( "Error parsing leaders" )
1031 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001032 if missing:
1033 for node in CLIs:
1034 response = node.leaders( jsonFormat=False)
1035 main.log.warn( str( node.name ) + " leaders output: \n" +
1036 str( response ) )
1037
Jon Hall5cfd23c2015-03-19 11:40:57 -07001038 partitions = main.ONOScli1.partitions()
1039 try:
1040 if partitions :
1041 parsedPartitions = json.loads( partitions )
1042 main.log.warn( json.dumps( parsedPartitions,
1043 sort_keys=True,
1044 indent=4,
1045 separators=( ',', ': ' ) ) )
1046 # TODO check for a leader in all paritions
1047 # TODO check for consistency among nodes
1048 else:
1049 main.log.error( "partitions() returned None" )
1050 except ( ValueError, TypeError ):
1051 main.log.exception( "Error parsing partitions" )
1052 main.log.error( repr( partitions ) )
1053 pendingMap = main.ONOScli1.pendingMap()
1054 try:
1055 if pendingMap :
1056 parsedPending = json.loads( pendingMap )
1057 main.log.warn( json.dumps( parsedPending,
1058 sort_keys=True,
1059 indent=4,
1060 separators=( ',', ': ' ) ) )
1061 # TODO check something here?
1062 else:
1063 main.log.error( "pendingMap() returned None" )
1064 except ( ValueError, TypeError ):
1065 main.log.exception( "Error parsing pending map" )
1066 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001067 # Print flowrules
1068 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001069 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001070 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001071 PingResult = main.TRUE
1072 for i in range( 8, 18 ):
1073 ping = main.Mininet1.pingHost( src="h" + str( i ),
1074 target="h" + str( i + 10 ) )
1075 PingResult = PingResult and ping
1076 if ping == main.FALSE:
1077 main.log.warn( "Ping failed between h" + str( i ) +
1078 " and h" + str( i + 10 ) )
1079 elif ping == main.TRUE:
1080 main.log.info( "Ping test passed!" )
1081 # Don't set PingResult or you'd override failures
1082 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001083 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001084 "Intents have not been installed correctly, pings failed." )
1085 # TODO: pretty print
1086 main.log.warn( "ONOS1 intents: " )
1087 try:
1088 tmpIntents = main.ONOScli1.intents()
1089 main.log.warn( json.dumps( json.loads( tmpIntents ),
1090 sort_keys=True,
1091 indent=4,
1092 separators=( ',', ': ' ) ) )
1093 except ( ValueError, TypeError ):
1094 main.log.warn( repr( tmpIntents ) )
1095 utilities.assert_equals(
1096 expect=main.TRUE,
1097 actual=PingResult,
1098 onpass="Intents have been installed correctly and pings work",
1099 onfail="Intents have not been installed correctly, pings failed." )
1100
Jon Hall6aec96b2015-01-19 14:49:31 -08001101 def CASE5( self, main ):
1102 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001103 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001104 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001105 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001106 import time
1107 assert numControllers, "numControllers not defined"
1108 assert main, "main not defined"
1109 assert utilities.assert_equals, "utilities.assert_equals not defined"
1110 assert CLIs, "CLIs not defined"
1111 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001112 # assumes that sts is already in you PYTHONPATH
1113 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001114
Jon Hall6aec96b2015-01-19 14:49:31 -08001115 main.case( "Setting up and gathering data for current state" )
1116 # The general idea for this test case is to pull the state of
1117 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001118 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001119
Jon Hall5cfd23c2015-03-19 11:40:57 -07001120 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001121 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001122 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001123
Jon Hall6aec96b2015-01-19 14:49:31 -08001124 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001125 rolesNotNull = main.TRUE
1126 threads = []
1127 for i in range( numControllers ):
1128 t = main.Thread( target=CLIs[i].rolesNotNull,
1129 name="rolesNotNull-" + str( i ),
1130 args=[] )
1131 threads.append( t )
1132 t.start()
1133
1134 for t in threads:
1135 t.join()
1136 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001137 utilities.assert_equals(
1138 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001139 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001140 onpass="Each device has a master",
1141 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001142
Jon Hall5cfd23c2015-03-19 11:40:57 -07001143 main.step( "Get the Mastership of each switch from each controller" )
1144 ONOSMastership = []
1145 mastershipCheck = main.FALSE
1146 consistentMastership = True
1147 rolesResults = True
1148 threads = []
1149 for i in range( numControllers ):
1150 t = main.Thread( target=CLIs[i].roles,
1151 name="roles-" + str( i ),
1152 args=[] )
1153 threads.append( t )
1154 t.start()
1155
1156 for t in threads:
1157 t.join()
1158 ONOSMastership.append( t.result )
1159
1160 for i in range( numControllers ):
1161 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001162 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001163 " roles" )
1164 main.log.warn(
1165 "ONOS" + str( i + 1 ) + " mastership response: " +
1166 repr( ONOSMastership[i] ) )
1167 rolesResults = False
1168 utilities.assert_equals(
1169 expect=True,
1170 actual=rolesResults,
1171 onpass="No error in reading roles output",
1172 onfail="Error in reading roles from ONOS" )
1173
1174 main.step( "Check for consistency in roles from each controller" )
1175 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001176 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001177 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001178 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001179 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001180 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001181 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001182 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001183 onpass="Switch roles are consistent across all ONOS nodes",
1184 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001185
Jon Hall5cfd23c2015-03-19 11:40:57 -07001186 if rolesResults and not consistentMastership:
1187 for i in range( numControllers ):
1188 try:
1189 main.log.warn(
1190 "ONOS" + str( i + 1 ) + " roles: ",
1191 json.dumps(
1192 json.loads( ONOSMastership[ i ] ),
1193 sort_keys=True,
1194 indent=4,
1195 separators=( ',', ': ' ) ) )
1196 except ( ValueError, TypeError ):
1197 main.log.warn( repr( ONOSMastership[ i ] ) )
1198 elif rolesResults and consistentMastership:
1199 mastershipCheck = main.TRUE
1200 mastershipState = ONOSMastership[ 0 ]
1201
Jon Hall6aec96b2015-01-19 14:49:31 -08001202 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001203 global intentState
1204 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001205 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001206 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001207 consistentIntents = True
1208 intentsResults = True
1209 threads = []
1210 for i in range( numControllers ):
1211 t = main.Thread( target=CLIs[i].intents,
1212 name="intents-" + str( i ),
1213 args=[],
1214 kwargs={ 'jsonFormat': True } )
1215 threads.append( t )
1216 t.start()
1217
1218 for t in threads:
1219 t.join()
1220 ONOSIntents.append( t.result )
1221
1222 for i in range( numControllers ):
1223 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001224 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001225 " intents" )
1226 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1227 repr( ONOSIntents[ i ] ) )
1228 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001229 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001230 expect=True,
1231 actual=intentsResults,
1232 onpass="No error in reading intents output",
1233 onfail="Error in reading intents from ONOS" )
1234
1235 main.step( "Check for consistency in Intents from each controller" )
1236 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001237 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001238 "nodes" )
1239 else:
1240 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001241 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001242 utilities.assert_equals(
1243 expect=True,
1244 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001245 onpass="Intents are consistent across all ONOS nodes",
1246 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001247
Jon Hall390696c2015-05-05 17:13:41 -07001248 if intentsResults:
1249 # Try to make it easy to figure out what is happening
1250 #
1251 # Intent ONOS1 ONOS2 ...
1252 # 0x01 INSTALLED INSTALLING
1253 # ... ... ...
1254 # ... ... ...
1255 title = " Id"
1256 for n in range( numControllers ):
1257 title += " " * 10 + "ONOS" + str( n + 1 )
1258 main.log.warn( title )
1259 # get all intent keys in the cluster
1260 keys = []
1261 for nodeStr in ONOSIntents:
1262 node = json.loads( nodeStr )
1263 for intent in node:
1264 keys.append( intent.get( 'id' ) )
1265 keys = set( keys )
1266 for key in keys:
1267 row = "%-13s" % key
1268 for nodeStr in ONOSIntents:
1269 node = json.loads( nodeStr )
1270 for intent in node:
1271 if intent.get( 'id', "Error" ) == key:
1272 row += "%-15s" % intent.get( 'state' )
1273 main.log.warn( row )
1274 # End table view
1275
Jon Hall5cfd23c2015-03-19 11:40:57 -07001276 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001277 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001278 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001279 main.log.debug( "ONOS" + str( n ) + " intents: " )
1280 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1281 sort_keys=True,
1282 indent=4,
1283 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001284 for i in range( numControllers ):
1285 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001286 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1287 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1288 sort_keys=True,
1289 indent=4,
1290 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001291 else:
Jon Hall390696c2015-05-05 17:13:41 -07001292 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1293 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001294 elif intentsResults and consistentIntents:
1295 intentCheck = main.TRUE
1296 intentState = ONOSIntents[ 0 ]
1297
Jon Hall6aec96b2015-01-19 14:49:31 -08001298 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001299 global flowState
1300 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001301 ONOSFlows = []
1302 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001303 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001304 consistentFlows = True
1305 flowsResults = True
1306 threads = []
1307 for i in range( numControllers ):
1308 t = main.Thread( target=CLIs[i].flows,
1309 name="flows-" + str( i ),
1310 args=[],
1311 kwargs={ 'jsonFormat': True } )
1312 threads.append( t )
1313 t.start()
1314
Jon Halla9d26da2015-03-30 16:45:32 -07001315 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001316 time.sleep(30)
1317 for t in threads:
1318 t.join()
1319 result = t.result
1320 ONOSFlows.append( result )
1321
1322 for i in range( numControllers ):
1323 num = str( i + 1 )
1324 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001325 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001326 main.log.warn( "ONOS" + num + " flows response: " +
1327 repr( ONOSFlows[ i ] ) )
1328 flowsResults = False
1329 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001330 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001331 try:
1332 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1333 except ( ValueError, TypeError ):
1334 # FIXME: change this to log.error?
1335 main.log.exception( "Error in parsing ONOS" + num +
1336 " response as json." )
1337 main.log.error( repr( ONOSFlows[ i ] ) )
1338 ONOSFlowsJson.append( None )
1339 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001340 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001341 expect=True,
1342 actual=flowsResults,
1343 onpass="No error in reading flows output",
1344 onfail="Error in reading flows from ONOS" )
1345
1346 main.step( "Check for consistency in Flows from each controller" )
1347 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1348 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001349 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001350 else:
1351 consistentFlows = False
1352 utilities.assert_equals(
1353 expect=True,
1354 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001355 onpass="The flow count is consistent across all ONOS nodes",
1356 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001357
Jon Hall5cfd23c2015-03-19 11:40:57 -07001358 if flowsResults and not consistentFlows:
1359 for i in range( numControllers ):
1360 try:
1361 main.log.warn(
1362 "ONOS" + str( i + 1 ) + " flows: " +
1363 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1364 indent=4, separators=( ',', ': ' ) ) )
1365 except ( ValueError, TypeError ):
1366 main.log.warn(
1367 "ONOS" + str( i + 1 ) + " flows: " +
1368 repr( ONOSFlows[ i ] ) )
1369 elif flowsResults and consistentFlows:
1370 flowCheck = main.TRUE
1371 flowState = ONOSFlows[ 0 ]
1372
Jon Hall6aec96b2015-01-19 14:49:31 -08001373 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001374 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001375 flows = []
1376 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001377 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001378 if flowCheck == main.FALSE:
1379 for table in flows:
1380 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001381 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001382
Jon Hall6aec96b2015-01-19 14:49:31 -08001383 main.step( "Start continuous pings" )
1384 main.Mininet2.pingLong(
1385 src=main.params[ 'PING' ][ 'source1' ],
1386 target=main.params[ 'PING' ][ 'target1' ],
1387 pingTime=500 )
1388 main.Mininet2.pingLong(
1389 src=main.params[ 'PING' ][ 'source2' ],
1390 target=main.params[ 'PING' ][ 'target2' ],
1391 pingTime=500 )
1392 main.Mininet2.pingLong(
1393 src=main.params[ 'PING' ][ 'source3' ],
1394 target=main.params[ 'PING' ][ 'target3' ],
1395 pingTime=500 )
1396 main.Mininet2.pingLong(
1397 src=main.params[ 'PING' ][ 'source4' ],
1398 target=main.params[ 'PING' ][ 'target4' ],
1399 pingTime=500 )
1400 main.Mininet2.pingLong(
1401 src=main.params[ 'PING' ][ 'source5' ],
1402 target=main.params[ 'PING' ][ 'target5' ],
1403 pingTime=500 )
1404 main.Mininet2.pingLong(
1405 src=main.params[ 'PING' ][ 'source6' ],
1406 target=main.params[ 'PING' ][ 'target6' ],
1407 pingTime=500 )
1408 main.Mininet2.pingLong(
1409 src=main.params[ 'PING' ][ 'source7' ],
1410 target=main.params[ 'PING' ][ 'target7' ],
1411 pingTime=500 )
1412 main.Mininet2.pingLong(
1413 src=main.params[ 'PING' ][ 'source8' ],
1414 target=main.params[ 'PING' ][ 'target8' ],
1415 pingTime=500 )
1416 main.Mininet2.pingLong(
1417 src=main.params[ 'PING' ][ 'source9' ],
1418 target=main.params[ 'PING' ][ 'target9' ],
1419 pingTime=500 )
1420 main.Mininet2.pingLong(
1421 src=main.params[ 'PING' ][ 'source10' ],
1422 target=main.params[ 'PING' ][ 'target10' ],
1423 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001424
Jon Hall6aec96b2015-01-19 14:49:31 -08001425 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001426 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001427 for node in nodes:
1428 temp = ( node, node.name, node.ip_address, 6633 )
1429 ctrls.append( temp )
1430 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001431
Jon Hall6aec96b2015-01-19 14:49:31 -08001432 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001433 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001434 threads = []
1435 for i in range( numControllers ):
1436 t = main.Thread( target=CLIs[i].devices,
1437 name="devices-" + str( i ),
1438 args=[ ] )
1439 threads.append( t )
1440 t.start()
1441
1442 for t in threads:
1443 t.join()
1444 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001445 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001446 threads = []
1447 for i in range( numControllers ):
1448 t = main.Thread( target=CLIs[i].hosts,
1449 name="hosts-" + str( i ),
1450 args=[ ] )
1451 threads.append( t )
1452 t.start()
1453
1454 for t in threads:
1455 t.join()
1456 try:
1457 hosts.append( json.loads( t.result ) )
1458 except ( ValueError, TypeError ):
1459 # FIXME: better handling of this, print which node
1460 # Maybe use thread name?
1461 main.log.exception( "Error parsing json output of hosts" )
1462 # FIXME: should this be an empty json object instead?
1463 hosts.append( None )
1464
Jon Hall73cf9cc2014-11-20 22:28:38 -08001465 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001466 threads = []
1467 for i in range( numControllers ):
1468 t = main.Thread( target=CLIs[i].ports,
1469 name="ports-" + str( i ),
1470 args=[ ] )
1471 threads.append( t )
1472 t.start()
1473
1474 for t in threads:
1475 t.join()
1476 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001477 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001478 threads = []
1479 for i in range( numControllers ):
1480 t = main.Thread( target=CLIs[i].links,
1481 name="links-" + str( i ),
1482 args=[ ] )
1483 threads.append( t )
1484 t.start()
1485
1486 for t in threads:
1487 t.join()
1488 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001489 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001490 threads = []
1491 for i in range( numControllers ):
1492 t = main.Thread( target=CLIs[i].clusters,
1493 name="clusters-" + str( i ),
1494 args=[ ] )
1495 threads.append( t )
1496 t.start()
1497
1498 for t in threads:
1499 t.join()
1500 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001501 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001502
Jon Hall6aec96b2015-01-19 14:49:31 -08001503 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001504 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001505 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001506 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001507 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001508 if "Error" not in hosts[ controller ]:
1509 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001510 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001511 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001512 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001513 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001514 " is inconsistent with ONOS1" )
1515 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001516 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001517
1518 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001519 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001520 controllerStr )
1521 consistentHostsResult = main.FALSE
1522 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001523 " hosts response: " +
1524 repr( hosts[ controller ] ) )
1525 utilities.assert_equals(
1526 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001527 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001528 onpass="Hosts view is consistent across all ONOS nodes",
1529 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001530
Jon Hall390696c2015-05-05 17:13:41 -07001531 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001532 ipResult = main.TRUE
1533 for controller in range( 0, len( hosts ) ):
1534 controllerStr = str( controller + 1 )
1535 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001536 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001537 main.log.error( "DEBUG:Error with host ips on controller" +
1538 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001539 ipResult = main.FALSE
1540 utilities.assert_equals(
1541 expect=main.TRUE,
1542 actual=ipResult,
1543 onpass="The ips of the hosts aren't empty",
1544 onfail="The ip of at least one host is missing" )
1545
Jon Hall6aec96b2015-01-19 14:49:31 -08001546 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001547 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001548 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001549 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001550 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 if "Error" not in clusters[ controller ]:
1552 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001553 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001554 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001555 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001557 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001558
1559 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001560 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001561 "from ONOS" + controllerStr )
1562 consistentClustersResult = main.FALSE
1563 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001564 " clusters response: " +
1565 repr( clusters[ controller ] ) )
1566 utilities.assert_equals(
1567 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001568 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001569 onpass="Clusters view is consistent across all ONOS nodes",
1570 onfail="ONOS nodes have different views of clusters" )
1571 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001572 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001573 try:
1574 numClusters = len( json.loads( clusters[ 0 ] ) )
1575 except ( ValueError, TypeError ):
1576 main.log.exception( "Error parsing clusters[0]: " +
1577 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001578 clusterResults = main.FALSE
1579 if numClusters == 1:
1580 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001581 utilities.assert_equals(
1582 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001583 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001584 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001585 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001586
Jon Hall6aec96b2015-01-19 14:49:31 -08001587 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001588 devicesResults = main.TRUE
1589 portsResults = main.TRUE
1590 linksResults = main.TRUE
1591 for controller in range( numControllers ):
1592 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001593 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001594 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001595 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001596 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001597 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001598 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001599 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001600 actual=currentDevicesResult,
1601 onpass="ONOS" + controllerStr +
1602 " Switches view is correct",
1603 onfail="ONOS" + controllerStr +
1604 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001605
Jon Hall6aec96b2015-01-19 14:49:31 -08001606 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001607 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001608 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001609 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001610 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001611 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001612 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001613 actual=currentPortsResult,
1614 onpass="ONOS" + controllerStr +
1615 " ports view is correct",
1616 onfail="ONOS" + controllerStr +
1617 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001618
Jon Hall6aec96b2015-01-19 14:49:31 -08001619 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001620 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001621 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001622 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001623 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001624 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001625 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001626 actual=currentLinksResult,
1627 onpass="ONOS" + controllerStr +
1628 " links view is correct",
1629 onfail="ONOS" + controllerStr +
1630 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001631
Jon Hall8f89dda2015-01-22 16:03:33 -08001632 devicesResults = devicesResults and currentDevicesResult
1633 portsResults = portsResults and currentPortsResult
1634 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001635
Jon Hall5cfd23c2015-03-19 11:40:57 -07001636 topoResult = ( devicesResults and portsResults and linksResults
1637 and consistentHostsResult and consistentClustersResult
1638 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001639 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001640 onpass="Topology Check Test successful",
1641 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001642
Jon Hall6aec96b2015-01-19 14:49:31 -08001643 def CASE6( self, main ):
1644 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001645 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001646 """
Jon Hallfeff3082015-05-19 10:23:26 -07001647 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001648 assert numControllers, "numControllers not defined"
1649 assert main, "main not defined"
1650 assert utilities.assert_equals, "utilities.assert_equals not defined"
1651 assert CLIs, "CLIs not defined"
1652 assert nodes, "nodes not defined"
Jon Hallc9eabec2015-06-10 14:33:14 -07001653 try:
1654 labels
1655 except NameError:
1656 main.log.error( "labels not defined, setting to []" )
1657 global labels
1658 labels = []
1659 try:
1660 data
1661 except NameError:
1662 main.log.error( "data not defined, setting to []" )
1663 global data
1664 data = []
Jon Hall390696c2015-05-05 17:13:41 -07001665 # Reset non-persistent variables
1666 try:
1667 iCounterValue = 0
1668 except NameError:
1669 main.log.error( "iCounterValue not defined, setting to 0" )
1670 iCounterValue = 0
1671
Jon Hall5cfd23c2015-03-19 11:40:57 -07001672 main.case( "Restart entire ONOS cluster" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001673
Jon Hall5cfd23c2015-03-19 11:40:57 -07001674 main.step( "Killing ONOS nodes" )
1675 killResults = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001676 killTime = time.time()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001677 for node in nodes:
1678 killed = main.ONOSbench.onosKill( node.ip_address )
1679 killResults = killResults and killed
Jon Hall390696c2015-05-05 17:13:41 -07001680 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1681 onpass="ONOS nodes killed",
1682 onfail="ONOS kill unsuccessful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001683
Jon Hall6aec96b2015-01-19 14:49:31 -08001684 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001685 for i in range( 2 ):
1686 onosIsupResult = main.TRUE
1687 for node in nodes:
1688 started = main.ONOSbench.isup( node.ip_address )
1689 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001690 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001691 onosIsupResult = onosIsupResult and started
1692 if onosIsupResult == main.TRUE:
1693 break
Jon Hall390696c2015-05-05 17:13:41 -07001694 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1695 onpass="ONOS restarted",
1696 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001697
Jon Hall5cfd23c2015-03-19 11:40:57 -07001698 main.log.step( "Starting ONOS CLI sessions" )
1699 cliResults = main.TRUE
1700 threads = []
1701 for i in range( numControllers ):
1702 t = main.Thread( target=CLIs[i].startOnosCli,
1703 name="startOnosCli-" + str( i ),
1704 args=[nodes[i].ip_address] )
1705 threads.append( t )
1706 t.start()
1707
1708 for t in threads:
1709 t.join()
1710 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -07001711 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1712 onpass="ONOS cli started",
1713 onfail="ONOS clis did not restart" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001714
Jon Hallfeff3082015-05-19 10:23:26 -07001715 # Grab the time of restart so we chan check how long the gossip
1716 # protocol has had time to work
1717 main.restartTime = time.time() - killTime
1718 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001719 labels.append( "Restart" )
1720 data.append( str( main.restartTime ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001721
Jon Hallfeff3082015-05-19 10:23:26 -07001722 # FIXME: revisit test plan for election with madan
1723 # Rerun for election on restarted nodes
Jon Hall40d2cbd2015-06-03 16:24:29 -07001724 runResults = main.TRUE
1725 for cli in CLIs:
1726 run = CLIs[0].electionTestRun()
1727 if run != main.TRUE:
1728 main.log.error( "Error running for election on " + cli.name )
1729 runResults = runResults and run
Jon Hallfeff3082015-05-19 10:23:26 -07001730 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1731 onpass="Reran for election",
1732 onfail="Failed to rerun for election" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001733
1734 # TODO: Make this configurable
Jon Hallfeff3082015-05-19 10:23:26 -07001735 time.sleep( 60 )
1736 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1737 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1738 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001739
Jon Hall6aec96b2015-01-19 14:49:31 -08001740 def CASE7( self, main ):
1741 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001742 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001743 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001744 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001745 assert numControllers, "numControllers not defined"
1746 assert main, "main not defined"
1747 assert utilities.assert_equals, "utilities.assert_equals not defined"
1748 assert CLIs, "CLIs not defined"
1749 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001750 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001751
Jon Hall5cfd23c2015-03-19 11:40:57 -07001752 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001753 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001754 rolesNotNull = main.TRUE
1755 threads = []
1756 for i in range( numControllers ):
1757 t = main.Thread( target=CLIs[i].rolesNotNull,
1758 name="rolesNotNull-" + str( i ),
1759 args=[ ] )
1760 threads.append( t )
1761 t.start()
1762
1763 for t in threads:
1764 t.join()
1765 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001766 utilities.assert_equals(
1767 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001768 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001769 onpass="Each device has a master",
1770 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001771
Jon Hall390696c2015-05-05 17:13:41 -07001772 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001773 ONOSMastership = []
1774 mastershipCheck = main.FALSE
1775 consistentMastership = True
1776 rolesResults = True
1777 threads = []
1778 for i in range( numControllers ):
1779 t = main.Thread( target=CLIs[i].roles,
1780 name="roles-" + str( i ),
1781 args=[] )
1782 threads.append( t )
1783 t.start()
1784
1785 for t in threads:
1786 t.join()
1787 ONOSMastership.append( t.result )
1788
1789 for i in range( numControllers ):
1790 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001791 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001792 " roles" )
1793 main.log.warn(
1794 "ONOS" + str( i + 1 ) + " mastership response: " +
1795 repr( ONOSMastership[i] ) )
1796 rolesResults = False
1797 utilities.assert_equals(
1798 expect=True,
1799 actual=rolesResults,
1800 onpass="No error in reading roles output",
1801 onfail="Error in reading roles from ONOS" )
1802
1803 main.step( "Check for consistency in roles from each controller" )
1804 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001805 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001806 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001807 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001808 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001809 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001810 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001811 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001812 onpass="Switch roles are consistent across all ONOS nodes",
1813 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001814
Jon Hall5cfd23c2015-03-19 11:40:57 -07001815 if rolesResults and not consistentMastership:
1816 for i in range( numControllers ):
1817 main.log.warn(
1818 "ONOS" + str( i + 1 ) + " roles: ",
1819 json.dumps(
1820 json.loads( ONOSMastership[ i ] ),
1821 sort_keys=True,
1822 indent=4,
1823 separators=( ',', ': ' ) ) )
1824 elif rolesResults and not consistentMastership:
1825 mastershipCheck = main.TRUE
1826
Jon Hallfeff3082015-05-19 10:23:26 -07001827 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001828 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001829 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001830 try:
1831 currentJson = json.loads( ONOSMastership[0] )
1832 oldJson = json.loads( mastershipState )
1833 except ( ValueError, TypeError ):
1834 main.log.exception( "Something is wrong with parsing " +
1835 "ONOSMastership[0] or mastershipState" )
1836 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1837 main.log.error( "mastershipState" + repr( mastershipState ) )
1838 main.cleanup()
1839 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001840 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001841 for i in range( 1, 29 ):
1842 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001843 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001844 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001845 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001846 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001847 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001848 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001849 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001850 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001851 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001852 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001853 utilities.assert_equals(
1854 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001855 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001856 onpass="Mastership of Switches was not changed",
1857 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001858 '''
Jon Hall6aec96b2015-01-19 14:49:31 -08001859 # NOTE: we expect mastership to change on controller failure
Jon Hall73cf9cc2014-11-20 22:28:38 -08001860
Jon Hall6aec96b2015-01-19 14:49:31 -08001861 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001862 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001863 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001864 consistentIntents = True
1865 intentsResults = True
1866 threads = []
1867 for i in range( numControllers ):
1868 t = main.Thread( target=CLIs[i].intents,
1869 name="intents-" + str( i ),
1870 args=[],
1871 kwargs={ 'jsonFormat': True } )
1872 threads.append( t )
1873 t.start()
1874
1875 for t in threads:
1876 t.join()
1877 ONOSIntents.append( t.result )
1878
1879 for i in range( numControllers ):
1880 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001881 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001882 " intents" )
1883 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1884 repr( ONOSIntents[ i ] ) )
1885 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001886 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001887 expect=True,
1888 actual=intentsResults,
1889 onpass="No error in reading intents output",
1890 onfail="Error in reading intents from ONOS" )
1891
1892 main.step( "Check for consistency in Intents from each controller" )
1893 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001894 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001895 "nodes" )
1896 else:
1897 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001898
1899 # Try to make it easy to figure out what is happening
1900 #
1901 # Intent ONOS1 ONOS2 ...
1902 # 0x01 INSTALLED INSTALLING
1903 # ... ... ...
1904 # ... ... ...
1905 title = " ID"
1906 for n in range( numControllers ):
1907 title += " " * 10 + "ONOS" + str( n + 1 )
1908 main.log.warn( title )
1909 # get all intent keys in the cluster
1910 keys = []
1911 for nodeStr in ONOSIntents:
1912 node = json.loads( nodeStr )
1913 for intent in node:
1914 keys.append( intent.get( 'id' ) )
1915 keys = set( keys )
1916 for key in keys:
1917 row = "%-13s" % key
1918 for nodeStr in ONOSIntents:
1919 node = json.loads( nodeStr )
1920 for intent in node:
1921 if intent.get( 'id' ) == key:
1922 row += "%-15s" % intent.get( 'state' )
1923 main.log.warn( row )
1924 # End table view
1925
Jon Hall5cfd23c2015-03-19 11:40:57 -07001926 utilities.assert_equals(
1927 expect=True,
1928 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001929 onpass="Intents are consistent across all ONOS nodes",
1930 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001931 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001932 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001933 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001934 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001935 try:
1936 for intent in json.loads( node ):
1937 nodeStates.append( intent[ 'state' ] )
1938 except ( ValueError, TypeError ):
1939 main.log.exception( "Error in parsing intents" )
1940 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001941 intentStates.append( nodeStates )
1942 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1943 main.log.info( dict( out ) )
1944
Jon Hall5cfd23c2015-03-19 11:40:57 -07001945 if intentsResults and not consistentIntents:
1946 for i in range( numControllers ):
1947 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1948 main.log.warn( json.dumps(
1949 json.loads( ONOSIntents[ i ] ),
1950 sort_keys=True,
1951 indent=4,
1952 separators=( ',', ': ' ) ) )
1953 elif intentsResults and consistentIntents:
1954 intentCheck = main.TRUE
1955
Jon Hall58c76b72015-02-23 11:09:24 -08001956 # NOTE: Store has no durability, so intents are lost across system
1957 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 """
1959 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001960 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001961 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001962 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001963 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001964 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001965 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001966 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001967 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001968 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1969 sameIntents = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001970 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001971 before = json.loads( intentState )
1972 after = json.loads( ONOSIntents[ 0 ] )
1973 for intent in before:
1974 if intent not in after:
1975 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001976 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001977 "(at least in the same form):" )
1978 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001979 except ( ValueError, TypeError ):
1980 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001981 main.log.debug( repr( ONOSIntents[0] ) )
1982 main.log.debug( repr( intentState ) )
1983 if sameIntents == main.FALSE:
1984 try:
1985 main.log.debug( "ONOS intents before: " )
1986 main.log.debug( json.dumps( json.loads( intentState ),
1987 sort_keys=True, indent=4,
1988 separators=( ',', ': ' ) ) )
1989 main.log.debug( "Current ONOS intents: " )
1990 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1991 sort_keys=True, indent=4,
1992 separators=( ',', ': ' ) ) )
1993 except ( ValueError, TypeError ):
1994 main.log.exception( "Exception printing intents" )
1995 main.log.debug( repr( ONOSIntents[0] ) )
1996 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001997 utilities.assert_equals(
1998 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001999 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 onpass="Intents are consistent with before failure",
2001 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002002 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 """
2004 main.step( "Get the OF Table entries and compare to before " +
2005 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002006 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002007 flows2 = []
2008 for i in range( 28 ):
2009 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002010 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
2011 flows2.append( tmpFlows )
2012 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08002013 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 flow2=tmpFlows )
2015 FlowTables = FlowTables and tempResult
2016 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002017 main.log.info( "Differences in flow table for switch: s" +
2018 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002019 utilities.assert_equals(
2020 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002021 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08002022 onpass="No changes were found in the flow tables",
2023 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002024
Jon Hall40d2cbd2015-06-03 16:24:29 -07002025 # main.step( "Check the continuous pings to ensure that no packets " +
2026 # "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002027 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2028 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08002029 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002030 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2031 for i in range( 8, 18 ):
2032 main.log.info(
2033 "Checking for a loss in pings along flow from s" +
2034 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002035 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08002036 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002037 str( i ) ) or LossInPings
2038 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002039 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002040 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08002041 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002042 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002043 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002044 main.log.info( "No loss of dataplane connectivity" )
2045 # utilities.assert_equals(
2046 # expect=main.FALSE,
2047 # actual=LossInPings,
2048 # onpass="No Loss of connectivity",
2049 # onfail="Loss of dataplane connectivity detected" )
2050
Jon Hall58c76b72015-02-23 11:09:24 -08002051 # NOTE: Since intents are not persisted with IntnentStore,
2052 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08002053 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002054
Jon Hall390696c2015-05-05 17:13:41 -07002055 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002056 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08002057 leaderList = []
2058 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002059 for cli in CLIs:
2060 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08002061 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002062 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002063 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07002064 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002065 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002066 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002067 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002068 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002069 main.log.error( cli.name +
2070 " shows no leader for the election-app." )
Jon Hall8f89dda2015-01-22 16:03:33 -08002071 leaderResult = main.FALSE
2072 if len( set( leaderList ) ) != 1:
2073 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002074 main.log.error(
2075 "Inconsistent view of leader for the election test app" )
2076 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002077 utilities.assert_equals(
2078 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002079 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002080 onpass="Leadership election passed",
2081 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002082
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 def CASE8( self, main ):
2084 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002085 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002086 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002087 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08002088 # FIXME add this path to params
2089 sys.path.append( "/home/admin/sts" )
2090 # assumes that sts is already in you PYTHONPATH
2091 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08002092 import json
2093 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002094 assert numControllers, "numControllers not defined"
2095 assert main, "main not defined"
2096 assert utilities.assert_equals, "utilities.assert_equals not defined"
2097 assert CLIs, "CLIs not defined"
2098 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002099
Jon Hallfeff3082015-05-19 10:23:26 -07002100 main.case( "Compare ONOS Topology view to Mininet topology" )
2101 main.caseExplaination = "Compare topology objects between Mininet" +\
2102 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08002103 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07002104 try:
2105 ctrls = []
2106 for node in nodes:
2107 temp = ( node, node.name, node.ip_address, 6633 )
2108 ctrls.append( temp )
2109 MNTopo = TestONTopology( main.Mininet1, ctrls )
2110 except Exception:
2111 objResult = main.FALSE
2112 else:
2113 objResult = main.TRUE
2114 utilities.assert_equals( expect=main.TRUE, actual=objResult,
2115 onpass="Created TestONTopology object",
2116 onfail="Exception while creating " +
2117 "TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002118
Jon Hallfeff3082015-05-19 10:23:26 -07002119 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002120 devicesResults = main.TRUE
2121 portsResults = main.TRUE
2122 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002123 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002124 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002125 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002126 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002127 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002128 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002129 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002130 # Give time for Gossip to work
Jon Hallc9eabec2015-06-10 14:33:14 -07002131 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002132 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08002133 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002134 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08002135 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002136 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002137 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002138 threads = []
2139 for i in range( numControllers ):
2140 t = main.Thread( target=CLIs[i].devices,
2141 name="devices-" + str( i ),
2142 args=[ ] )
2143 threads.append( t )
2144 t.start()
2145
2146 for t in threads:
2147 t.join()
2148 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002149 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002150 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002151 threads = []
2152 for i in range( numControllers ):
2153 t = main.Thread( target=CLIs[i].hosts,
2154 name="hosts-" + str( i ),
2155 args=[ ] )
2156 threads.append( t )
2157 t.start()
2158
2159 for t in threads:
2160 t.join()
2161 try:
2162 hosts.append( json.loads( t.result ) )
2163 except ( ValueError, TypeError ):
2164 main.log.exception( "Error parsing hosts results" )
2165 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002166 for controller in range( 0, len( hosts ) ):
2167 controllerStr = str( controller + 1 )
2168 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002169 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002170 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07002171 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002172 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002173 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002174 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002175 threads = []
2176 for i in range( numControllers ):
2177 t = main.Thread( target=CLIs[i].ports,
2178 name="ports-" + str( i ),
2179 args=[ ] )
2180 threads.append( t )
2181 t.start()
2182
2183 for t in threads:
2184 t.join()
2185 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002186 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002187 threads = []
2188 for i in range( numControllers ):
2189 t = main.Thread( target=CLIs[i].links,
2190 name="links-" + str( i ),
2191 args=[ ] )
2192 threads.append( t )
2193 t.start()
2194
2195 for t in threads:
2196 t.join()
2197 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002198 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002199 threads = []
2200 for i in range( numControllers ):
2201 t = main.Thread( target=CLIs[i].clusters,
2202 name="clusters-" + str( i ),
2203 args=[ ] )
2204 threads.append( t )
2205 t.start()
2206
2207 for t in threads:
2208 t.join()
2209 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002210
Jon Hall8f89dda2015-01-22 16:03:33 -08002211 elapsed = time.time() - startTime
2212 cliTime = time.time() - cliStart
Jon Hall40d2cbd2015-06-03 16:24:29 -07002213 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002214 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002215
Jon Hall8f89dda2015-01-22 16:03:33 -08002216 for controller in range( numControllers ):
2217 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002218 if devices[ controller ] or "Error" not in devices[
2219 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002220 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002221 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002222 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002223 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002224 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002225 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002226 actual=currentDevicesResult,
2227 onpass="ONOS" + controllerStr +
2228 " Switches view is correct",
2229 onfail="ONOS" + controllerStr +
2230 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002231
Jon Hall6aec96b2015-01-19 14:49:31 -08002232 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002233 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002234 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002235 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002236 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002237 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002238 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002239 actual=currentPortsResult,
2240 onpass="ONOS" + controllerStr +
2241 " ports view is correct",
2242 onfail="ONOS" + controllerStr +
2243 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002244
Jon Hall6aec96b2015-01-19 14:49:31 -08002245 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002246 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002247 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002248 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002249 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002250 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002251 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002252 actual=currentLinksResult,
2253 onpass="ONOS" + controllerStr +
2254 " links view is correct",
2255 onfail="ONOS" + controllerStr +
2256 " links view is incorrect" )
2257
2258 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2259 currentHostsResult = main.Mininet1.compareHosts(
2260 MNTopo, hosts[ controller ] )
2261 else:
2262 currentHostsResult = main.FALSE
2263 utilities.assert_equals( expect=main.TRUE,
2264 actual=currentHostsResult,
2265 onpass="ONOS" + controllerStr +
2266 " hosts exist in Mininet",
2267 onfail="ONOS" + controllerStr +
2268 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002269 # CHECKING HOST ATTACHMENT POINTS
2270 hostAttachment = True
2271 zeroHosts = False
2272 # FIXME: topo-HA/obelisk specific mappings:
2273 # key is mac and value is dpid
2274 mappings = {}
2275 for i in range( 1, 29 ): # hosts 1 through 28
2276 # set up correct variables:
2277 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2278 if i == 1:
2279 deviceId = "1000".zfill(16)
2280 elif i == 2:
2281 deviceId = "2000".zfill(16)
2282 elif i == 3:
2283 deviceId = "3000".zfill(16)
2284 elif i == 4:
2285 deviceId = "3004".zfill(16)
2286 elif i == 5:
2287 deviceId = "5000".zfill(16)
2288 elif i == 6:
2289 deviceId = "6000".zfill(16)
2290 elif i == 7:
2291 deviceId = "6007".zfill(16)
2292 elif i >= 8 and i <= 17:
2293 dpid = '3' + str( i ).zfill( 3 )
2294 deviceId = dpid.zfill(16)
2295 elif i >= 18 and i <= 27:
2296 dpid = '6' + str( i ).zfill( 3 )
2297 deviceId = dpid.zfill(16)
2298 elif i == 28:
2299 deviceId = "2800".zfill(16)
2300 mappings[ macId ] = deviceId
2301 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2302 if hosts[ controller ] == []:
2303 main.log.warn( "There are no hosts discovered" )
2304 zeroHosts = True
2305 else:
2306 for host in hosts[ controller ]:
2307 mac = None
2308 location = None
2309 device = None
2310 port = None
2311 try:
2312 mac = host.get( 'mac' )
2313 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002314
Jon Hallc9eabec2015-06-10 14:33:14 -07002315 location = host.get( 'location' )
2316 assert location, "location field could not be found for this host object"
2317
2318 # Trim the protocol identifier off deviceId
2319 device = str( location.get( 'elementId' ) ).split(':')[1]
2320 assert device, "elementId field could not be found for this host location object"
2321
2322 port = location.get( 'port' )
2323 assert port, "port field could not be found for this host location object"
2324
2325 # Now check if this matches where they should be
2326 if mac and device and port:
2327 if str( port ) != "1":
2328 main.log.error( "The attachment port is incorrect for " +
2329 "host " + str( mac ) +
2330 ". Expected: 1 Actual: " + str( port) )
2331 hostAttachment = False
2332 if device != mappings[ str( mac ) ]:
2333 main.log.error( "The attachment device is incorrect for " +
2334 "host " + str( mac ) +
2335 ". Expected: " + mappings[ str( mac ) ] +
2336 " Actual: " + device )
2337 hostAttachment = False
2338 else:
2339 hostAttachment = False
2340 except AssertionError:
2341 main.log.exception( "Json object not as expected" )
2342 main.log.error( repr( host ) )
2343 hostAttachment = False
2344 else:
2345 main.log.error( "No hosts json output or \"Error\"" +
2346 " in output. hosts = " +
2347 repr( hosts[ controller ] ) )
2348 if zeroHosts:
2349 # TODO: Find a way to know if there should be hosts in a
2350 # given point of the test
2351 hostAttachment = True
2352
2353 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002354 devicesResults = devicesResults and currentDevicesResult
2355 portsResults = portsResults and currentPortsResult
2356 linksResults = linksResults and currentLinksResult
2357 hostsResults = hostsResults and currentHostsResult
Jon Hallc9eabec2015-06-10 14:33:14 -07002358 hostAttachmentResults = hostAttachmentResults and hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002359
Jon Hallc9eabec2015-06-10 14:33:14 -07002360 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002361
Jon Hallc9eabec2015-06-10 14:33:14 -07002362 # hosts
2363 main.step( "Hosts view is consistent across all ONOS nodes" )
2364 consistentHostsResult = main.TRUE
2365 for controller in range( len( hosts ) ):
2366 controllerStr = str( controller + 1 )
2367 if "Error" not in hosts[ controller ]:
2368 if hosts[ controller ] == hosts[ 0 ]:
2369 continue
2370 else: # hosts not consistent
2371 main.log.error( "hosts from ONOS" + controllerStr +
2372 " is inconsistent with ONOS1" )
2373 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002374 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002375
Jon Hallc9eabec2015-06-10 14:33:14 -07002376 else:
2377 main.log.error( "Error in getting ONOS hosts from ONOS" +
2378 controllerStr )
2379 consistentHostsResult = main.FALSE
2380 main.log.warn( "ONOS" + controllerStr +
2381 " hosts response: " +
2382 repr( hosts[ controller ] ) )
2383 utilities.assert_equals(
2384 expect=main.TRUE,
2385 actual=consistentHostsResult,
2386 onpass="Hosts view is consistent across all ONOS nodes",
2387 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002388
Jon Hallc9eabec2015-06-10 14:33:14 -07002389 main.step( "Hosts information is correct" )
2390 hostsResults = hostsResults and ipResult
2391 utilities.assert_equals(
2392 expect=main.TRUE,
2393 actual=hostsResults,
2394 onpass="Host information is correct",
2395 onfail="Host information is incorrect" )
2396
2397 main.step( "Host attachment points to the network" )
2398 utilities.assert_equals(
2399 expect=True,
2400 actual=hostAttachmentResults,
2401 onpass="Hosts are correctly attached to the network",
2402 onfail="ONOS did not correctly attach hosts to the network" )
2403
2404 # Strongly connected clusters of devices
2405 main.step( "Clusters view is consistent across all ONOS nodes" )
2406 consistentClustersResult = main.TRUE
2407 for controller in range( len( clusters ) ):
2408 controllerStr = str( controller + 1 )
2409 if "Error" not in clusters[ controller ]:
2410 if clusters[ controller ] == clusters[ 0 ]:
2411 continue
2412 else: # clusters not consistent
2413 main.log.error( "clusters from ONOS" +
2414 controllerStr +
2415 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002416 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002417
Jon Hallc9eabec2015-06-10 14:33:14 -07002418 else:
2419 main.log.error( "Error in getting dataplane clusters " +
2420 "from ONOS" + controllerStr )
2421 consistentClustersResult = main.FALSE
2422 main.log.warn( "ONOS" + controllerStr +
2423 " clusters response: " +
2424 repr( clusters[ controller ] ) )
2425 utilities.assert_equals(
2426 expect=main.TRUE,
2427 actual=consistentClustersResult,
2428 onpass="Clusters view is consistent across all ONOS nodes",
2429 onfail="ONOS nodes have different views of clusters" )
2430
2431 main.step( "There is only one SCC" )
2432 # there should always only be one cluster
2433 try:
2434 numClusters = len( json.loads( clusters[ 0 ] ) )
2435 except ( ValueError, TypeError ):
2436 main.log.exception( "Error parsing clusters[0]: " +
2437 repr( clusters[0] ) )
2438 clusterResults = main.FALSE
2439 if numClusters == 1:
2440 clusterResults = main.TRUE
2441 utilities.assert_equals(
2442 expect=1,
2443 actual=numClusters,
2444 onpass="ONOS shows 1 SCC",
2445 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2446
2447 topoResult = ( devicesResults and portsResults and linksResults
2448 and hostsResults and consistentHostsResult
2449 and consistentClustersResult and clusterResults
2450 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002451
Jon Hall8f89dda2015-01-22 16:03:33 -08002452 topoResult = topoResult and int( count <= 2 )
2453 note = "note it takes about " + str( int( cliTime ) ) + \
2454 " seconds for the test to make all the cli calls to fetch " +\
2455 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002456 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002457 "Very crass estimate for topology discovery/convergence( " +
2458 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002459 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002460
2461 main.step( "Device information is correct" )
2462 utilities.assert_equals(
2463 expect=main.TRUE,
2464 actual=devicesResults,
2465 onpass="Device information is correct",
2466 onfail="Device information is incorrect" )
2467
2468 main.step( "Port information is correct" )
2469 utilities.assert_equals(
2470 expect=main.TRUE,
2471 actual=portsResults,
2472 onpass="Port information is correct",
2473 onfail="Port information is incorrect" )
2474
2475 main.step( "Links are correct" )
2476 utilities.assert_equals(
2477 expect=main.TRUE,
2478 actual=linksResults,
2479 onpass="Link are correct",
2480 onfail="Links are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002481
Jon Halla9d26da2015-03-30 16:45:32 -07002482 # FIXME: move this to an ONOS state case
2483 main.step( "Checking ONOS nodes" )
2484 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002485 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002486 threads = []
2487 for i in range( numControllers ):
2488 t = main.Thread( target=CLIs[i].nodes,
2489 name="nodes-" + str( i ),
2490 args=[ ] )
2491 threads.append( t )
2492 t.start()
2493
2494 for t in threads:
2495 t.join()
2496 nodesOutput.append( t.result )
2497 ips = [ node.ip_address for node in nodes ]
2498 for i in nodesOutput:
2499 try:
2500 current = json.loads( i )
2501 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002502 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002503 if node['ip'] in ips: # node in nodes() output is in cell
2504 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002505 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002506 else:
2507 main.log.error( "Error in ONOS node availability" )
2508 main.log.error(
2509 json.dumps( current,
2510 sort_keys=True,
2511 indent=4,
2512 separators=( ',', ': ' ) ) )
2513 break
Jon Hall390696c2015-05-05 17:13:41 -07002514 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002515 except ( ValueError, TypeError ):
2516 main.log.error( "Error parsing nodes output" )
2517 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002518 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2519 onpass="Nodes check successful",
2520 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002521
Jon Hall6aec96b2015-01-19 14:49:31 -08002522 def CASE9( self, main ):
2523 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002524 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002525 """
2526 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002527 assert numControllers, "numControllers not defined"
2528 assert main, "main not defined"
2529 assert utilities.assert_equals, "utilities.assert_equals not defined"
2530 assert CLIs, "CLIs not defined"
2531 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002533
Jon Hall8f89dda2015-01-22 16:03:33 -08002534 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002535
Jon Hall6aec96b2015-01-19 14:49:31 -08002536 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002537 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002538 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002539
Jon Hall6aec96b2015-01-19 14:49:31 -08002540 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002541 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002542 main.log.info( "Waiting " + str( linkSleep ) +
2543 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002544 time.sleep( linkSleep )
2545 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002546 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002547 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002548 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002549
Jon Hall6aec96b2015-01-19 14:49:31 -08002550 def CASE10( self, main ):
2551 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002552 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002553 """
2554 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002555 assert numControllers, "numControllers not defined"
2556 assert main, "main not defined"
2557 assert utilities.assert_equals, "utilities.assert_equals not defined"
2558 assert CLIs, "CLIs not defined"
2559 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002560 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002561
Jon Hall8f89dda2015-01-22 16:03:33 -08002562 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002563
Jon Hall6aec96b2015-01-19 14:49:31 -08002564 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002565 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002566 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002567
Jon Hall6aec96b2015-01-19 14:49:31 -08002568 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002569 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002570 main.log.info( "Waiting " + str( linkSleep ) +
2571 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002572 time.sleep( linkSleep )
2573 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002574 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002575 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002576 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002577
Jon Hall6aec96b2015-01-19 14:49:31 -08002578 def CASE11( self, main ):
2579 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002580 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002581 """
2582 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002583 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002584 assert numControllers, "numControllers not defined"
2585 assert main, "main not defined"
2586 assert utilities.assert_equals, "utilities.assert_equals not defined"
2587 assert CLIs, "CLIs not defined"
2588 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002589
Jon Hall8f89dda2015-01-22 16:03:33 -08002590 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002591
2592 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 main.case( description )
2594 switch = main.params[ 'kill' ][ 'switch' ]
2595 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002596
Jon Hall6aec96b2015-01-19 14:49:31 -08002597 # TODO: Make this switch parameterizable
2598 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002599 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002600 main.Mininet1.delSwitch( switch )
2601 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002602 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002603 time.sleep( switchSleep )
2604 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002605 # Peek at the deleted switch
2606 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002607 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002608 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002609 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002610 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002611 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002612 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002613
Jon Hall6aec96b2015-01-19 14:49:31 -08002614 def CASE12( self, main ):
2615 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002616 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002617 """
2618 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002619 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002620 assert numControllers, "numControllers not defined"
2621 assert main, "main not defined"
2622 assert utilities.assert_equals, "utilities.assert_equals not defined"
2623 assert CLIs, "CLIs not defined"
2624 assert nodes, "nodes not defined"
2625 assert ONOS1Port, "ONOS1Port not defined"
2626 assert ONOS2Port, "ONOS2Port not defined"
2627 assert ONOS3Port, "ONOS3Port not defined"
2628 assert ONOS4Port, "ONOS4Port not defined"
2629 assert ONOS5Port, "ONOS5Port not defined"
2630 assert ONOS6Port, "ONOS6Port not defined"
2631 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002632
Jon Hall8f89dda2015-01-22 16:03:33 -08002633 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002634 switch = main.params[ 'kill' ][ 'switch' ]
2635 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2636 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002637 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002638 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002639
Jon Hall6aec96b2015-01-19 14:49:31 -08002640 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002641 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002642 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002643 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002644 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2645 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002646 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002647 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002648 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002649 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002650 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002651 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002652 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002653 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002654 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002655 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002656 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002657 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002658 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002659 port7=ONOS7Port )
2660 main.log.info( "Waiting " + str( switchSleep ) +
2661 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002662 time.sleep( switchSleep )
2663 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002664 # Peek at the deleted switch
2665 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002666 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002667 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002668 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002669 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002670 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002671 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002672
Jon Hall6aec96b2015-01-19 14:49:31 -08002673 def CASE13( self, main ):
2674 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002675 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002676 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002677 import os
2678 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002679 assert numControllers, "numControllers not defined"
2680 assert main, "main not defined"
2681 assert utilities.assert_equals, "utilities.assert_equals not defined"
2682 assert CLIs, "CLIs not defined"
2683 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002684
2685 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002686 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2687 'blue': '\033[94m', 'green': '\033[92m',
2688 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002689 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002690 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002691 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002692
Jon Hall6aec96b2015-01-19 14:49:31 -08002693 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002694 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002695 teststationUser = main.params[ 'TESTONUSER' ]
2696 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002697 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002698 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002699 # FIXME: scp
2700 # mn files
2701 # TODO: Load these from params
2702 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002703 logFolder = "/opt/onos/log/"
2704 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002705 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002706 dstDir = "~/packet_captures/"
2707 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002708 for node in nodes:
2709 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2710 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002711 teststationUser + "@" +
2712 teststationIP + ":" +
2713 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002714 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002715 main.ONOSbench.handle.expect( "\$" )
2716
Jon Hall6aec96b2015-01-19 14:49:31 -08002717 # std*.log's
2718 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002719 logFolder = "/opt/onos/var/"
2720 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002721 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002722 dstDir = "~/packet_captures/"
2723 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002724 for node in nodes:
2725 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2726 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002727 teststationUser + "@" +
2728 teststationIP + ":" +
2729 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002730 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002731 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002732 # sleep so scp can finish
2733 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002734
2735 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002736 mnResult = main.Mininet1.stopNet()
2737 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2738 onpass="Mininet stopped",
2739 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002740
2741 main.step( "Checking ONOS Logs for errors" )
2742 for node in nodes:
2743 print colors[ 'purple' ] + "Checking logs for errors on " + \
2744 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002745 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002746
Jon Hall6aec96b2015-01-19 14:49:31 -08002747 main.step( "Packing and rotating pcap archives" )
2748 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002749
Jon Hallfeff3082015-05-19 10:23:26 -07002750 try:
2751 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hallc9eabec2015-06-10 14:33:14 -07002752 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2753 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
Jon Hallfeff3082015-05-19 10:23:26 -07002754 timerLog.close()
2755 except NameError, e:
2756 main.log.exception(e)
2757
Jon Hall6aec96b2015-01-19 14:49:31 -08002758 def CASE14( self, main ):
2759 """
Jon Hall669173b2014-12-17 11:36:30 -08002760 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002761 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002762 assert numControllers, "numControllers not defined"
2763 assert main, "main not defined"
2764 assert utilities.assert_equals, "utilities.assert_equals not defined"
2765 assert CLIs, "CLIs not defined"
2766 assert nodes, "nodes not defined"
2767
Jon Hall390696c2015-05-05 17:13:41 -07002768 main.case("Start Leadership Election app")
2769 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002770 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2771 utilities.assert_equals(
2772 expect=main.TRUE,
2773 actual=appResult,
2774 onpass="Election app installed",
2775 onfail="Something went wrong with installing Leadership election" )
2776
2777 main.step( "Run for election on each node" )
2778 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002779 leaders = []
2780 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002781 cli.electionTestRun()
2782 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002783 leader = cli.electionTestLeader()
2784 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002785 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002786 "should be an ONOS node, instead got '" +
2787 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002788 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002789 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002790 utilities.assert_equals(
2791 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002792 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002793 onpass="Successfully ran for leadership",
2794 onfail="Failed to run for leadership" )
2795
2796 main.step( "Check that each node shows the same leader" )
2797 sameLeader = main.TRUE
2798 if len( set( leaders ) ) != 1:
2799 sameLeader = main.FALSE
2800 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2801 str( leaders ) )
2802 utilities.assert_equals(
2803 expect=main.TRUE,
2804 actual=sameLeader,
2805 onpass="Leadership is consistent for the election topic",
2806 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002807
Jon Hall6aec96b2015-01-19 14:49:31 -08002808 def CASE15( self, main ):
2809 """
Jon Hall669173b2014-12-17 11:36:30 -08002810 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002811 """
Jon Hall390696c2015-05-05 17:13:41 -07002812 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002813 assert numControllers, "numControllers not defined"
2814 assert main, "main not defined"
2815 assert utilities.assert_equals, "utilities.assert_equals not defined"
2816 assert CLIs, "CLIs not defined"
2817 assert nodes, "nodes not defined"
2818
Jon Hall8f89dda2015-01-22 16:03:33 -08002819 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002820 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002821 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002822 # NOTE: Need to re-run since being a canidate is not persistant
2823 main.step( "Run for election on each node" )
2824 leaderResult = main.TRUE
2825 leaders = []
2826 for cli in CLIs:
2827 cli.electionTestRun()
2828 for cli in CLIs:
2829 leader = cli.electionTestLeader()
2830 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002831 main.log.error( cli.name + ": Leader for the election app " +
Jon Hallfeff3082015-05-19 10:23:26 -07002832 "should be an ONOS node, instead got '" +
2833 str( leader ) + "'" )
2834 leaderResult = main.FALSE
2835 leaders.append( leader )
2836 utilities.assert_equals(
2837 expect=main.TRUE,
2838 actual=leaderResult,
2839 onpass="Successfully ran for leadership",
2840 onfail="Failed to run for leadership" )
2841
2842 main.step( "Check that each node shows the same leader" )
2843 sameLeader = main.TRUE
2844 if len( set( leaders ) ) != 1:
2845 sameLeader = main.FALSE
2846 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2847 str( leaders ) )
2848 utilities.assert_equals(
2849 expect=main.TRUE,
2850 actual=sameLeader,
2851 onpass="Leadership is consistent for the election topic",
2852 onfail="Nodes have different leaders" )
2853
Jon Hall6aec96b2015-01-19 14:49:31 -08002854 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002855 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002856 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002857 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002858 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002859 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002860 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002861 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002862 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002863 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002864 for i in range( len( CLIs ) ):
2865 if leader == nodes[ i ].ip_address:
2866 oldLeader = CLIs[ i ]
2867 break
Jon Halla9d26da2015-03-30 16:45:32 -07002868 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002869 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002870 if oldLeader:
2871 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002872 utilities.assert_equals(
2873 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002874 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002875 onpass="Node was withdrawn from election",
2876 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002877
Jon Hall6aec96b2015-01-19 14:49:31 -08002878 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002879 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002880 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002881 for cli in CLIs:
2882 leaderN = cli.electionTestLeader()
2883 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002884 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002885 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002886 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002887 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002888 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002889 # error in response
2890 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002891 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002892 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002893 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002894 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002895 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002896 elif leaderN is None:
2897 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002898 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002899 leaderN = cli.electionTestLeader()
2900 leaderList.pop()
2901 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002902 consistentLeader = main.FALSE
2903 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002904 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002905 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002906 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002907 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002908 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002909 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002910 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002911 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002912 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002913 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002914 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002915 utilities.assert_equals(
2916 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002917 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002918 onpass="Leadership election passed",
2919 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002920
Jon Hall58c76b72015-02-23 11:09:24 -08002921 main.step( "Run for election on old leader( just so everyone " +
2922 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002923 if oldLeader:
2924 runResult = oldLeader.electionTestRun()
2925 else:
2926 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002927 utilities.assert_equals(
2928 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002929 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002930 onpass="App re-ran for election",
2931 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002932
Jon Hallfeff3082015-05-19 10:23:26 -07002933 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002934 afterRun = main.ONOScli1.electionTestLeader()
2935 # verify leader didn't just change
2936 if afterRun == leaderList[ 0 ]:
2937 afterResult = main.TRUE
2938 else:
2939 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002940
Jon Hall6aec96b2015-01-19 14:49:31 -08002941 utilities.assert_equals(
2942 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002943 actual=afterResult,
2944 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002945 onfail="Something went wrong with Leadership election after " +
2946 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002947
Jon Hall390696c2015-05-05 17:13:41 -07002948 def CASE16( self, main ):
2949 """
2950 Install Distributed Primitives app
2951 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002952 import time
Jon Hall390696c2015-05-05 17:13:41 -07002953 assert numControllers, "numControllers not defined"
2954 assert main, "main not defined"
2955 assert utilities.assert_equals, "utilities.assert_equals not defined"
2956 assert CLIs, "CLIs not defined"
2957 assert nodes, "nodes not defined"
2958
2959 # Variables for the distributed primitives tests
2960 global pCounterName
2961 global iCounterName
2962 global pCounterValue
2963 global iCounterValue
2964 global onosSet
2965 global onosSetName
2966 pCounterName = "TestON-Partitions"
2967 iCounterName = "TestON-inMemory"
2968 pCounterValue = 0
2969 iCounterValue = 0
2970 onosSet = set([])
2971 onosSetName = "TestON-set"
2972
2973 description = "Install Primitives app"
2974 main.case( description )
2975 main.step( "Install Primitives app" )
2976 appName = "org.onosproject.distributedprimitives"
2977 appResults = CLIs[0].activateApp( appName )
2978 utilities.assert_equals( expect=main.TRUE,
2979 actual=appResults,
2980 onpass="Primitives app activated",
2981 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002982 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002983
2984 def CASE17( self, main ):
2985 """
2986 Check for basic functionality with distributed primitives
2987 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002988 import json
Jon Hall390696c2015-05-05 17:13:41 -07002989 # Make sure variables are defined/set
2990 assert numControllers, "numControllers not defined"
2991 assert main, "main not defined"
2992 assert utilities.assert_equals, "utilities.assert_equals not defined"
2993 assert CLIs, "CLIs not defined"
2994 assert nodes, "nodes not defined"
2995 assert pCounterName, "pCounterName not defined"
2996 assert iCounterName, "iCounterName not defined"
2997 assert onosSetName, "onosSetName not defined"
2998 # NOTE: assert fails if value is 0/None/Empty/False
2999 try:
3000 pCounterValue
3001 except NameError:
3002 main.log.error( "pCounterValue not defined, setting to 0" )
3003 pCounterValue = 0
3004 try:
3005 iCounterValue
3006 except NameError:
3007 main.log.error( "iCounterValue not defined, setting to 0" )
3008 iCounterValue = 0
3009 try:
3010 onosSet
3011 except NameError:
3012 main.log.error( "onosSet not defined, setting to empty Set" )
3013 onosSet = set([])
3014 # Variables for the distributed primitives tests. These are local only
3015 addValue = "a"
3016 addAllValue = "a b c d e f"
3017 retainValue = "c d e f"
3018
3019 description = "Check for basic functionality with distributed " +\
3020 "primitives"
3021 main.case( description )
3022 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
3023 # DISTRIBUTED ATOMIC COUNTERS
3024 main.step( "Increment and get a default counter on each node" )
3025 pCounters = []
3026 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07003027 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07003028 for i in range( numControllers ):
3029 t = main.Thread( target=CLIs[i].counterTestIncrement,
3030 name="counterIncrement-" + str( i ),
3031 args=[ pCounterName ] )
3032 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07003033 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07003034 threads.append( t )
3035 t.start()
3036
3037 for t in threads:
3038 t.join()
3039 pCounters.append( t.result )
3040 # Check that counter incremented numController times
3041 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07003042 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003043 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07003044 pCounterResults = pCounterResults and tmpResult
3045 if not tmpResult:
3046 main.log.error( str( i ) + " is not in partitioned "
3047 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07003048 utilities.assert_equals( expect=True,
3049 actual=pCounterResults,
3050 onpass="Default counter incremented",
3051 onfail="Error incrementing default" +
3052 " counter" )
3053
3054 main.step( "Increment and get an in memory counter on each node" )
3055 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07003056 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07003057 threads = []
3058 for i in range( numControllers ):
3059 t = main.Thread( target=CLIs[i].counterTestIncrement,
3060 name="icounterIncrement-" + str( i ),
3061 args=[ iCounterName ],
3062 kwargs={ "inMemory": True } )
3063 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07003064 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07003065 threads.append( t )
3066 t.start()
3067
3068 for t in threads:
3069 t.join()
3070 iCounters.append( t.result )
3071 # Check that counter incremented numController times
3072 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07003073 for i in addedIValues:
3074 tmpResult = i in iCounters
3075 iCounterResults = iCounterResults and tmpResult
3076 if not tmpResult:
3077 main.log.error( str( i ) + " is not in the in-memory "
3078 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07003079 utilities.assert_equals( expect=True,
3080 actual=iCounterResults,
3081 onpass="In memory counter incremented",
3082 onfail="Error incrementing in memory" +
3083 " counter" )
3084
3085 main.step( "Check counters are consistant across nodes" )
3086 onosCounters = []
3087 threads = []
3088 for i in range( numControllers ):
3089 t = main.Thread( target=CLIs[i].counters,
3090 name="counters-" + str( i ) )
3091 threads.append( t )
3092 t.start()
3093 for t in threads:
3094 t.join()
3095 onosCounters.append( t.result )
3096 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3097 if all( tmp ):
3098 main.log.info( "Counters are consistent across all nodes" )
3099 consistentCounterResults = main.TRUE
3100 else:
3101 main.log.error( "Counters are not consistent across all nodes" )
3102 consistentCounterResults = main.FALSE
3103 utilities.assert_equals( expect=main.TRUE,
3104 actual=consistentCounterResults,
3105 onpass="ONOS counters are consistent " +
3106 "across nodes",
3107 onfail="ONOS Counters are inconsistent " +
3108 "across nodes" )
3109
3110 main.step( "Counters we added have the correct values" )
3111 correctResults = main.TRUE
3112 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07003113 current = json.loads( onosCounters[i] )
3114 pValue = None
3115 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003116 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003117 for database in current:
3118 partitioned = database.get( 'partitionedDatabaseCounters' )
3119 if partitioned:
3120 for value in partitioned:
3121 if value.get( 'name' ) == pCounterName:
3122 pValue = value.get( 'value' )
3123 break
3124 inMemory = database.get( 'inMemoryDatabaseCounters' )
3125 if inMemory:
3126 for value in inMemory:
3127 if value.get( 'name' ) == iCounterName:
3128 iValue = value.get( 'value' )
3129 break
Jon Hall390696c2015-05-05 17:13:41 -07003130 except AttributeError, e:
3131 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3132 "is not as expected" )
3133 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003134 if pValue == pCounterValue:
3135 main.log.info( "Partitioned counter value is correct" )
3136 else:
3137 main.log.error( "Partitioned counter value is incorrect," +
3138 " expected value: " + str( pCounterValue )
3139 + " current value: " + str( pValue ) )
3140 correctResults = main.FALSE
3141 if iValue == iCounterValue:
3142 main.log.info( "In memory counter value is correct" )
3143 else:
3144 main.log.error( "In memory counter value is incorrect, " +
3145 "expected value: " + str( iCounterValue ) +
3146 " current value: " + str( iValue ) )
3147 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003148 utilities.assert_equals( expect=main.TRUE,
3149 actual=correctResults,
3150 onpass="Added counters are correct",
3151 onfail="Added counters are incorrect" )
3152 # DISTRIBUTED SETS
3153 main.step( "Distributed Set get" )
3154 size = len( onosSet )
3155 getResponses = []
3156 threads = []
3157 for i in range( numControllers ):
3158 t = main.Thread( target=CLIs[i].setTestGet,
3159 name="setTestGet-" + str( i ),
3160 args=[ onosSetName ] )
3161 threads.append( t )
3162 t.start()
3163 for t in threads:
3164 t.join()
3165 getResponses.append( t.result )
3166
3167 getResults = main.TRUE
3168 for i in range( numControllers ):
3169 if isinstance( getResponses[ i ], list):
3170 current = set( getResponses[ i ] )
3171 if len( current ) == len( getResponses[ i ] ):
3172 # no repeats
3173 if onosSet != current:
3174 main.log.error( "ONOS" + str( i + 1 ) +
3175 " has incorrect view" +
3176 " of set " + onosSetName + ":\n" +
3177 str( getResponses[ i ] ) )
3178 main.log.debug( "Expected: " + str( onosSet ) )
3179 main.log.debug( "Actual: " + str( current ) )
3180 getResults = main.FALSE
3181 else:
3182 # error, set is not a set
3183 main.log.error( "ONOS" + str( i + 1 ) +
3184 " has repeat elements in" +
3185 " set " + onosSetName + ":\n" +
3186 str( getResponses[ i ] ) )
3187 getResults = main.FALSE
3188 elif getResponses[ i ] == main.ERROR:
3189 getResults = main.FALSE
3190 utilities.assert_equals( expect=main.TRUE,
3191 actual=getResults,
3192 onpass="Set elements are correct",
3193 onfail="Set elements are incorrect" )
3194
3195 main.step( "Distributed Set size" )
3196 sizeResponses = []
3197 threads = []
3198 for i in range( numControllers ):
3199 t = main.Thread( target=CLIs[i].setTestSize,
3200 name="setTestSize-" + str( i ),
3201 args=[ onosSetName ] )
3202 threads.append( t )
3203 t.start()
3204 for t in threads:
3205 t.join()
3206 sizeResponses.append( t.result )
3207
3208 sizeResults = main.TRUE
3209 for i in range( numControllers ):
3210 if size != sizeResponses[ i ]:
3211 sizeResults = main.FALSE
3212 main.log.error( "ONOS" + str( i + 1 ) +
3213 " expected a size of " + str( size ) +
3214 " for set " + onosSetName +
3215 " but got " + str( sizeResponses[ i ] ) )
3216 utilities.assert_equals( expect=main.TRUE,
3217 actual=sizeResults,
3218 onpass="Set sizes are correct",
3219 onfail="Set sizes are incorrect" )
3220
3221 main.step( "Distributed Set add()" )
3222 onosSet.add( addValue )
3223 addResponses = []
3224 threads = []
3225 for i in range( numControllers ):
3226 t = main.Thread( target=CLIs[i].setTestAdd,
3227 name="setTestAdd-" + str( i ),
3228 args=[ onosSetName, addValue ] )
3229 threads.append( t )
3230 t.start()
3231 for t in threads:
3232 t.join()
3233 addResponses.append( t.result )
3234
3235 # main.TRUE = successfully changed the set
3236 # main.FALSE = action resulted in no change in set
3237 # main.ERROR - Some error in executing the function
3238 addResults = main.TRUE
3239 for i in range( numControllers ):
3240 if addResponses[ i ] == main.TRUE:
3241 # All is well
3242 pass
3243 elif addResponses[ i ] == main.FALSE:
3244 # Already in set, probably fine
3245 pass
3246 elif addResponses[ i ] == main.ERROR:
3247 # Error in execution
3248 addResults = main.FALSE
3249 else:
3250 # unexpected result
3251 addResults = main.FALSE
3252 if addResults != main.TRUE:
3253 main.log.error( "Error executing set add" )
3254
3255 # Check if set is still correct
3256 size = len( onosSet )
3257 getResponses = []
3258 threads = []
3259 for i in range( numControllers ):
3260 t = main.Thread( target=CLIs[i].setTestGet,
3261 name="setTestGet-" + str( i ),
3262 args=[ onosSetName ] )
3263 threads.append( t )
3264 t.start()
3265 for t in threads:
3266 t.join()
3267 getResponses.append( t.result )
3268 getResults = main.TRUE
3269 for i in range( numControllers ):
3270 if isinstance( getResponses[ i ], list):
3271 current = set( getResponses[ i ] )
3272 if len( current ) == len( getResponses[ i ] ):
3273 # no repeats
3274 if onosSet != current:
3275 main.log.error( "ONOS" + str( i + 1 ) +
3276 " has incorrect view" +
3277 " of set " + onosSetName + ":\n" +
3278 str( getResponses[ i ] ) )
3279 main.log.debug( "Expected: " + str( onosSet ) )
3280 main.log.debug( "Actual: " + str( current ) )
3281 getResults = main.FALSE
3282 else:
3283 # error, set is not a set
3284 main.log.error( "ONOS" + str( i + 1 ) +
3285 " has repeat elements in" +
3286 " set " + onosSetName + ":\n" +
3287 str( getResponses[ i ] ) )
3288 getResults = main.FALSE
3289 elif getResponses[ i ] == main.ERROR:
3290 getResults = main.FALSE
3291 sizeResponses = []
3292 threads = []
3293 for i in range( numControllers ):
3294 t = main.Thread( target=CLIs[i].setTestSize,
3295 name="setTestSize-" + str( i ),
3296 args=[ onosSetName ] )
3297 threads.append( t )
3298 t.start()
3299 for t in threads:
3300 t.join()
3301 sizeResponses.append( t.result )
3302 sizeResults = main.TRUE
3303 for i in range( numControllers ):
3304 if size != sizeResponses[ i ]:
3305 sizeResults = main.FALSE
3306 main.log.error( "ONOS" + str( i + 1 ) +
3307 " expected a size of " + str( size ) +
3308 " for set " + onosSetName +
3309 " but got " + str( sizeResponses[ i ] ) )
3310 addResults = addResults and getResults and sizeResults
3311 utilities.assert_equals( expect=main.TRUE,
3312 actual=addResults,
3313 onpass="Set add correct",
3314 onfail="Set add was incorrect" )
3315
3316 main.step( "Distributed Set addAll()" )
3317 onosSet.update( addAllValue.split() )
3318 addResponses = []
3319 threads = []
3320 for i in range( numControllers ):
3321 t = main.Thread( target=CLIs[i].setTestAdd,
3322 name="setTestAddAll-" + str( i ),
3323 args=[ onosSetName, addAllValue ] )
3324 threads.append( t )
3325 t.start()
3326 for t in threads:
3327 t.join()
3328 addResponses.append( t.result )
3329
3330 # main.TRUE = successfully changed the set
3331 # main.FALSE = action resulted in no change in set
3332 # main.ERROR - Some error in executing the function
3333 addAllResults = main.TRUE
3334 for i in range( numControllers ):
3335 if addResponses[ i ] == main.TRUE:
3336 # All is well
3337 pass
3338 elif addResponses[ i ] == main.FALSE:
3339 # Already in set, probably fine
3340 pass
3341 elif addResponses[ i ] == main.ERROR:
3342 # Error in execution
3343 addAllResults = main.FALSE
3344 else:
3345 # unexpected result
3346 addAllResults = main.FALSE
3347 if addAllResults != main.TRUE:
3348 main.log.error( "Error executing set addAll" )
3349
3350 # Check if set is still correct
3351 size = len( onosSet )
3352 getResponses = []
3353 threads = []
3354 for i in range( numControllers ):
3355 t = main.Thread( target=CLIs[i].setTestGet,
3356 name="setTestGet-" + str( i ),
3357 args=[ onosSetName ] )
3358 threads.append( t )
3359 t.start()
3360 for t in threads:
3361 t.join()
3362 getResponses.append( t.result )
3363 getResults = main.TRUE
3364 for i in range( numControllers ):
3365 if isinstance( getResponses[ i ], list):
3366 current = set( getResponses[ i ] )
3367 if len( current ) == len( getResponses[ i ] ):
3368 # no repeats
3369 if onosSet != current:
3370 main.log.error( "ONOS" + str( i + 1 ) +
3371 " has incorrect view" +
3372 " of set " + onosSetName + ":\n" +
3373 str( getResponses[ i ] ) )
3374 main.log.debug( "Expected: " + str( onosSet ) )
3375 main.log.debug( "Actual: " + str( current ) )
3376 getResults = main.FALSE
3377 else:
3378 # error, set is not a set
3379 main.log.error( "ONOS" + str( i + 1 ) +
3380 " has repeat elements in" +
3381 " set " + onosSetName + ":\n" +
3382 str( getResponses[ i ] ) )
3383 getResults = main.FALSE
3384 elif getResponses[ i ] == main.ERROR:
3385 getResults = main.FALSE
3386 sizeResponses = []
3387 threads = []
3388 for i in range( numControllers ):
3389 t = main.Thread( target=CLIs[i].setTestSize,
3390 name="setTestSize-" + str( i ),
3391 args=[ onosSetName ] )
3392 threads.append( t )
3393 t.start()
3394 for t in threads:
3395 t.join()
3396 sizeResponses.append( t.result )
3397 sizeResults = main.TRUE
3398 for i in range( numControllers ):
3399 if size != sizeResponses[ i ]:
3400 sizeResults = main.FALSE
3401 main.log.error( "ONOS" + str( i + 1 ) +
3402 " expected a size of " + str( size ) +
3403 " for set " + onosSetName +
3404 " but got " + str( sizeResponses[ i ] ) )
3405 addAllResults = addAllResults and getResults and sizeResults
3406 utilities.assert_equals( expect=main.TRUE,
3407 actual=addAllResults,
3408 onpass="Set addAll correct",
3409 onfail="Set addAll was incorrect" )
3410
3411 main.step( "Distributed Set contains()" )
3412 containsResponses = []
3413 threads = []
3414 for i in range( numControllers ):
3415 t = main.Thread( target=CLIs[i].setTestGet,
3416 name="setContains-" + str( i ),
3417 args=[ onosSetName ],
3418 kwargs={ "values": addValue } )
3419 threads.append( t )
3420 t.start()
3421 for t in threads:
3422 t.join()
3423 # NOTE: This is the tuple
3424 containsResponses.append( t.result )
3425
3426 containsResults = main.TRUE
3427 for i in range( numControllers ):
3428 if containsResponses[ i ] == main.ERROR:
3429 containsResults = main.FALSE
3430 else:
3431 containsResults = containsResults and\
3432 containsResponses[ i ][ 1 ]
3433 utilities.assert_equals( expect=main.TRUE,
3434 actual=containsResults,
3435 onpass="Set contains is functional",
3436 onfail="Set contains failed" )
3437
3438 main.step( "Distributed Set containsAll()" )
3439 containsAllResponses = []
3440 threads = []
3441 for i in range( numControllers ):
3442 t = main.Thread( target=CLIs[i].setTestGet,
3443 name="setContainsAll-" + str( i ),
3444 args=[ onosSetName ],
3445 kwargs={ "values": addAllValue } )
3446 threads.append( t )
3447 t.start()
3448 for t in threads:
3449 t.join()
3450 # NOTE: This is the tuple
3451 containsAllResponses.append( t.result )
3452
3453 containsAllResults = main.TRUE
3454 for i in range( numControllers ):
3455 if containsResponses[ i ] == main.ERROR:
3456 containsResults = main.FALSE
3457 else:
3458 containsResults = containsResults and\
3459 containsResponses[ i ][ 1 ]
3460 utilities.assert_equals( expect=main.TRUE,
3461 actual=containsAllResults,
3462 onpass="Set containsAll is functional",
3463 onfail="Set containsAll failed" )
3464
3465 main.step( "Distributed Set remove()" )
3466 onosSet.remove( addValue )
3467 removeResponses = []
3468 threads = []
3469 for i in range( numControllers ):
3470 t = main.Thread( target=CLIs[i].setTestRemove,
3471 name="setTestRemove-" + str( i ),
3472 args=[ onosSetName, addValue ] )
3473 threads.append( t )
3474 t.start()
3475 for t in threads:
3476 t.join()
3477 removeResponses.append( t.result )
3478
3479 # main.TRUE = successfully changed the set
3480 # main.FALSE = action resulted in no change in set
3481 # main.ERROR - Some error in executing the function
3482 removeResults = main.TRUE
3483 for i in range( numControllers ):
3484 if removeResponses[ i ] == main.TRUE:
3485 # All is well
3486 pass
3487 elif removeResponses[ i ] == main.FALSE:
3488 # not in set, probably fine
3489 pass
3490 elif removeResponses[ i ] == main.ERROR:
3491 # Error in execution
3492 removeResults = main.FALSE
3493 else:
3494 # unexpected result
3495 removeResults = main.FALSE
3496 if removeResults != main.TRUE:
3497 main.log.error( "Error executing set remove" )
3498
3499 # Check if set is still correct
3500 size = len( onosSet )
3501 getResponses = []
3502 threads = []
3503 for i in range( numControllers ):
3504 t = main.Thread( target=CLIs[i].setTestGet,
3505 name="setTestGet-" + str( i ),
3506 args=[ onosSetName ] )
3507 threads.append( t )
3508 t.start()
3509 for t in threads:
3510 t.join()
3511 getResponses.append( t.result )
3512 getResults = main.TRUE
3513 for i in range( numControllers ):
3514 if isinstance( getResponses[ i ], list):
3515 current = set( getResponses[ i ] )
3516 if len( current ) == len( getResponses[ i ] ):
3517 # no repeats
3518 if onosSet != current:
3519 main.log.error( "ONOS" + str( i + 1 ) +
3520 " has incorrect view" +
3521 " of set " + onosSetName + ":\n" +
3522 str( getResponses[ i ] ) )
3523 main.log.debug( "Expected: " + str( onosSet ) )
3524 main.log.debug( "Actual: " + str( current ) )
3525 getResults = main.FALSE
3526 else:
3527 # error, set is not a set
3528 main.log.error( "ONOS" + str( i + 1 ) +
3529 " has repeat elements in" +
3530 " set " + onosSetName + ":\n" +
3531 str( getResponses[ i ] ) )
3532 getResults = main.FALSE
3533 elif getResponses[ i ] == main.ERROR:
3534 getResults = main.FALSE
3535 sizeResponses = []
3536 threads = []
3537 for i in range( numControllers ):
3538 t = main.Thread( target=CLIs[i].setTestSize,
3539 name="setTestSize-" + str( i ),
3540 args=[ onosSetName ] )
3541 threads.append( t )
3542 t.start()
3543 for t in threads:
3544 t.join()
3545 sizeResponses.append( t.result )
3546 sizeResults = main.TRUE
3547 for i in range( numControllers ):
3548 if size != sizeResponses[ i ]:
3549 sizeResults = main.FALSE
3550 main.log.error( "ONOS" + str( i + 1 ) +
3551 " expected a size of " + str( size ) +
3552 " for set " + onosSetName +
3553 " but got " + str( sizeResponses[ i ] ) )
3554 removeResults = removeResults and getResults and sizeResults
3555 utilities.assert_equals( expect=main.TRUE,
3556 actual=removeResults,
3557 onpass="Set remove correct",
3558 onfail="Set remove was incorrect" )
3559
3560 main.step( "Distributed Set removeAll()" )
3561 onosSet.difference_update( addAllValue.split() )
3562 removeAllResponses = []
3563 threads = []
3564 try:
3565 for i in range( numControllers ):
3566 t = main.Thread( target=CLIs[i].setTestRemove,
3567 name="setTestRemoveAll-" + str( i ),
3568 args=[ onosSetName, addAllValue ] )
3569 threads.append( t )
3570 t.start()
3571 for t in threads:
3572 t.join()
3573 removeAllResponses.append( t.result )
3574 except Exception, e:
3575 main.log.exception(e)
3576
3577 # main.TRUE = successfully changed the set
3578 # main.FALSE = action resulted in no change in set
3579 # main.ERROR - Some error in executing the function
3580 removeAllResults = main.TRUE
3581 for i in range( numControllers ):
3582 if removeAllResponses[ i ] == main.TRUE:
3583 # All is well
3584 pass
3585 elif removeAllResponses[ i ] == main.FALSE:
3586 # not in set, probably fine
3587 pass
3588 elif removeAllResponses[ i ] == main.ERROR:
3589 # Error in execution
3590 removeAllResults = main.FALSE
3591 else:
3592 # unexpected result
3593 removeAllResults = main.FALSE
3594 if removeAllResults != main.TRUE:
3595 main.log.error( "Error executing set removeAll" )
3596
3597 # Check if set is still correct
3598 size = len( onosSet )
3599 getResponses = []
3600 threads = []
3601 for i in range( numControllers ):
3602 t = main.Thread( target=CLIs[i].setTestGet,
3603 name="setTestGet-" + str( i ),
3604 args=[ onosSetName ] )
3605 threads.append( t )
3606 t.start()
3607 for t in threads:
3608 t.join()
3609 getResponses.append( t.result )
3610 getResults = main.TRUE
3611 for i in range( numControllers ):
3612 if isinstance( getResponses[ i ], list):
3613 current = set( getResponses[ i ] )
3614 if len( current ) == len( getResponses[ i ] ):
3615 # no repeats
3616 if onosSet != current:
3617 main.log.error( "ONOS" + str( i + 1 ) +
3618 " has incorrect view" +
3619 " of set " + onosSetName + ":\n" +
3620 str( getResponses[ i ] ) )
3621 main.log.debug( "Expected: " + str( onosSet ) )
3622 main.log.debug( "Actual: " + str( current ) )
3623 getResults = main.FALSE
3624 else:
3625 # error, set is not a set
3626 main.log.error( "ONOS" + str( i + 1 ) +
3627 " has repeat elements in" +
3628 " set " + onosSetName + ":\n" +
3629 str( getResponses[ i ] ) )
3630 getResults = main.FALSE
3631 elif getResponses[ i ] == main.ERROR:
3632 getResults = main.FALSE
3633 sizeResponses = []
3634 threads = []
3635 for i in range( numControllers ):
3636 t = main.Thread( target=CLIs[i].setTestSize,
3637 name="setTestSize-" + str( i ),
3638 args=[ onosSetName ] )
3639 threads.append( t )
3640 t.start()
3641 for t in threads:
3642 t.join()
3643 sizeResponses.append( t.result )
3644 sizeResults = main.TRUE
3645 for i in range( numControllers ):
3646 if size != sizeResponses[ i ]:
3647 sizeResults = main.FALSE
3648 main.log.error( "ONOS" + str( i + 1 ) +
3649 " expected a size of " + str( size ) +
3650 " for set " + onosSetName +
3651 " but got " + str( sizeResponses[ i ] ) )
3652 removeAllResults = removeAllResults and getResults and sizeResults
3653 utilities.assert_equals( expect=main.TRUE,
3654 actual=removeAllResults,
3655 onpass="Set removeAll correct",
3656 onfail="Set removeAll was incorrect" )
3657
3658 main.step( "Distributed Set addAll()" )
3659 onosSet.update( addAllValue.split() )
3660 addResponses = []
3661 threads = []
3662 for i in range( numControllers ):
3663 t = main.Thread( target=CLIs[i].setTestAdd,
3664 name="setTestAddAll-" + str( i ),
3665 args=[ onosSetName, addAllValue ] )
3666 threads.append( t )
3667 t.start()
3668 for t in threads:
3669 t.join()
3670 addResponses.append( t.result )
3671
3672 # main.TRUE = successfully changed the set
3673 # main.FALSE = action resulted in no change in set
3674 # main.ERROR - Some error in executing the function
3675 addAllResults = main.TRUE
3676 for i in range( numControllers ):
3677 if addResponses[ i ] == main.TRUE:
3678 # All is well
3679 pass
3680 elif addResponses[ i ] == main.FALSE:
3681 # Already in set, probably fine
3682 pass
3683 elif addResponses[ i ] == main.ERROR:
3684 # Error in execution
3685 addAllResults = main.FALSE
3686 else:
3687 # unexpected result
3688 addAllResults = main.FALSE
3689 if addAllResults != main.TRUE:
3690 main.log.error( "Error executing set addAll" )
3691
3692 # Check if set is still correct
3693 size = len( onosSet )
3694 getResponses = []
3695 threads = []
3696 for i in range( numControllers ):
3697 t = main.Thread( target=CLIs[i].setTestGet,
3698 name="setTestGet-" + str( i ),
3699 args=[ onosSetName ] )
3700 threads.append( t )
3701 t.start()
3702 for t in threads:
3703 t.join()
3704 getResponses.append( t.result )
3705 getResults = main.TRUE
3706 for i in range( numControllers ):
3707 if isinstance( getResponses[ i ], list):
3708 current = set( getResponses[ i ] )
3709 if len( current ) == len( getResponses[ i ] ):
3710 # no repeats
3711 if onosSet != current:
3712 main.log.error( "ONOS" + str( i + 1 ) +
3713 " has incorrect view" +
3714 " of set " + onosSetName + ":\n" +
3715 str( getResponses[ i ] ) )
3716 main.log.debug( "Expected: " + str( onosSet ) )
3717 main.log.debug( "Actual: " + str( current ) )
3718 getResults = main.FALSE
3719 else:
3720 # error, set is not a set
3721 main.log.error( "ONOS" + str( i + 1 ) +
3722 " has repeat elements in" +
3723 " set " + onosSetName + ":\n" +
3724 str( getResponses[ i ] ) )
3725 getResults = main.FALSE
3726 elif getResponses[ i ] == main.ERROR:
3727 getResults = main.FALSE
3728 sizeResponses = []
3729 threads = []
3730 for i in range( numControllers ):
3731 t = main.Thread( target=CLIs[i].setTestSize,
3732 name="setTestSize-" + str( i ),
3733 args=[ onosSetName ] )
3734 threads.append( t )
3735 t.start()
3736 for t in threads:
3737 t.join()
3738 sizeResponses.append( t.result )
3739 sizeResults = main.TRUE
3740 for i in range( numControllers ):
3741 if size != sizeResponses[ i ]:
3742 sizeResults = main.FALSE
3743 main.log.error( "ONOS" + str( i + 1 ) +
3744 " expected a size of " + str( size ) +
3745 " for set " + onosSetName +
3746 " but got " + str( sizeResponses[ i ] ) )
3747 addAllResults = addAllResults and getResults and sizeResults
3748 utilities.assert_equals( expect=main.TRUE,
3749 actual=addAllResults,
3750 onpass="Set addAll correct",
3751 onfail="Set addAll was incorrect" )
3752
3753 main.step( "Distributed Set clear()" )
3754 onosSet.clear()
3755 clearResponses = []
3756 threads = []
3757 for i in range( numControllers ):
3758 t = main.Thread( target=CLIs[i].setTestRemove,
3759 name="setTestClear-" + str( i ),
3760 args=[ onosSetName, " "], # Values doesn't matter
3761 kwargs={ "clear": True } )
3762 threads.append( t )
3763 t.start()
3764 for t in threads:
3765 t.join()
3766 clearResponses.append( t.result )
3767
3768 # main.TRUE = successfully changed the set
3769 # main.FALSE = action resulted in no change in set
3770 # main.ERROR - Some error in executing the function
3771 clearResults = main.TRUE
3772 for i in range( numControllers ):
3773 if clearResponses[ i ] == main.TRUE:
3774 # All is well
3775 pass
3776 elif clearResponses[ i ] == main.FALSE:
3777 # Nothing set, probably fine
3778 pass
3779 elif clearResponses[ i ] == main.ERROR:
3780 # Error in execution
3781 clearResults = main.FALSE
3782 else:
3783 # unexpected result
3784 clearResults = main.FALSE
3785 if clearResults != main.TRUE:
3786 main.log.error( "Error executing set clear" )
3787
3788 # Check if set is still correct
3789 size = len( onosSet )
3790 getResponses = []
3791 threads = []
3792 for i in range( numControllers ):
3793 t = main.Thread( target=CLIs[i].setTestGet,
3794 name="setTestGet-" + str( i ),
3795 args=[ onosSetName ] )
3796 threads.append( t )
3797 t.start()
3798 for t in threads:
3799 t.join()
3800 getResponses.append( t.result )
3801 getResults = main.TRUE
3802 for i in range( numControllers ):
3803 if isinstance( getResponses[ i ], list):
3804 current = set( getResponses[ i ] )
3805 if len( current ) == len( getResponses[ i ] ):
3806 # no repeats
3807 if onosSet != current:
3808 main.log.error( "ONOS" + str( i + 1 ) +
3809 " has incorrect view" +
3810 " of set " + onosSetName + ":\n" +
3811 str( getResponses[ i ] ) )
3812 main.log.debug( "Expected: " + str( onosSet ) )
3813 main.log.debug( "Actual: " + str( current ) )
3814 getResults = main.FALSE
3815 else:
3816 # error, set is not a set
3817 main.log.error( "ONOS" + str( i + 1 ) +
3818 " has repeat elements in" +
3819 " set " + onosSetName + ":\n" +
3820 str( getResponses[ i ] ) )
3821 getResults = main.FALSE
3822 elif getResponses[ i ] == main.ERROR:
3823 getResults = main.FALSE
3824 sizeResponses = []
3825 threads = []
3826 for i in range( numControllers ):
3827 t = main.Thread( target=CLIs[i].setTestSize,
3828 name="setTestSize-" + str( i ),
3829 args=[ onosSetName ] )
3830 threads.append( t )
3831 t.start()
3832 for t in threads:
3833 t.join()
3834 sizeResponses.append( t.result )
3835 sizeResults = main.TRUE
3836 for i in range( numControllers ):
3837 if size != sizeResponses[ i ]:
3838 sizeResults = main.FALSE
3839 main.log.error( "ONOS" + str( i + 1 ) +
3840 " expected a size of " + str( size ) +
3841 " for set " + onosSetName +
3842 " but got " + str( sizeResponses[ i ] ) )
3843 clearResults = clearResults and getResults and sizeResults
3844 utilities.assert_equals( expect=main.TRUE,
3845 actual=clearResults,
3846 onpass="Set clear correct",
3847 onfail="Set clear was incorrect" )
3848
3849 main.step( "Distributed Set addAll()" )
3850 onosSet.update( addAllValue.split() )
3851 addResponses = []
3852 threads = []
3853 for i in range( numControllers ):
3854 t = main.Thread( target=CLIs[i].setTestAdd,
3855 name="setTestAddAll-" + str( i ),
3856 args=[ onosSetName, addAllValue ] )
3857 threads.append( t )
3858 t.start()
3859 for t in threads:
3860 t.join()
3861 addResponses.append( t.result )
3862
3863 # main.TRUE = successfully changed the set
3864 # main.FALSE = action resulted in no change in set
3865 # main.ERROR - Some error in executing the function
3866 addAllResults = main.TRUE
3867 for i in range( numControllers ):
3868 if addResponses[ i ] == main.TRUE:
3869 # All is well
3870 pass
3871 elif addResponses[ i ] == main.FALSE:
3872 # Already in set, probably fine
3873 pass
3874 elif addResponses[ i ] == main.ERROR:
3875 # Error in execution
3876 addAllResults = main.FALSE
3877 else:
3878 # unexpected result
3879 addAllResults = main.FALSE
3880 if addAllResults != main.TRUE:
3881 main.log.error( "Error executing set addAll" )
3882
3883 # Check if set is still correct
3884 size = len( onosSet )
3885 getResponses = []
3886 threads = []
3887 for i in range( numControllers ):
3888 t = main.Thread( target=CLIs[i].setTestGet,
3889 name="setTestGet-" + str( i ),
3890 args=[ onosSetName ] )
3891 threads.append( t )
3892 t.start()
3893 for t in threads:
3894 t.join()
3895 getResponses.append( t.result )
3896 getResults = main.TRUE
3897 for i in range( numControllers ):
3898 if isinstance( getResponses[ i ], list):
3899 current = set( getResponses[ i ] )
3900 if len( current ) == len( getResponses[ i ] ):
3901 # no repeats
3902 if onosSet != current:
3903 main.log.error( "ONOS" + str( i + 1 ) +
3904 " has incorrect view" +
3905 " of set " + onosSetName + ":\n" +
3906 str( getResponses[ i ] ) )
3907 main.log.debug( "Expected: " + str( onosSet ) )
3908 main.log.debug( "Actual: " + str( current ) )
3909 getResults = main.FALSE
3910 else:
3911 # error, set is not a set
3912 main.log.error( "ONOS" + str( i + 1 ) +
3913 " has repeat elements in" +
3914 " set " + onosSetName + ":\n" +
3915 str( getResponses[ i ] ) )
3916 getResults = main.FALSE
3917 elif getResponses[ i ] == main.ERROR:
3918 getResults = main.FALSE
3919 sizeResponses = []
3920 threads = []
3921 for i in range( numControllers ):
3922 t = main.Thread( target=CLIs[i].setTestSize,
3923 name="setTestSize-" + str( i ),
3924 args=[ onosSetName ] )
3925 threads.append( t )
3926 t.start()
3927 for t in threads:
3928 t.join()
3929 sizeResponses.append( t.result )
3930 sizeResults = main.TRUE
3931 for i in range( numControllers ):
3932 if size != sizeResponses[ i ]:
3933 sizeResults = main.FALSE
3934 main.log.error( "ONOS" + str( i + 1 ) +
3935 " expected a size of " + str( size ) +
3936 " for set " + onosSetName +
3937 " but got " + str( sizeResponses[ i ] ) )
3938 addAllResults = addAllResults and getResults and sizeResults
3939 utilities.assert_equals( expect=main.TRUE,
3940 actual=addAllResults,
3941 onpass="Set addAll correct",
3942 onfail="Set addAll was incorrect" )
3943
3944 main.step( "Distributed Set retain()" )
3945 onosSet.intersection_update( retainValue.split() )
3946 retainResponses = []
3947 threads = []
3948 for i in range( numControllers ):
3949 t = main.Thread( target=CLIs[i].setTestRemove,
3950 name="setTestRetain-" + str( i ),
3951 args=[ onosSetName, retainValue ],
3952 kwargs={ "retain": True } )
3953 threads.append( t )
3954 t.start()
3955 for t in threads:
3956 t.join()
3957 retainResponses.append( t.result )
3958
3959 # main.TRUE = successfully changed the set
3960 # main.FALSE = action resulted in no change in set
3961 # main.ERROR - Some error in executing the function
3962 retainResults = main.TRUE
3963 for i in range( numControllers ):
3964 if retainResponses[ i ] == main.TRUE:
3965 # All is well
3966 pass
3967 elif retainResponses[ i ] == main.FALSE:
3968 # Already in set, probably fine
3969 pass
3970 elif retainResponses[ i ] == main.ERROR:
3971 # Error in execution
3972 retainResults = main.FALSE
3973 else:
3974 # unexpected result
3975 retainResults = main.FALSE
3976 if retainResults != main.TRUE:
3977 main.log.error( "Error executing set retain" )
3978
3979 # Check if set is still correct
3980 size = len( onosSet )
3981 getResponses = []
3982 threads = []
3983 for i in range( numControllers ):
3984 t = main.Thread( target=CLIs[i].setTestGet,
3985 name="setTestGet-" + str( i ),
3986 args=[ onosSetName ] )
3987 threads.append( t )
3988 t.start()
3989 for t in threads:
3990 t.join()
3991 getResponses.append( t.result )
3992 getResults = main.TRUE
3993 for i in range( numControllers ):
3994 if isinstance( getResponses[ i ], list):
3995 current = set( getResponses[ i ] )
3996 if len( current ) == len( getResponses[ i ] ):
3997 # no repeats
3998 if onosSet != current:
3999 main.log.error( "ONOS" + str( i + 1 ) +
4000 " has incorrect view" +
4001 " of set " + onosSetName + ":\n" +
4002 str( getResponses[ i ] ) )
4003 main.log.debug( "Expected: " + str( onosSet ) )
4004 main.log.debug( "Actual: " + str( current ) )
4005 getResults = main.FALSE
4006 else:
4007 # error, set is not a set
4008 main.log.error( "ONOS" + str( i + 1 ) +
4009 " has repeat elements in" +
4010 " set " + onosSetName + ":\n" +
4011 str( getResponses[ i ] ) )
4012 getResults = main.FALSE
4013 elif getResponses[ i ] == main.ERROR:
4014 getResults = main.FALSE
4015 sizeResponses = []
4016 threads = []
4017 for i in range( numControllers ):
4018 t = main.Thread( target=CLIs[i].setTestSize,
4019 name="setTestSize-" + str( i ),
4020 args=[ onosSetName ] )
4021 threads.append( t )
4022 t.start()
4023 for t in threads:
4024 t.join()
4025 sizeResponses.append( t.result )
4026 sizeResults = main.TRUE
4027 for i in range( numControllers ):
4028 if size != sizeResponses[ i ]:
4029 sizeResults = main.FALSE
4030 main.log.error( "ONOS" + str( i + 1 ) +
4031 " expected a size of " +
4032 str( size ) + " for set " + onosSetName +
4033 " but got " + str( sizeResponses[ i ] ) )
4034 retainResults = retainResults and getResults and sizeResults
4035 utilities.assert_equals( expect=main.TRUE,
4036 actual=retainResults,
4037 onpass="Set retain correct",
4038 onfail="Set retain was incorrect" )
4039