blob: 4ecc271692bd4c6eca0610dbbf0a40c78f3c0ba8 [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 Hall0f523f22015-07-06 09:31:09 -0700273 ipList = []
274 for i in range( numControllers ):
275 ipList.append( nodes[ i ].ip_address )
276 swList = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800277 for i in range( 1, 29 ):
Jon Hall0f523f22015-07-06 09:31:09 -0700278 swList.append( "s" + str( i ) )
279 main.Mininet1.assignSwController( sw=swList, ip=ipList )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800280
Jon Hall8f89dda2015-01-22 16:03:33 -0800281 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800282 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800283 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800284 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800285 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800286 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800287 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700288 for node in nodes:
289 if re.search( "tcp:" + node.ip_address, response ):
290 mastershipCheck = mastershipCheck and main.TRUE
291 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700292 main.log.error( "Error, node " + node.ip_address + " is " +
293 "not in the list of controllers s" +
294 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700295 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800296 utilities.assert_equals(
297 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800298 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800299 onpass="Switch mastership assigned correctly",
300 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700301
Jon Hallc9eabec2015-06-10 14:33:14 -0700302 def CASE21( self, main ):
303 """
304 Assign mastership to controllers
305 """
306 import re
307 import time
308 assert numControllers, "numControllers not defined"
309 assert main, "main not defined"
310 assert utilities.assert_equals, "utilities.assert_equals not defined"
311 assert CLIs, "CLIs not defined"
312 assert nodes, "nodes not defined"
313 assert ONOS1Port, "ONOS1Port not defined"
314 assert ONOS2Port, "ONOS2Port not defined"
315 assert ONOS3Port, "ONOS3Port not defined"
316 assert ONOS4Port, "ONOS4Port not defined"
317 assert ONOS5Port, "ONOS5Port not defined"
318 assert ONOS6Port, "ONOS6Port not defined"
319 assert ONOS7Port, "ONOS7Port not defined"
320
321 main.case( "Assigning Controller roles for switches" )
322 main.caseExplaination = "Check that ONOS is connected to each " +\
323 "device. Then manually assign" +\
324 " mastership to specific ONOS nodes using" +\
325 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700326 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800327 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800328 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700329
330 ipList = [ ]
331 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800332 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700333 for i in range( 1, 29 ): # switches 1 through 28
334 # set up correct variables:
335 if i == 1:
336 ip = nodes[ 0 ].ip_address # ONOS1
337 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
338 elif i == 2:
339 ip = nodes[ 1 ].ip_address # ONOS2
340 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
341 elif i == 3:
342 ip = nodes[ 1 ].ip_address # ONOS2
343 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
344 elif i == 4:
345 ip = nodes[ 3 ].ip_address # ONOS4
346 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
347 elif i == 5:
348 ip = nodes[ 2 ].ip_address # ONOS3
349 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
350 elif i == 6:
351 ip = nodes[ 2 ].ip_address # ONOS3
352 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
353 elif i == 7:
354 ip = nodes[ 5 ].ip_address # ONOS6
355 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
356 elif i >= 8 and i <= 17:
357 ip = nodes[ 4 ].ip_address # ONOS5
358 dpid = '3' + str( i ).zfill( 3 )
359 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
360 elif i >= 18 and i <= 27:
361 ip = nodes[ 6 ].ip_address # ONOS7
362 dpid = '6' + str( i ).zfill( 3 )
363 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
364 elif i == 28:
365 ip = nodes[ 0 ].ip_address # ONOS1
366 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
367 else:
368 main.log.error( "You didn't write an else statement for " +
369 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700370 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700371 # Assign switch
372 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
373 # TODO: make this controller dynamic
374 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
375 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700376 ipList.append( ip )
377 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800378 except ( AttributeError, AssertionError ):
379 main.log.exception( "Something is wrong with ONOS device view" )
380 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800381 utilities.assert_equals(
382 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800383 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800384 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800385 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800386
Jon Hall390696c2015-05-05 17:13:41 -0700387 main.step( "Check mastership was correctly assigned" )
388 roleCheck = main.TRUE
389 # NOTE: This is due to the fact that device mastership change is not
390 # atomic and is actually a multi step process
391 time.sleep( 5 )
392 for i in range( len( ipList ) ):
393 ip = ipList[i]
394 deviceId = deviceList[i]
395 # Check assignment
396 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
397 if ip in master:
398 roleCheck = roleCheck and main.TRUE
399 else:
400 roleCheck = roleCheck and main.FALSE
401 main.log.error( "Error, controller " + ip + " is not" +
402 " master " + "of device " +
403 str( deviceId ) + ". Master is " +
404 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800405 utilities.assert_equals(
406 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800407 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800408 onpass="Switches were successfully reassigned to designated " +
409 "controller",
410 onfail="Switches were not successfully reassigned" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800411
Jon Hall6aec96b2015-01-19 14:49:31 -0800412 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800413 """
414 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800415 """
416 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800417 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700418 assert numControllers, "numControllers not defined"
419 assert main, "main not defined"
420 assert utilities.assert_equals, "utilities.assert_equals not defined"
421 assert CLIs, "CLIs not defined"
422 assert nodes, "nodes not defined"
Jon Hallc9eabec2015-06-10 14:33:14 -0700423 try:
424 labels
425 except NameError:
426 main.log.error( "labels not defined, setting to []" )
427 labels = []
428 try:
429 data
430 except NameError:
431 main.log.error( "data not defined, setting to []" )
432 data = []
Jon Hallfeff3082015-05-19 10:23:26 -0700433 # NOTE: we must reinstall intents until we have a persistant intent
434 # datastore!
Jon Hall6aec96b2015-01-19 14:49:31 -0800435 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700436 main.caseExplaination = "Discover hosts by using pingall then " +\
437 "assign predetermined host-to-host intents." +\
438 " After installation, check that the intent" +\
439 " is distributed to all nodes and the state" +\
440 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800441
Jon Hall6aec96b2015-01-19 14:49:31 -0800442 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700443 main.step( "Install reactive forwarding app" )
444 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
445 utilities.assert_equals( expect=main.TRUE, actual=installResults,
446 onpass="Install fwd successful",
447 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700448
Jon Hallfeff3082015-05-19 10:23:26 -0700449 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700450 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700451 threads = []
452 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700453 t = main.Thread( target=CLIs[i].appToIDCheck,
454 name="appToIDCheck-" + str( i ),
455 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700456 threads.append( t )
457 t.start()
458
459 for t in threads:
460 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700461 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700462 if appCheck != main.TRUE:
463 main.log.warn( CLIs[0].apps() )
464 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700465 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
466 onpass="App Ids seem to be correct",
467 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800468
Jon Hallfeff3082015-05-19 10:23:26 -0700469 main.step( "Discovering Hosts( Via pingall for now )" )
470 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800471 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800472 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700473 for i in range(2): # Retry if pingall fails first time
474 time1 = time.time()
475 pingResult = main.Mininet1.pingall()
Jon Hall0f523f22015-07-06 09:31:09 -0700476 if i == 0:
477 utilities.assert_equals(
478 expect=main.TRUE,
479 actual=pingResult,
480 onpass="Reactive Pingall test passed",
481 onfail="Reactive Pingall failed, " +
482 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700483 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700484 main.log.info( "Time for pingall: %2f seconds" %
485 ( time2 - time1 ) )
486 # timeout for fwd flows
487 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800488 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700489 main.step( "Uninstall reactive forwarding app" )
490 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
491 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
492 onpass="Uninstall fwd successful",
493 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700494
495 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700496 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700497 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700498 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700499 t = main.Thread( target=CLIs[i].appToIDCheck,
500 name="appToIDCheck-" + str( i ),
501 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700502 threads.append( t )
503 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800504
Jon Hall5cfd23c2015-03-19 11:40:57 -0700505 for t in threads:
506 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700507 appCheck2 = appCheck2 and t.result
508 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700509 main.log.warn( CLIs[0].apps() )
510 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700511 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700512 onpass="App Ids seem to be correct",
513 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700514
Jon Hallfeff3082015-05-19 10:23:26 -0700515 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800516 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800517 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800518 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800519 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800520 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800521 for i in range( 8, 18 ):
522 main.log.info( "Adding host intent between h" + str( i ) +
523 " and h" + str( i + 10 ) )
524 host1 = "00:00:00:00:00:" + \
525 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
526 host2 = "00:00:00:00:00:" + \
527 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800528 # NOTE: getHost can return None
529 host1Dict = main.ONOScli1.getHost( host1 )
530 host2Dict = main.ONOScli1.getHost( host2 )
531 host1Id = None
532 host2Id = None
533 if host1Dict and host2Dict:
534 host1Id = host1Dict.get( 'id', None )
535 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800536 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700537 nodeNum = ( i % 7 )
538 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800539 if tmpId:
540 main.log.info( "Added intent with id: " + tmpId )
541 intentIds.append( tmpId )
542 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700543 main.log.error( "addHostIntent returned: " +
544 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800545 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700546 main.log.error( "Error, getHost() failed for h" + str( i ) +
547 " and/or h" + str( i + 10 ) )
548 hosts = CLIs[ 0 ].hosts()
549 main.log.warn( "Hosts output: " )
550 try:
551 main.log.warn( json.dumps( json.loads( hosts ),
552 sort_keys=True,
553 indent=4,
554 separators=( ',', ': ' ) ) )
555 except ( ValueError, TypeError ):
556 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800557 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700558 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
559 onpass="Found a host id for each host",
560 onfail="Error looking up host ids" )
561
Jon Halla9d26da2015-03-30 16:45:32 -0700562 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800563 onosIds = main.ONOScli1.getAllIntentsId()
564 main.log.info( "Submitted intents: " + str( intentIds ) )
565 main.log.info( "Intents in ONOS: " + str( onosIds ) )
566 for intent in intentIds:
567 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700568 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800569 else:
570 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700571 if intentAddResult:
572 intentStop = time.time()
573 else:
574 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800575 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800576 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800577 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800578 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800579 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
580 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700581 try:
582 for intent in json.loads( intents ):
583 state = intent.get( 'state', None )
584 if "INSTALLED" not in state:
585 installedCheck = False
586 intentId = intent.get( 'id', None )
587 intentStates.append( ( intentId, state ) )
588 except ( ValueError, TypeError ):
589 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800590 # add submitted intents not in the store
591 tmplist = [ i for i, s in intentStates ]
592 missingIntents = False
593 for i in intentIds:
594 if i not in tmplist:
595 intentStates.append( ( i, " - " ) )
596 missingIntents = True
597 intentStates.sort()
598 for i, s in intentStates:
599 count += 1
600 main.log.info( "%-6s%-15s%-15s" %
601 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700602 leaders = main.ONOScli1.leaders()
603 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700604 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700605 if leaders:
606 parsedLeaders = json.loads( leaders )
607 main.log.warn( json.dumps( parsedLeaders,
608 sort_keys=True,
609 indent=4,
610 separators=( ',', ': ' ) ) )
611 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700612 topics = []
613 for i in range( 14 ):
614 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700615 main.log.debug( topics )
616 ONOStopics = [ j['topic'] for j in parsedLeaders ]
617 for topic in topics:
618 if topic not in ONOStopics:
619 main.log.error( "Error: " + topic +
620 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700621 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700622 else:
623 main.log.error( "leaders() returned None" )
624 except ( ValueError, TypeError ):
625 main.log.exception( "Error parsing leaders" )
626 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700627 # Check all nodes
628 if missing:
629 for node in CLIs:
630 response = node.leaders( jsonFormat=False)
631 main.log.warn( str( node.name ) + " leaders output: \n" +
632 str( response ) )
633
Jon Hall5cfd23c2015-03-19 11:40:57 -0700634 partitions = main.ONOScli1.partitions()
635 try:
636 if partitions :
637 parsedPartitions = json.loads( partitions )
638 main.log.warn( json.dumps( parsedPartitions,
639 sort_keys=True,
640 indent=4,
641 separators=( ',', ': ' ) ) )
642 # TODO check for a leader in all paritions
643 # TODO check for consistency among nodes
644 else:
645 main.log.error( "partitions() returned None" )
646 except ( ValueError, TypeError ):
647 main.log.exception( "Error parsing partitions" )
648 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800649 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700650 try:
651 if pendingMap :
652 parsedPending = json.loads( pendingMap )
653 main.log.warn( json.dumps( parsedPending,
654 sort_keys=True,
655 indent=4,
656 separators=( ',', ': ' ) ) )
657 # TODO check something here?
658 else:
659 main.log.error( "pendingMap() returned None" )
660 except ( ValueError, TypeError ):
661 main.log.exception( "Error parsing pending map" )
662 main.log.error( repr( pendingMap ) )
663
Jon Hallfeff3082015-05-19 10:23:26 -0700664 intentAddResult = bool( intentAddResult and not missingIntents and
665 installedCheck )
666 if not intentAddResult:
667 main.log.error( "Error in pushing host intents to ONOS" )
668
Jon Hall390696c2015-05-05 17:13:41 -0700669 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700670 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700671 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700672 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700673 for cli in CLIs:
674 onosIds = []
675 ids = cli.getAllIntentsId()
676 onosIds.append( ids )
677 main.log.debug( "Intents in " + cli.name + ": " +
678 str( sorted( onosIds ) ) )
679 if sorted( ids ) != sorted( intentIds ):
Jon Hallafa8a472015-06-12 14:02:42 -0700680 main.log.warn( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700681 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700682 break
683 else:
684 intents = json.loads( cli.intents() )
685 for intent in intents:
686 if intent[ 'state' ] != "INSTALLED":
Jon Hallc9eabec2015-06-10 14:33:14 -0700687 main.log.warn( "Intent " + intent[ 'id' ] +
688 " is " + intent[ 'state' ] )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700689 correct = False
690 break
Jon Hall390696c2015-05-05 17:13:41 -0700691 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700692 break
693 else:
694 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700695 if not intentStop:
696 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700697 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700698 gossipTime = intentStop - intentStart
699 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700700 " seconds for all intents to appear in each node" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700701 append = False
702 title = "Gossip Intents"
703 count = 1
704 while append is False:
705 curTitle = title + str( count )
706 if curTitle not in labels:
707 labels.append( curTitle )
708 data.append( str( gossipTime ) )
709 append = True
710 else:
711 count += 1
Jon Halla9d26da2015-03-30 16:45:32 -0700712 # FIXME: make this time configurable/calculate based off of number of
713 # nodes and gossip rounds
714 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700715 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700716 onpass="ECM anti-entropy for intents worked within " +
717 "expected time",
718 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700719 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700720 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800721
Jon Hall63604932015-02-26 17:09:50 -0800722 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800723 import time
Jon Hall63604932015-02-26 17:09:50 -0800724 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800725 main.log.info( "Sleeping 60 seconds to see if intents are found" )
726 time.sleep( 60 )
727 onosIds = main.ONOScli1.getAllIntentsId()
728 main.log.info( "Submitted intents: " + str( intentIds ) )
729 main.log.info( "Intents in ONOS: " + str( onosIds ) )
730 # Print the intent states
731 intents = main.ONOScli1.intents()
732 intentStates = []
733 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
734 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700735 try:
736 for intent in json.loads( intents ):
737 # Iter through intents of a node
738 state = intent.get( 'state', None )
739 if "INSTALLED" not in state:
740 installedCheck = False
741 intentId = intent.get( 'id', None )
742 intentStates.append( ( intentId, state ) )
743 except ( ValueError, TypeError ):
744 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800745 # add submitted intents not in the store
746 tmplist = [ i for i, s in intentStates ]
747 for i in intentIds:
748 if i not in tmplist:
749 intentStates.append( ( i, " - " ) )
750 intentStates.sort()
751 for i, s in intentStates:
752 count += 1
753 main.log.info( "%-6s%-15s%-15s" %
754 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700755 leaders = main.ONOScli1.leaders()
756 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700757 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700758 if leaders:
759 parsedLeaders = json.loads( leaders )
760 main.log.warn( json.dumps( parsedLeaders,
761 sort_keys=True,
762 indent=4,
763 separators=( ',', ': ' ) ) )
764 # check for all intent partitions
765 # check for election
766 topics = []
767 for i in range( 14 ):
768 topics.append( "intent-partition-" + str( i ) )
769 # FIXME: this should only be after we start the app
770 topics.append( "org.onosproject.election" )
771 main.log.debug( topics )
772 ONOStopics = [ j['topic'] for j in parsedLeaders ]
773 for topic in topics:
774 if topic not in ONOStopics:
775 main.log.error( "Error: " + topic +
776 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700777 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700778 else:
779 main.log.error( "leaders() returned None" )
780 except ( ValueError, TypeError ):
781 main.log.exception( "Error parsing leaders" )
782 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700783 # Check all nodes
784 if missing:
785 for node in CLIs:
786 response = node.leaders( jsonFormat=False)
787 main.log.warn( str( node.name ) + " leaders output: \n" +
788 str( response ) )
789
Jon Hall5cfd23c2015-03-19 11:40:57 -0700790 partitions = main.ONOScli1.partitions()
791 try:
792 if partitions :
793 parsedPartitions = json.loads( partitions )
794 main.log.warn( json.dumps( parsedPartitions,
795 sort_keys=True,
796 indent=4,
797 separators=( ',', ': ' ) ) )
798 # TODO check for a leader in all paritions
799 # TODO check for consistency among nodes
800 else:
801 main.log.error( "partitions() returned None" )
802 except ( ValueError, TypeError ):
803 main.log.exception( "Error parsing partitions" )
804 main.log.error( repr( partitions ) )
805 pendingMap = main.ONOScli1.pendingMap()
806 try:
807 if pendingMap :
808 parsedPending = json.loads( pendingMap )
809 main.log.warn( json.dumps( parsedPending,
810 sort_keys=True,
811 indent=4,
812 separators=( ',', ': ' ) ) )
813 # TODO check something here?
814 else:
815 main.log.error( "pendingMap() returned None" )
816 except ( ValueError, TypeError ):
817 main.log.exception( "Error parsing pending map" )
818 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800819
Jon Hall6aec96b2015-01-19 14:49:31 -0800820 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800821 """
822 Ping across added host intents
823 """
Jon Hall58c76b72015-02-23 11:09:24 -0800824 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700825 import time
826 assert numControllers, "numControllers not defined"
827 assert main, "main not defined"
828 assert utilities.assert_equals, "utilities.assert_equals not defined"
829 assert CLIs, "CLIs not defined"
830 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700831 main.case( "Verify connectivity by sendind traffic across Intents" )
832 main.caseExplaination = "Ping across added host intents to check " +\
833 "functionality and check the state of " +\
834 "the intent"
835 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800836 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800837 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800838 ping = main.Mininet1.pingHost( src="h" + str( i ),
839 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800840 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800841 if ping == main.FALSE:
842 main.log.warn( "Ping failed between h" + str( i ) +
843 " and h" + str( i + 10 ) )
844 elif ping == main.TRUE:
845 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800846 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800847 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700848 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800849 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800850 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700851 main.log.warn( "ONOS1 intents: " )
852 try:
853 tmpIntents = main.ONOScli1.intents()
854 main.log.warn( json.dumps( json.loads( tmpIntents ),
855 sort_keys=True,
856 indent=4,
857 separators=( ',', ': ' ) ) )
858 except ( ValueError, TypeError ):
859 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800860 utilities.assert_equals(
861 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800862 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800863 onpass="Intents have been installed correctly and pings work",
864 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800865
Jon Hallfeff3082015-05-19 10:23:26 -0700866 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700867 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700868 loopCount = 0
869 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700870 installedCheck = True
871 # Print the intent states
872 intents = main.ONOScli1.intents()
873 intentStates = []
874 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700875 # Iter through intents of a node
876 try:
877 for intent in json.loads( intents ):
878 state = intent.get( 'state', None )
879 if "INSTALLED" not in state:
880 installedCheck = False
881 intentId = intent.get( 'id', None )
882 intentStates.append( ( intentId, state ) )
883 except ( ValueError, TypeError ):
884 main.log.exception( "Error parsing intents." )
885 # Print states
886 intentStates.sort()
887 for i, s in intentStates:
888 count += 1
889 main.log.info( "%-6s%-15s%-15s" %
890 ( str( count ), str( i ), str( s ) ) )
891 if not installedCheck:
892 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700893 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700894 utilities.assert_equals( expect=True, actual=installedCheck,
895 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700896 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700897 "INSTALLED state" )
898
899 main.step( "Check leadership of topics" )
900 leaders = main.ONOScli1.leaders()
901 topicCheck = main.TRUE
902 try:
903 if leaders:
904 parsedLeaders = json.loads( leaders )
905 main.log.warn( json.dumps( parsedLeaders,
906 sort_keys=True,
907 indent=4,
908 separators=( ',', ': ' ) ) )
909 # check for all intent partitions
910 # check for election
911 # TODO: Look at Devices as topics now that it uses this system
912 topics = []
913 for i in range( 14 ):
914 topics.append( "intent-partition-" + str( i ) )
915 # FIXME: this should only be after we start the app
916 # FIXME: topics.append( "org.onosproject.election" )
917 # Print leaders output
918 main.log.debug( topics )
919 ONOStopics = [ j['topic'] for j in parsedLeaders ]
920 for topic in topics:
921 if topic not in ONOStopics:
922 main.log.error( "Error: " + topic +
923 " not in leaders" )
924 topicCheck = main.FALSE
925 else:
926 main.log.error( "leaders() returned None" )
927 topicCheck = main.FALSE
928 except ( ValueError, TypeError ):
929 topicCheck = main.FALSE
930 main.log.exception( "Error parsing leaders" )
931 main.log.error( repr( leaders ) )
932 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700933 # Check all nodes
934 if topicCheck:
935 for node in CLIs:
936 response = node.leaders( jsonFormat=False)
937 main.log.warn( str( node.name ) + " leaders output: \n" +
938 str( response ) )
939
Jon Hallfeff3082015-05-19 10:23:26 -0700940 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
941 onpass="intent Partitions is in leaders",
942 onfail="Some topics were lost " )
943 # Print partitions
944 partitions = main.ONOScli1.partitions()
945 try:
946 if partitions :
947 parsedPartitions = json.loads( partitions )
948 main.log.warn( json.dumps( parsedPartitions,
949 sort_keys=True,
950 indent=4,
951 separators=( ',', ': ' ) ) )
952 # TODO check for a leader in all paritions
953 # TODO check for consistency among nodes
954 else:
955 main.log.error( "partitions() returned None" )
956 except ( ValueError, TypeError ):
957 main.log.exception( "Error parsing partitions" )
958 main.log.error( repr( partitions ) )
959 # Print Pending Map
960 pendingMap = main.ONOScli1.pendingMap()
961 try:
962 if pendingMap :
963 parsedPending = json.loads( pendingMap )
964 main.log.warn( json.dumps( parsedPending,
965 sort_keys=True,
966 indent=4,
967 separators=( ',', ': ' ) ) )
968 # TODO check something here?
969 else:
970 main.log.error( "pendingMap() returned None" )
971 except ( ValueError, TypeError ):
972 main.log.exception( "Error parsing pending map" )
973 main.log.error( repr( pendingMap ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700974
Jon Hall63604932015-02-26 17:09:50 -0800975 if not installedCheck:
Jon Hallc9eabec2015-06-10 14:33:14 -0700976 main.log.info( "Waiting 60 seconds to see if the state of " +
977 "intents change" )
978 time.sleep( 60 )
Jon Hall63604932015-02-26 17:09:50 -0800979 # Print the intent states
980 intents = main.ONOScli1.intents()
981 intentStates = []
982 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
983 count = 0
984 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700985 try:
986 for intent in json.loads( intents ):
987 state = intent.get( 'state', None )
988 if "INSTALLED" not in state:
989 installedCheck = False
990 intentId = intent.get( 'id', None )
991 intentStates.append( ( intentId, state ) )
992 except ( ValueError, TypeError ):
993 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800994 intentStates.sort()
995 for i, s in intentStates:
996 count += 1
997 main.log.info( "%-6s%-15s%-15s" %
998 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700999 leaders = main.ONOScli1.leaders()
1000 try:
Jon Hallc9eabec2015-06-10 14:33:14 -07001001 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -07001002 if leaders:
1003 parsedLeaders = json.loads( leaders )
1004 main.log.warn( json.dumps( parsedLeaders,
1005 sort_keys=True,
1006 indent=4,
1007 separators=( ',', ': ' ) ) )
1008 # check for all intent partitions
1009 # check for election
1010 topics = []
1011 for i in range( 14 ):
1012 topics.append( "intent-partition-" + str( i ) )
1013 # FIXME: this should only be after we start the app
1014 topics.append( "org.onosproject.election" )
1015 main.log.debug( topics )
1016 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1017 for topic in topics:
1018 if topic not in ONOStopics:
1019 main.log.error( "Error: " + topic +
1020 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -07001021 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -07001022 else:
1023 main.log.error( "leaders() returned None" )
1024 except ( ValueError, TypeError ):
1025 main.log.exception( "Error parsing leaders" )
1026 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001027 if missing:
1028 for node in CLIs:
1029 response = node.leaders( jsonFormat=False)
1030 main.log.warn( str( node.name ) + " leaders output: \n" +
1031 str( response ) )
1032
Jon Hall5cfd23c2015-03-19 11:40:57 -07001033 partitions = main.ONOScli1.partitions()
1034 try:
1035 if partitions :
1036 parsedPartitions = json.loads( partitions )
1037 main.log.warn( json.dumps( parsedPartitions,
1038 sort_keys=True,
1039 indent=4,
1040 separators=( ',', ': ' ) ) )
1041 # TODO check for a leader in all paritions
1042 # TODO check for consistency among nodes
1043 else:
1044 main.log.error( "partitions() returned None" )
1045 except ( ValueError, TypeError ):
1046 main.log.exception( "Error parsing partitions" )
1047 main.log.error( repr( partitions ) )
1048 pendingMap = main.ONOScli1.pendingMap()
1049 try:
1050 if pendingMap :
1051 parsedPending = json.loads( pendingMap )
1052 main.log.warn( json.dumps( parsedPending,
1053 sort_keys=True,
1054 indent=4,
1055 separators=( ',', ': ' ) ) )
1056 # TODO check something here?
1057 else:
1058 main.log.error( "pendingMap() returned None" )
1059 except ( ValueError, TypeError ):
1060 main.log.exception( "Error parsing pending map" )
1061 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001062 # Print flowrules
1063 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001064 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001065 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001066 PingResult = main.TRUE
1067 for i in range( 8, 18 ):
1068 ping = main.Mininet1.pingHost( src="h" + str( i ),
1069 target="h" + str( i + 10 ) )
1070 PingResult = PingResult and ping
1071 if ping == main.FALSE:
1072 main.log.warn( "Ping failed between h" + str( i ) +
1073 " and h" + str( i + 10 ) )
1074 elif ping == main.TRUE:
1075 main.log.info( "Ping test passed!" )
1076 # Don't set PingResult or you'd override failures
1077 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001078 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001079 "Intents have not been installed correctly, pings failed." )
1080 # TODO: pretty print
1081 main.log.warn( "ONOS1 intents: " )
1082 try:
1083 tmpIntents = main.ONOScli1.intents()
1084 main.log.warn( json.dumps( json.loads( tmpIntents ),
1085 sort_keys=True,
1086 indent=4,
1087 separators=( ',', ': ' ) ) )
1088 except ( ValueError, TypeError ):
1089 main.log.warn( repr( tmpIntents ) )
1090 utilities.assert_equals(
1091 expect=main.TRUE,
1092 actual=PingResult,
1093 onpass="Intents have been installed correctly and pings work",
1094 onfail="Intents have not been installed correctly, pings failed." )
1095
Jon Hall6aec96b2015-01-19 14:49:31 -08001096 def CASE5( self, main ):
1097 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001098 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001099 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001100 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001101 import time
1102 assert numControllers, "numControllers not defined"
1103 assert main, "main not defined"
1104 assert utilities.assert_equals, "utilities.assert_equals not defined"
1105 assert CLIs, "CLIs not defined"
1106 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001107
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 main.case( "Setting up and gathering data for current state" )
1109 # The general idea for this test case is to pull the state of
1110 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001111 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001112
Jon Hall5cfd23c2015-03-19 11:40:57 -07001113 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001114 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001115 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001116
Jon Hall6aec96b2015-01-19 14:49:31 -08001117 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001118 rolesNotNull = main.TRUE
1119 threads = []
1120 for i in range( numControllers ):
1121 t = main.Thread( target=CLIs[i].rolesNotNull,
1122 name="rolesNotNull-" + str( i ),
1123 args=[] )
1124 threads.append( t )
1125 t.start()
1126
1127 for t in threads:
1128 t.join()
1129 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001130 utilities.assert_equals(
1131 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001132 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001133 onpass="Each device has a master",
1134 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001135
Jon Hall5cfd23c2015-03-19 11:40:57 -07001136 main.step( "Get the Mastership of each switch from each controller" )
1137 ONOSMastership = []
1138 mastershipCheck = main.FALSE
1139 consistentMastership = True
1140 rolesResults = True
1141 threads = []
1142 for i in range( numControllers ):
1143 t = main.Thread( target=CLIs[i].roles,
1144 name="roles-" + str( i ),
1145 args=[] )
1146 threads.append( t )
1147 t.start()
1148
1149 for t in threads:
1150 t.join()
1151 ONOSMastership.append( t.result )
1152
1153 for i in range( numControllers ):
1154 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001155 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001156 " roles" )
1157 main.log.warn(
1158 "ONOS" + str( i + 1 ) + " mastership response: " +
1159 repr( ONOSMastership[i] ) )
1160 rolesResults = False
1161 utilities.assert_equals(
1162 expect=True,
1163 actual=rolesResults,
1164 onpass="No error in reading roles output",
1165 onfail="Error in reading roles from ONOS" )
1166
1167 main.step( "Check for consistency in roles from each controller" )
1168 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001169 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001170 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001171 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001172 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001173 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001174 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001175 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001176 onpass="Switch roles are consistent across all ONOS nodes",
1177 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001178
Jon Hall5cfd23c2015-03-19 11:40:57 -07001179 if rolesResults and not consistentMastership:
1180 for i in range( numControllers ):
1181 try:
1182 main.log.warn(
1183 "ONOS" + str( i + 1 ) + " roles: ",
1184 json.dumps(
1185 json.loads( ONOSMastership[ i ] ),
1186 sort_keys=True,
1187 indent=4,
1188 separators=( ',', ': ' ) ) )
1189 except ( ValueError, TypeError ):
1190 main.log.warn( repr( ONOSMastership[ i ] ) )
1191 elif rolesResults and consistentMastership:
1192 mastershipCheck = main.TRUE
1193 mastershipState = ONOSMastership[ 0 ]
1194
Jon Hall6aec96b2015-01-19 14:49:31 -08001195 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001196 global intentState
1197 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001198 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001199 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001200 consistentIntents = True
1201 intentsResults = True
1202 threads = []
1203 for i in range( numControllers ):
1204 t = main.Thread( target=CLIs[i].intents,
1205 name="intents-" + str( i ),
1206 args=[],
1207 kwargs={ 'jsonFormat': True } )
1208 threads.append( t )
1209 t.start()
1210
1211 for t in threads:
1212 t.join()
1213 ONOSIntents.append( t.result )
1214
1215 for i in range( numControllers ):
1216 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001217 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001218 " intents" )
1219 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1220 repr( ONOSIntents[ i ] ) )
1221 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001222 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001223 expect=True,
1224 actual=intentsResults,
1225 onpass="No error in reading intents output",
1226 onfail="Error in reading intents from ONOS" )
1227
1228 main.step( "Check for consistency in Intents from each controller" )
1229 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001230 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001231 "nodes" )
1232 else:
1233 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001234 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001235 utilities.assert_equals(
1236 expect=True,
1237 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001238 onpass="Intents are consistent across all ONOS nodes",
1239 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001240
Jon Hall390696c2015-05-05 17:13:41 -07001241 if intentsResults:
1242 # Try to make it easy to figure out what is happening
1243 #
1244 # Intent ONOS1 ONOS2 ...
1245 # 0x01 INSTALLED INSTALLING
1246 # ... ... ...
1247 # ... ... ...
1248 title = " Id"
1249 for n in range( numControllers ):
1250 title += " " * 10 + "ONOS" + str( n + 1 )
1251 main.log.warn( title )
1252 # get all intent keys in the cluster
1253 keys = []
1254 for nodeStr in ONOSIntents:
1255 node = json.loads( nodeStr )
1256 for intent in node:
1257 keys.append( intent.get( 'id' ) )
1258 keys = set( keys )
1259 for key in keys:
1260 row = "%-13s" % key
1261 for nodeStr in ONOSIntents:
1262 node = json.loads( nodeStr )
1263 for intent in node:
1264 if intent.get( 'id', "Error" ) == key:
1265 row += "%-15s" % intent.get( 'state' )
1266 main.log.warn( row )
1267 # End table view
1268
Jon Hall5cfd23c2015-03-19 11:40:57 -07001269 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001270 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001271 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001272 main.log.debug( "ONOS" + str( n ) + " intents: " )
1273 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1274 sort_keys=True,
1275 indent=4,
1276 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001277 for i in range( numControllers ):
1278 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001279 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1280 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1281 sort_keys=True,
1282 indent=4,
1283 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001284 else:
Jon Hall390696c2015-05-05 17:13:41 -07001285 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1286 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001287 elif intentsResults and consistentIntents:
1288 intentCheck = main.TRUE
1289 intentState = ONOSIntents[ 0 ]
1290
Jon Hall6aec96b2015-01-19 14:49:31 -08001291 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001292 global flowState
1293 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001294 ONOSFlows = []
1295 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001296 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001297 consistentFlows = True
1298 flowsResults = True
1299 threads = []
1300 for i in range( numControllers ):
1301 t = main.Thread( target=CLIs[i].flows,
1302 name="flows-" + str( i ),
1303 args=[],
1304 kwargs={ 'jsonFormat': True } )
1305 threads.append( t )
1306 t.start()
1307
Jon Halla9d26da2015-03-30 16:45:32 -07001308 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001309 time.sleep(30)
1310 for t in threads:
1311 t.join()
1312 result = t.result
1313 ONOSFlows.append( result )
1314
1315 for i in range( numControllers ):
1316 num = str( i + 1 )
1317 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001318 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001319 main.log.warn( "ONOS" + num + " flows response: " +
1320 repr( ONOSFlows[ i ] ) )
1321 flowsResults = False
1322 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001323 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001324 try:
1325 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1326 except ( ValueError, TypeError ):
1327 # FIXME: change this to log.error?
1328 main.log.exception( "Error in parsing ONOS" + num +
1329 " response as json." )
1330 main.log.error( repr( ONOSFlows[ i ] ) )
1331 ONOSFlowsJson.append( None )
1332 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001333 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001334 expect=True,
1335 actual=flowsResults,
1336 onpass="No error in reading flows output",
1337 onfail="Error in reading flows from ONOS" )
1338
1339 main.step( "Check for consistency in Flows from each controller" )
1340 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1341 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001342 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001343 else:
1344 consistentFlows = False
1345 utilities.assert_equals(
1346 expect=True,
1347 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001348 onpass="The flow count is consistent across all ONOS nodes",
1349 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001350
Jon Hall5cfd23c2015-03-19 11:40:57 -07001351 if flowsResults and not consistentFlows:
1352 for i in range( numControllers ):
1353 try:
1354 main.log.warn(
1355 "ONOS" + str( i + 1 ) + " flows: " +
1356 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1357 indent=4, separators=( ',', ': ' ) ) )
1358 except ( ValueError, TypeError ):
1359 main.log.warn(
1360 "ONOS" + str( i + 1 ) + " flows: " +
1361 repr( ONOSFlows[ i ] ) )
1362 elif flowsResults and consistentFlows:
1363 flowCheck = main.TRUE
1364 flowState = ONOSFlows[ 0 ]
1365
Jon Hall6aec96b2015-01-19 14:49:31 -08001366 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001367 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001368 flows = []
1369 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001370 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001371 if flowCheck == main.FALSE:
1372 for table in flows:
1373 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001374 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001375
Jon Hall6aec96b2015-01-19 14:49:31 -08001376 main.step( "Start continuous pings" )
1377 main.Mininet2.pingLong(
1378 src=main.params[ 'PING' ][ 'source1' ],
1379 target=main.params[ 'PING' ][ 'target1' ],
1380 pingTime=500 )
1381 main.Mininet2.pingLong(
1382 src=main.params[ 'PING' ][ 'source2' ],
1383 target=main.params[ 'PING' ][ 'target2' ],
1384 pingTime=500 )
1385 main.Mininet2.pingLong(
1386 src=main.params[ 'PING' ][ 'source3' ],
1387 target=main.params[ 'PING' ][ 'target3' ],
1388 pingTime=500 )
1389 main.Mininet2.pingLong(
1390 src=main.params[ 'PING' ][ 'source4' ],
1391 target=main.params[ 'PING' ][ 'target4' ],
1392 pingTime=500 )
1393 main.Mininet2.pingLong(
1394 src=main.params[ 'PING' ][ 'source5' ],
1395 target=main.params[ 'PING' ][ 'target5' ],
1396 pingTime=500 )
1397 main.Mininet2.pingLong(
1398 src=main.params[ 'PING' ][ 'source6' ],
1399 target=main.params[ 'PING' ][ 'target6' ],
1400 pingTime=500 )
1401 main.Mininet2.pingLong(
1402 src=main.params[ 'PING' ][ 'source7' ],
1403 target=main.params[ 'PING' ][ 'target7' ],
1404 pingTime=500 )
1405 main.Mininet2.pingLong(
1406 src=main.params[ 'PING' ][ 'source8' ],
1407 target=main.params[ 'PING' ][ 'target8' ],
1408 pingTime=500 )
1409 main.Mininet2.pingLong(
1410 src=main.params[ 'PING' ][ 'source9' ],
1411 target=main.params[ 'PING' ][ 'target9' ],
1412 pingTime=500 )
1413 main.Mininet2.pingLong(
1414 src=main.params[ 'PING' ][ 'source10' ],
1415 target=main.params[ 'PING' ][ 'target10' ],
1416 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001417
Jon Hall6aec96b2015-01-19 14:49:31 -08001418 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001419 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001420 threads = []
1421 for i in range( numControllers ):
1422 t = main.Thread( target=CLIs[i].devices,
1423 name="devices-" + str( i ),
1424 args=[ ] )
1425 threads.append( t )
1426 t.start()
1427
1428 for t in threads:
1429 t.join()
1430 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001431 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001432 threads = []
1433 for i in range( numControllers ):
1434 t = main.Thread( target=CLIs[i].hosts,
1435 name="hosts-" + str( i ),
1436 args=[ ] )
1437 threads.append( t )
1438 t.start()
1439
1440 for t in threads:
1441 t.join()
1442 try:
1443 hosts.append( json.loads( t.result ) )
1444 except ( ValueError, TypeError ):
1445 # FIXME: better handling of this, print which node
1446 # Maybe use thread name?
1447 main.log.exception( "Error parsing json output of hosts" )
1448 # FIXME: should this be an empty json object instead?
1449 hosts.append( None )
1450
Jon Hall73cf9cc2014-11-20 22:28:38 -08001451 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001452 threads = []
1453 for i in range( numControllers ):
1454 t = main.Thread( target=CLIs[i].ports,
1455 name="ports-" + str( i ),
1456 args=[ ] )
1457 threads.append( t )
1458 t.start()
1459
1460 for t in threads:
1461 t.join()
1462 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001463 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001464 threads = []
1465 for i in range( numControllers ):
1466 t = main.Thread( target=CLIs[i].links,
1467 name="links-" + str( i ),
1468 args=[ ] )
1469 threads.append( t )
1470 t.start()
1471
1472 for t in threads:
1473 t.join()
1474 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001475 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001476 threads = []
1477 for i in range( numControllers ):
1478 t = main.Thread( target=CLIs[i].clusters,
1479 name="clusters-" + str( i ),
1480 args=[ ] )
1481 threads.append( t )
1482 t.start()
1483
1484 for t in threads:
1485 t.join()
1486 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001487 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001488
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001490 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001491 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001492 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001493 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001494 if "Error" not in hosts[ controller ]:
1495 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001496 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001497 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001498 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001499 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001500 " is inconsistent with ONOS1" )
1501 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001502 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001503
1504 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001505 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001506 controllerStr )
1507 consistentHostsResult = main.FALSE
1508 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001509 " hosts response: " +
1510 repr( hosts[ controller ] ) )
1511 utilities.assert_equals(
1512 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001513 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001514 onpass="Hosts view is consistent across all ONOS nodes",
1515 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001516
Jon Hall390696c2015-05-05 17:13:41 -07001517 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001518 ipResult = main.TRUE
1519 for controller in range( 0, len( hosts ) ):
1520 controllerStr = str( controller + 1 )
1521 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001522 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001523 main.log.error( "DEBUG:Error with host ips on controller" +
1524 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001525 ipResult = main.FALSE
1526 utilities.assert_equals(
1527 expect=main.TRUE,
1528 actual=ipResult,
1529 onpass="The ips of the hosts aren't empty",
1530 onfail="The ip of at least one host is missing" )
1531
Jon Hall6aec96b2015-01-19 14:49:31 -08001532 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001533 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001534 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001535 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001536 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001537 if "Error" not in clusters[ controller ]:
1538 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001539 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001540 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001541 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001542 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001543 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001544
1545 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001546 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001547 "from ONOS" + controllerStr )
1548 consistentClustersResult = main.FALSE
1549 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001550 " clusters response: " +
1551 repr( clusters[ controller ] ) )
1552 utilities.assert_equals(
1553 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001554 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001555 onpass="Clusters view is consistent across all ONOS nodes",
1556 onfail="ONOS nodes have different views of clusters" )
1557 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001558 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001559 try:
1560 numClusters = len( json.loads( clusters[ 0 ] ) )
1561 except ( ValueError, TypeError ):
1562 main.log.exception( "Error parsing clusters[0]: " +
1563 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001564 clusterResults = main.FALSE
1565 if numClusters == 1:
1566 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001567 utilities.assert_equals(
1568 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001569 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001570 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001571 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001572
Jon Hall6aec96b2015-01-19 14:49:31 -08001573 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001574 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001575 linksResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001576 hostsResults = main.TRUE
1577 mnSwitches = main.Mininet1.getSwitches()
1578 mnLinks = main.Mininet1.getLinks()
1579 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001580 for controller in range( numControllers ):
1581 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001582 if devices[ controller ] and ports[ controller ] and\
1583 "Error" not in devices[ controller ] and\
1584 "Error" not in ports[ controller ]:
1585
Jon Hall8f89dda2015-01-22 16:03:33 -08001586 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001587 mnSwitches,
1588 json.loads( devices[ controller ] ),
1589 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001590 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001591 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001592 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001593 actual=currentDevicesResult,
1594 onpass="ONOS" + controllerStr +
1595 " Switches view is correct",
1596 onfail="ONOS" + controllerStr +
1597 " Switches view is incorrect" )
Jon Hallafa8a472015-06-12 14:02:42 -07001598 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001599 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001600 mnSwitches, mnLinks,
1601 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001602 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001603 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001604 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001605 actual=currentLinksResult,
1606 onpass="ONOS" + controllerStr +
1607 " links view is correct",
1608 onfail="ONOS" + controllerStr +
1609 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001610
Jon Hallafa8a472015-06-12 14:02:42 -07001611 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1612 currentHostsResult = main.Mininet1.compareHosts(
1613 mnHosts,
1614 hosts[ controller ] )
1615 else:
1616 currentHostsResult = main.FALSE
1617 utilities.assert_equals( expect=main.TRUE,
1618 actual=currentHostsResult,
1619 onpass="ONOS" + controllerStr +
1620 " hosts exist in Mininet",
1621 onfail="ONOS" + controllerStr +
1622 " hosts don't match Mininet" )
Jon Hallb6a54872015-06-12 14:02:42 -07001623
Jon Hallafa8a472015-06-12 14:02:42 -07001624 devicesResults = devicesResults and currentDevicesResult
1625 linksResults = linksResults and currentLinksResult
1626 hostsResults = hostsResults and currentHostsResult
1627
1628 main.step( "Device information is correct" )
1629 utilities.assert_equals(
1630 expect=main.TRUE,
1631 actual=devicesResults,
1632 onpass="Device information is correct",
1633 onfail="Device information is incorrect" )
1634
1635 main.step( "Links are correct" )
1636 utilities.assert_equals(
1637 expect=main.TRUE,
1638 actual=linksResults,
1639 onpass="Link are correct",
1640 onfail="Links are incorrect" )
1641
1642 main.step( "Hosts are correct" )
1643 utilities.assert_equals(
1644 expect=main.TRUE,
1645 actual=hostsResults,
1646 onpass="Hosts are correct",
1647 onfail="Hosts are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001648
Jon Hall6aec96b2015-01-19 14:49:31 -08001649 def CASE6( self, main ):
1650 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001651 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001652 """
Jon Hallfeff3082015-05-19 10:23:26 -07001653 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001654 assert numControllers, "numControllers not defined"
1655 assert main, "main not defined"
1656 assert utilities.assert_equals, "utilities.assert_equals not defined"
1657 assert CLIs, "CLIs not defined"
1658 assert nodes, "nodes not defined"
Jon Hallc9eabec2015-06-10 14:33:14 -07001659 try:
1660 labels
1661 except NameError:
1662 main.log.error( "labels not defined, setting to []" )
1663 global labels
1664 labels = []
1665 try:
1666 data
1667 except NameError:
1668 main.log.error( "data not defined, setting to []" )
1669 global data
1670 data = []
Jon Hall390696c2015-05-05 17:13:41 -07001671 # Reset non-persistent variables
1672 try:
1673 iCounterValue = 0
1674 except NameError:
1675 main.log.error( "iCounterValue not defined, setting to 0" )
1676 iCounterValue = 0
1677
Jon Hall5cfd23c2015-03-19 11:40:57 -07001678 main.case( "Restart entire ONOS cluster" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001679
Jon Hall5cfd23c2015-03-19 11:40:57 -07001680 main.step( "Killing ONOS nodes" )
1681 killResults = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001682 killTime = time.time()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001683 for node in nodes:
1684 killed = main.ONOSbench.onosKill( node.ip_address )
1685 killResults = killResults and killed
Jon Hall390696c2015-05-05 17:13:41 -07001686 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1687 onpass="ONOS nodes killed",
1688 onfail="ONOS kill unsuccessful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001689
Jon Hall6aec96b2015-01-19 14:49:31 -08001690 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001691 for i in range( 2 ):
1692 onosIsupResult = main.TRUE
1693 for node in nodes:
1694 started = main.ONOSbench.isup( node.ip_address )
1695 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001696 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001697 onosIsupResult = onosIsupResult and started
1698 if onosIsupResult == main.TRUE:
1699 break
Jon Hall390696c2015-05-05 17:13:41 -07001700 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1701 onpass="ONOS restarted",
1702 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001703
Jon Hall5cfd23c2015-03-19 11:40:57 -07001704 main.log.step( "Starting ONOS CLI sessions" )
1705 cliResults = main.TRUE
1706 threads = []
1707 for i in range( numControllers ):
1708 t = main.Thread( target=CLIs[i].startOnosCli,
1709 name="startOnosCli-" + str( i ),
1710 args=[nodes[i].ip_address] )
1711 threads.append( t )
1712 t.start()
1713
1714 for t in threads:
1715 t.join()
1716 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -07001717 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1718 onpass="ONOS cli started",
1719 onfail="ONOS clis did not restart" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001720
Jon Hallfeff3082015-05-19 10:23:26 -07001721 # Grab the time of restart so we chan check how long the gossip
1722 # protocol has had time to work
1723 main.restartTime = time.time() - killTime
1724 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001725 labels.append( "Restart" )
1726 data.append( str( main.restartTime ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001727
Jon Hallfeff3082015-05-19 10:23:26 -07001728 # FIXME: revisit test plan for election with madan
1729 # Rerun for election on restarted nodes
Jon Hall40d2cbd2015-06-03 16:24:29 -07001730 runResults = main.TRUE
1731 for cli in CLIs:
1732 run = CLIs[0].electionTestRun()
1733 if run != main.TRUE:
1734 main.log.error( "Error running for election on " + cli.name )
1735 runResults = runResults and run
Jon Hallfeff3082015-05-19 10:23:26 -07001736 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1737 onpass="Reran for election",
1738 onfail="Failed to rerun for election" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001739
1740 # TODO: Make this configurable
Jon Hallfeff3082015-05-19 10:23:26 -07001741 time.sleep( 60 )
1742 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1743 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1744 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001745
Jon Hall6aec96b2015-01-19 14:49:31 -08001746 def CASE7( self, main ):
1747 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001748 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001749 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001750 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001751 assert numControllers, "numControllers not defined"
1752 assert main, "main not defined"
1753 assert utilities.assert_equals, "utilities.assert_equals not defined"
1754 assert CLIs, "CLIs not defined"
1755 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001756 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001757
Jon Hall5cfd23c2015-03-19 11:40:57 -07001758 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001759 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001760 rolesNotNull = main.TRUE
1761 threads = []
1762 for i in range( numControllers ):
1763 t = main.Thread( target=CLIs[i].rolesNotNull,
1764 name="rolesNotNull-" + str( i ),
1765 args=[ ] )
1766 threads.append( t )
1767 t.start()
1768
1769 for t in threads:
1770 t.join()
1771 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001772 utilities.assert_equals(
1773 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001774 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001775 onpass="Each device has a master",
1776 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001777
Jon Hall390696c2015-05-05 17:13:41 -07001778 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001779 ONOSMastership = []
1780 mastershipCheck = main.FALSE
1781 consistentMastership = True
1782 rolesResults = True
1783 threads = []
1784 for i in range( numControllers ):
1785 t = main.Thread( target=CLIs[i].roles,
1786 name="roles-" + str( i ),
1787 args=[] )
1788 threads.append( t )
1789 t.start()
1790
1791 for t in threads:
1792 t.join()
1793 ONOSMastership.append( t.result )
1794
1795 for i in range( numControllers ):
1796 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001797 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001798 " roles" )
1799 main.log.warn(
1800 "ONOS" + str( i + 1 ) + " mastership response: " +
1801 repr( ONOSMastership[i] ) )
1802 rolesResults = False
1803 utilities.assert_equals(
1804 expect=True,
1805 actual=rolesResults,
1806 onpass="No error in reading roles output",
1807 onfail="Error in reading roles from ONOS" )
1808
1809 main.step( "Check for consistency in roles from each controller" )
1810 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001811 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001812 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001813 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001814 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001815 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001816 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001817 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001818 onpass="Switch roles are consistent across all ONOS nodes",
1819 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001820
Jon Hall5cfd23c2015-03-19 11:40:57 -07001821 if rolesResults and not consistentMastership:
1822 for i in range( numControllers ):
1823 main.log.warn(
1824 "ONOS" + str( i + 1 ) + " roles: ",
1825 json.dumps(
1826 json.loads( ONOSMastership[ i ] ),
1827 sort_keys=True,
1828 indent=4,
1829 separators=( ',', ': ' ) ) )
1830 elif rolesResults and not consistentMastership:
1831 mastershipCheck = main.TRUE
1832
Jon Hallfeff3082015-05-19 10:23:26 -07001833 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001834 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001835 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001836 try:
1837 currentJson = json.loads( ONOSMastership[0] )
1838 oldJson = json.loads( mastershipState )
1839 except ( ValueError, TypeError ):
1840 main.log.exception( "Something is wrong with parsing " +
1841 "ONOSMastership[0] or mastershipState" )
1842 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1843 main.log.error( "mastershipState" + repr( mastershipState ) )
1844 main.cleanup()
1845 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001846 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001847 for i in range( 1, 29 ):
1848 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001849 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001850 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001851 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001852 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001853 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001854 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001855 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001856 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001857 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001858 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001859 utilities.assert_equals(
1860 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001861 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001862 onpass="Mastership of Switches was not changed",
1863 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001864 '''
Jon Hall6aec96b2015-01-19 14:49:31 -08001865 # NOTE: we expect mastership to change on controller failure
Jon Hall73cf9cc2014-11-20 22:28:38 -08001866
Jon Hall6aec96b2015-01-19 14:49:31 -08001867 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001868 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001869 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001870 consistentIntents = True
1871 intentsResults = True
1872 threads = []
1873 for i in range( numControllers ):
1874 t = main.Thread( target=CLIs[i].intents,
1875 name="intents-" + str( i ),
1876 args=[],
1877 kwargs={ 'jsonFormat': True } )
1878 threads.append( t )
1879 t.start()
1880
1881 for t in threads:
1882 t.join()
1883 ONOSIntents.append( t.result )
1884
1885 for i in range( numControllers ):
1886 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001887 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001888 " intents" )
1889 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1890 repr( ONOSIntents[ i ] ) )
1891 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001892 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001893 expect=True,
1894 actual=intentsResults,
1895 onpass="No error in reading intents output",
1896 onfail="Error in reading intents from ONOS" )
1897
1898 main.step( "Check for consistency in Intents from each controller" )
1899 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001900 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001901 "nodes" )
1902 else:
1903 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001904
1905 # Try to make it easy to figure out what is happening
1906 #
1907 # Intent ONOS1 ONOS2 ...
1908 # 0x01 INSTALLED INSTALLING
1909 # ... ... ...
1910 # ... ... ...
1911 title = " ID"
1912 for n in range( numControllers ):
1913 title += " " * 10 + "ONOS" + str( n + 1 )
1914 main.log.warn( title )
1915 # get all intent keys in the cluster
1916 keys = []
1917 for nodeStr in ONOSIntents:
1918 node = json.loads( nodeStr )
1919 for intent in node:
1920 keys.append( intent.get( 'id' ) )
1921 keys = set( keys )
1922 for key in keys:
1923 row = "%-13s" % key
1924 for nodeStr in ONOSIntents:
1925 node = json.loads( nodeStr )
1926 for intent in node:
1927 if intent.get( 'id' ) == key:
1928 row += "%-15s" % intent.get( 'state' )
1929 main.log.warn( row )
1930 # End table view
1931
Jon Hall5cfd23c2015-03-19 11:40:57 -07001932 utilities.assert_equals(
1933 expect=True,
1934 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001935 onpass="Intents are consistent across all ONOS nodes",
1936 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001937 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001938 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001939 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001940 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001941 try:
1942 for intent in json.loads( node ):
1943 nodeStates.append( intent[ 'state' ] )
1944 except ( ValueError, TypeError ):
1945 main.log.exception( "Error in parsing intents" )
1946 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001947 intentStates.append( nodeStates )
1948 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1949 main.log.info( dict( out ) )
1950
Jon Hall5cfd23c2015-03-19 11:40:57 -07001951 if intentsResults and not consistentIntents:
1952 for i in range( numControllers ):
1953 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1954 main.log.warn( json.dumps(
1955 json.loads( ONOSIntents[ i ] ),
1956 sort_keys=True,
1957 indent=4,
1958 separators=( ',', ': ' ) ) )
1959 elif intentsResults and consistentIntents:
1960 intentCheck = main.TRUE
1961
Jon Hall58c76b72015-02-23 11:09:24 -08001962 # NOTE: Store has no durability, so intents are lost across system
1963 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001964 """
1965 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001966 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001967 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001968 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001969 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001970 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001971 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001973 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001974 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1975 sameIntents = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001976 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001977 before = json.loads( intentState )
1978 after = json.loads( ONOSIntents[ 0 ] )
1979 for intent in before:
1980 if intent not in after:
1981 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001982 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001983 "(at least in the same form):" )
1984 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001985 except ( ValueError, TypeError ):
1986 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001987 main.log.debug( repr( ONOSIntents[0] ) )
1988 main.log.debug( repr( intentState ) )
1989 if sameIntents == main.FALSE:
1990 try:
1991 main.log.debug( "ONOS intents before: " )
1992 main.log.debug( json.dumps( json.loads( intentState ),
1993 sort_keys=True, indent=4,
1994 separators=( ',', ': ' ) ) )
1995 main.log.debug( "Current ONOS intents: " )
1996 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1997 sort_keys=True, indent=4,
1998 separators=( ',', ': ' ) ) )
1999 except ( ValueError, TypeError ):
2000 main.log.exception( "Exception printing intents" )
2001 main.log.debug( repr( ONOSIntents[0] ) )
2002 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 utilities.assert_equals(
2004 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002005 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08002006 onpass="Intents are consistent with before failure",
2007 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002008 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08002009 """
2010 main.step( "Get the OF Table entries and compare to before " +
2011 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002012 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002013 flows2 = []
2014 for i in range( 28 ):
2015 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002016 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
2017 flows2.append( tmpFlows )
2018 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08002019 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08002020 flow2=tmpFlows )
2021 FlowTables = FlowTables and tempResult
2022 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002023 main.log.info( "Differences in flow table for switch: s" +
2024 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002025 utilities.assert_equals(
2026 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002027 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08002028 onpass="No changes were found in the flow tables",
2029 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002030
Jon Hall40d2cbd2015-06-03 16:24:29 -07002031 # main.step( "Check the continuous pings to ensure that no packets " +
2032 # "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002033 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2034 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08002035 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002036 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2037 for i in range( 8, 18 ):
2038 main.log.info(
2039 "Checking for a loss in pings along flow from s" +
2040 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002041 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08002042 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002043 str( i ) ) or LossInPings
2044 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002045 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002046 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08002047 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002048 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002049 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002050 main.log.info( "No loss of dataplane connectivity" )
2051 # utilities.assert_equals(
2052 # expect=main.FALSE,
2053 # actual=LossInPings,
2054 # onpass="No Loss of connectivity",
2055 # onfail="Loss of dataplane connectivity detected" )
2056
Jon Hall58c76b72015-02-23 11:09:24 -08002057 # NOTE: Since intents are not persisted with IntnentStore,
2058 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08002059 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002060
Jon Hall390696c2015-05-05 17:13:41 -07002061 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002062 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08002063 leaderList = []
2064 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002065 for cli in CLIs:
2066 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08002067 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002068 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002069 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07002070 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002071 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002072 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002073 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002074 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002075 main.log.error( cli.name +
2076 " shows no leader for the election-app." )
Jon Hall8f89dda2015-01-22 16:03:33 -08002077 leaderResult = main.FALSE
2078 if len( set( leaderList ) ) != 1:
2079 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002080 main.log.error(
2081 "Inconsistent view of leader for the election test app" )
2082 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 utilities.assert_equals(
2084 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002085 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002086 onpass="Leadership election passed",
2087 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002088
Jon Hall6aec96b2015-01-19 14:49:31 -08002089 def CASE8( self, main ):
2090 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002091 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002092 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002093 import json
2094 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002095 assert numControllers, "numControllers not defined"
2096 assert main, "main not defined"
2097 assert utilities.assert_equals, "utilities.assert_equals not defined"
2098 assert CLIs, "CLIs not defined"
2099 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002100
Jon Hallfeff3082015-05-19 10:23:26 -07002101 main.case( "Compare ONOS Topology view to Mininet topology" )
2102 main.caseExplaination = "Compare topology objects between Mininet" +\
2103 " and ONOS"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002104
Jon Hallfeff3082015-05-19 10:23:26 -07002105 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002106 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002107 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002108 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002109 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002110 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002111 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002112 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002113 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002114 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002115 # Give time for Gossip to work
Jon Hallc9eabec2015-06-10 14:33:14 -07002116 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002117 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002118 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002119 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002120 threads = []
2121 for i in range( numControllers ):
2122 t = main.Thread( target=CLIs[i].devices,
2123 name="devices-" + str( i ),
2124 args=[ ] )
2125 threads.append( t )
2126 t.start()
2127
2128 for t in threads:
2129 t.join()
2130 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002131 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002132 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002133 threads = []
2134 for i in range( numControllers ):
2135 t = main.Thread( target=CLIs[i].hosts,
2136 name="hosts-" + str( i ),
2137 args=[ ] )
2138 threads.append( t )
2139 t.start()
2140
2141 for t in threads:
2142 t.join()
2143 try:
2144 hosts.append( json.loads( t.result ) )
2145 except ( ValueError, TypeError ):
2146 main.log.exception( "Error parsing hosts results" )
2147 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002148 for controller in range( 0, len( hosts ) ):
2149 controllerStr = str( controller + 1 )
2150 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002151 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002152 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07002153 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002154 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002155 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002156 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002157 threads = []
2158 for i in range( numControllers ):
2159 t = main.Thread( target=CLIs[i].ports,
2160 name="ports-" + str( i ),
2161 args=[ ] )
2162 threads.append( t )
2163 t.start()
2164
2165 for t in threads:
2166 t.join()
2167 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002168 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002169 threads = []
2170 for i in range( numControllers ):
2171 t = main.Thread( target=CLIs[i].links,
2172 name="links-" + str( i ),
2173 args=[ ] )
2174 threads.append( t )
2175 t.start()
2176
2177 for t in threads:
2178 t.join()
2179 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002180 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002181 threads = []
2182 for i in range( numControllers ):
2183 t = main.Thread( target=CLIs[i].clusters,
2184 name="clusters-" + str( i ),
2185 args=[ ] )
2186 threads.append( t )
2187 t.start()
2188
2189 for t in threads:
2190 t.join()
2191 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002192
Jon Hall8f89dda2015-01-22 16:03:33 -08002193 elapsed = time.time() - startTime
2194 cliTime = time.time() - cliStart
Jon Hall40d2cbd2015-06-03 16:24:29 -07002195 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002196 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002197
Jon Hallafa8a472015-06-12 14:02:42 -07002198 mnSwitches = main.Mininet1.getSwitches()
2199 mnLinks = main.Mininet1.getLinks()
2200 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08002201 for controller in range( numControllers ):
2202 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07002203 if devices[ controller ] and ports[ controller ] and\
2204 "Error" not in devices[ controller ] and\
2205 "Error" not in ports[ controller ]:
2206
Jon Hall8f89dda2015-01-22 16:03:33 -08002207 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07002208 mnSwitches,
2209 json.loads( devices[ controller ] ),
2210 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002211 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002212 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002213 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002214 actual=currentDevicesResult,
2215 onpass="ONOS" + controllerStr +
2216 " Switches view is correct",
2217 onfail="ONOS" + controllerStr +
2218 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002219
Jon Hallafa8a472015-06-12 14:02:42 -07002220 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002221 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07002222 mnSwitches, mnLinks,
2223 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002224 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002225 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002226 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002227 actual=currentLinksResult,
2228 onpass="ONOS" + controllerStr +
2229 " links view is correct",
2230 onfail="ONOS" + controllerStr +
2231 " links view is incorrect" )
2232
2233 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2234 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07002235 mnHosts,
2236 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002237 else:
2238 currentHostsResult = main.FALSE
2239 utilities.assert_equals( expect=main.TRUE,
2240 actual=currentHostsResult,
2241 onpass="ONOS" + controllerStr +
2242 " hosts exist in Mininet",
2243 onfail="ONOS" + controllerStr +
2244 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002245 # CHECKING HOST ATTACHMENT POINTS
2246 hostAttachment = True
Jon Hall0f523f22015-07-06 09:31:09 -07002247 noHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002248 # FIXME: topo-HA/obelisk specific mappings:
2249 # key is mac and value is dpid
2250 mappings = {}
2251 for i in range( 1, 29 ): # hosts 1 through 28
2252 # set up correct variables:
2253 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2254 if i == 1:
2255 deviceId = "1000".zfill(16)
2256 elif i == 2:
2257 deviceId = "2000".zfill(16)
2258 elif i == 3:
2259 deviceId = "3000".zfill(16)
2260 elif i == 4:
2261 deviceId = "3004".zfill(16)
2262 elif i == 5:
2263 deviceId = "5000".zfill(16)
2264 elif i == 6:
2265 deviceId = "6000".zfill(16)
2266 elif i == 7:
2267 deviceId = "6007".zfill(16)
2268 elif i >= 8 and i <= 17:
2269 dpid = '3' + str( i ).zfill( 3 )
2270 deviceId = dpid.zfill(16)
2271 elif i >= 18 and i <= 27:
2272 dpid = '6' + str( i ).zfill( 3 )
2273 deviceId = dpid.zfill(16)
2274 elif i == 28:
2275 deviceId = "2800".zfill(16)
2276 mappings[ macId ] = deviceId
2277 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2278 if hosts[ controller ] == []:
2279 main.log.warn( "There are no hosts discovered" )
Jon Hall0f523f22015-07-06 09:31:09 -07002280 noHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002281 else:
2282 for host in hosts[ controller ]:
2283 mac = None
2284 location = None
2285 device = None
2286 port = None
2287 try:
2288 mac = host.get( 'mac' )
2289 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002290
Jon Hallc9eabec2015-06-10 14:33:14 -07002291 location = host.get( 'location' )
2292 assert location, "location field could not be found for this host object"
2293
2294 # Trim the protocol identifier off deviceId
2295 device = str( location.get( 'elementId' ) ).split(':')[1]
2296 assert device, "elementId field could not be found for this host location object"
2297
2298 port = location.get( 'port' )
2299 assert port, "port field could not be found for this host location object"
2300
2301 # Now check if this matches where they should be
2302 if mac and device and port:
2303 if str( port ) != "1":
2304 main.log.error( "The attachment port is incorrect for " +
2305 "host " + str( mac ) +
2306 ". Expected: 1 Actual: " + str( port) )
2307 hostAttachment = False
2308 if device != mappings[ str( mac ) ]:
2309 main.log.error( "The attachment device is incorrect for " +
2310 "host " + str( mac ) +
2311 ". Expected: " + mappings[ str( mac ) ] +
2312 " Actual: " + device )
2313 hostAttachment = False
2314 else:
2315 hostAttachment = False
2316 except AssertionError:
2317 main.log.exception( "Json object not as expected" )
2318 main.log.error( repr( host ) )
2319 hostAttachment = False
2320 else:
2321 main.log.error( "No hosts json output or \"Error\"" +
2322 " in output. hosts = " +
2323 repr( hosts[ controller ] ) )
Jon Hall0f523f22015-07-06 09:31:09 -07002324 if noHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002325 # TODO: Find a way to know if there should be hosts in a
2326 # given point of the test
2327 hostAttachment = True
2328
2329 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002330 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002331 linksResults = linksResults and currentLinksResult
2332 hostsResults = hostsResults and currentHostsResult
Jon Hallafa8a472015-06-12 14:02:42 -07002333 hostAttachmentResults = hostAttachmentResults and\
2334 hostAttachment
2335 topoResult = ( devicesResults and linksResults
2336 and hostsResults and ipResult and
2337 hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002338
Jon Hallc9eabec2015-06-10 14:33:14 -07002339 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002340
Jon Hallc9eabec2015-06-10 14:33:14 -07002341 # hosts
2342 main.step( "Hosts view is consistent across all ONOS nodes" )
2343 consistentHostsResult = main.TRUE
2344 for controller in range( len( hosts ) ):
2345 controllerStr = str( controller + 1 )
2346 if "Error" not in hosts[ controller ]:
2347 if hosts[ controller ] == hosts[ 0 ]:
2348 continue
2349 else: # hosts not consistent
2350 main.log.error( "hosts from ONOS" + controllerStr +
2351 " is inconsistent with ONOS1" )
2352 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002353 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002354
Jon Hallc9eabec2015-06-10 14:33:14 -07002355 else:
2356 main.log.error( "Error in getting ONOS hosts from ONOS" +
2357 controllerStr )
2358 consistentHostsResult = main.FALSE
2359 main.log.warn( "ONOS" + controllerStr +
2360 " hosts response: " +
2361 repr( hosts[ controller ] ) )
2362 utilities.assert_equals(
2363 expect=main.TRUE,
2364 actual=consistentHostsResult,
2365 onpass="Hosts view is consistent across all ONOS nodes",
2366 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002367
Jon Hallc9eabec2015-06-10 14:33:14 -07002368 main.step( "Hosts information is correct" )
2369 hostsResults = hostsResults and ipResult
2370 utilities.assert_equals(
2371 expect=main.TRUE,
2372 actual=hostsResults,
2373 onpass="Host information is correct",
2374 onfail="Host information is incorrect" )
2375
2376 main.step( "Host attachment points to the network" )
2377 utilities.assert_equals(
2378 expect=True,
2379 actual=hostAttachmentResults,
2380 onpass="Hosts are correctly attached to the network",
2381 onfail="ONOS did not correctly attach hosts to the network" )
2382
2383 # Strongly connected clusters of devices
2384 main.step( "Clusters view is consistent across all ONOS nodes" )
2385 consistentClustersResult = main.TRUE
2386 for controller in range( len( clusters ) ):
2387 controllerStr = str( controller + 1 )
2388 if "Error" not in clusters[ controller ]:
2389 if clusters[ controller ] == clusters[ 0 ]:
2390 continue
2391 else: # clusters not consistent
2392 main.log.error( "clusters from ONOS" +
2393 controllerStr +
2394 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002395 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002396
Jon Hallc9eabec2015-06-10 14:33:14 -07002397 else:
2398 main.log.error( "Error in getting dataplane clusters " +
2399 "from ONOS" + controllerStr )
2400 consistentClustersResult = main.FALSE
2401 main.log.warn( "ONOS" + controllerStr +
2402 " clusters response: " +
2403 repr( clusters[ controller ] ) )
2404 utilities.assert_equals(
2405 expect=main.TRUE,
2406 actual=consistentClustersResult,
2407 onpass="Clusters view is consistent across all ONOS nodes",
2408 onfail="ONOS nodes have different views of clusters" )
2409
2410 main.step( "There is only one SCC" )
2411 # there should always only be one cluster
2412 try:
2413 numClusters = len( json.loads( clusters[ 0 ] ) )
2414 except ( ValueError, TypeError ):
2415 main.log.exception( "Error parsing clusters[0]: " +
2416 repr( clusters[0] ) )
2417 clusterResults = main.FALSE
2418 if numClusters == 1:
2419 clusterResults = main.TRUE
2420 utilities.assert_equals(
2421 expect=1,
2422 actual=numClusters,
2423 onpass="ONOS shows 1 SCC",
2424 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2425
Jon Hallafa8a472015-06-12 14:02:42 -07002426 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002427 and hostsResults and consistentHostsResult
2428 and consistentClustersResult and clusterResults
2429 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002430
Jon Hall8f89dda2015-01-22 16:03:33 -08002431 topoResult = topoResult and int( count <= 2 )
2432 note = "note it takes about " + str( int( cliTime ) ) + \
2433 " seconds for the test to make all the cli calls to fetch " +\
2434 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002435 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002436 "Very crass estimate for topology discovery/convergence( " +
2437 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002438 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002439
2440 main.step( "Device information is correct" )
2441 utilities.assert_equals(
2442 expect=main.TRUE,
2443 actual=devicesResults,
2444 onpass="Device information is correct",
2445 onfail="Device information is incorrect" )
2446
Jon Hallc9eabec2015-06-10 14:33:14 -07002447 main.step( "Links are correct" )
2448 utilities.assert_equals(
2449 expect=main.TRUE,
2450 actual=linksResults,
2451 onpass="Link are correct",
2452 onfail="Links are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002453
Jon Halla9d26da2015-03-30 16:45:32 -07002454 # FIXME: move this to an ONOS state case
2455 main.step( "Checking ONOS nodes" )
2456 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002457 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002458 threads = []
2459 for i in range( numControllers ):
2460 t = main.Thread( target=CLIs[i].nodes,
2461 name="nodes-" + str( i ),
2462 args=[ ] )
2463 threads.append( t )
2464 t.start()
2465
2466 for t in threads:
2467 t.join()
2468 nodesOutput.append( t.result )
2469 ips = [ node.ip_address for node in nodes ]
2470 for i in nodesOutput:
2471 try:
2472 current = json.loads( i )
2473 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002474 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002475 if node['ip'] in ips: # node in nodes() output is in cell
2476 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002477 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002478 else:
2479 main.log.error( "Error in ONOS node availability" )
2480 main.log.error(
2481 json.dumps( current,
2482 sort_keys=True,
2483 indent=4,
2484 separators=( ',', ': ' ) ) )
2485 break
Jon Hall390696c2015-05-05 17:13:41 -07002486 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002487 except ( ValueError, TypeError ):
2488 main.log.error( "Error parsing nodes output" )
2489 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002490 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2491 onpass="Nodes check successful",
2492 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002493
Jon Hall6aec96b2015-01-19 14:49:31 -08002494 def CASE9( self, main ):
2495 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002496 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002497 """
2498 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002499 assert numControllers, "numControllers not defined"
2500 assert main, "main not defined"
2501 assert utilities.assert_equals, "utilities.assert_equals not defined"
2502 assert CLIs, "CLIs not defined"
2503 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002504 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002505
Jon Hall8f89dda2015-01-22 16:03:33 -08002506 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002507
Jon Hall6aec96b2015-01-19 14:49:31 -08002508 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002509 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002510 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002511
Jon Hall6aec96b2015-01-19 14:49:31 -08002512 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002513 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002514 main.log.info( "Waiting " + str( linkSleep ) +
2515 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002516 time.sleep( linkSleep )
2517 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002518 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002519 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002520 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002521
Jon Hall6aec96b2015-01-19 14:49:31 -08002522 def CASE10( self, main ):
2523 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002524 Link s3-s28 up
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 = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002537 "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( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002541 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002542 main.log.info( "Waiting " + str( linkSleep ) +
2543 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002544 time.sleep( linkSleep )
2545 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002546 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002547 onfail="Failed to bring link up" )
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 CASE11( self, main ):
2551 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002552 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002553 """
2554 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002555 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002556 assert numControllers, "numControllers not defined"
2557 assert main, "main not defined"
2558 assert utilities.assert_equals, "utilities.assert_equals not defined"
2559 assert CLIs, "CLIs not defined"
2560 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002561
Jon Hall8f89dda2015-01-22 16:03:33 -08002562 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002563
2564 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002565 main.case( description )
2566 switch = main.params[ 'kill' ][ 'switch' ]
2567 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002568
Jon Hall6aec96b2015-01-19 14:49:31 -08002569 # TODO: Make this switch parameterizable
2570 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002571 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002572 main.Mininet1.delSwitch( switch )
2573 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002574 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002575 time.sleep( switchSleep )
2576 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002577 # Peek at the deleted switch
2578 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002579 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002580 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002581 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002582 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002583 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002584 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002585
Jon Hall6aec96b2015-01-19 14:49:31 -08002586 def CASE12( self, main ):
2587 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002588 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002589 """
2590 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002591 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002592 assert numControllers, "numControllers not defined"
2593 assert main, "main not defined"
2594 assert utilities.assert_equals, "utilities.assert_equals not defined"
2595 assert CLIs, "CLIs not defined"
2596 assert nodes, "nodes not defined"
2597 assert ONOS1Port, "ONOS1Port not defined"
2598 assert ONOS2Port, "ONOS2Port not defined"
2599 assert ONOS3Port, "ONOS3Port not defined"
2600 assert ONOS4Port, "ONOS4Port not defined"
2601 assert ONOS5Port, "ONOS5Port not defined"
2602 assert ONOS6Port, "ONOS6Port not defined"
2603 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002604
Jon Hall8f89dda2015-01-22 16:03:33 -08002605 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002606 switch = main.params[ 'kill' ][ 'switch' ]
2607 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2608 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002609 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002610 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002611
Jon Hall6aec96b2015-01-19 14:49:31 -08002612 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002613 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002614 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002615 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002616 ipList = []
2617 for i in range( numControllers ):
2618 ipList.append( nodes[ i ].ip_address )
2619 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002620 main.log.info( "Waiting " + str( switchSleep ) +
2621 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002622 time.sleep( switchSleep )
2623 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002624 # Peek at the deleted switch
2625 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002626 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002627 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002628 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002629 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002630 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002631 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002632
Jon Hall6aec96b2015-01-19 14:49:31 -08002633 def CASE13( self, main ):
2634 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002635 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002636 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002637 import os
2638 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002639 assert numControllers, "numControllers not defined"
2640 assert main, "main not defined"
2641 assert utilities.assert_equals, "utilities.assert_equals not defined"
2642 assert CLIs, "CLIs not defined"
2643 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002644
2645 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002646 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2647 'blue': '\033[94m', 'green': '\033[92m',
2648 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002649 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002650 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002651 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002652
Jon Hall6aec96b2015-01-19 14:49:31 -08002653 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002654 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002655 teststationUser = main.params[ 'TESTONUSER' ]
2656 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002657 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002658 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002659 # FIXME: scp
2660 # mn files
2661 # TODO: Load these from params
2662 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002663 logFolder = "/opt/onos/log/"
2664 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002665 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002666 dstDir = "~/packet_captures/"
2667 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002668 for node in nodes:
2669 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2670 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002671 teststationUser + "@" +
2672 teststationIP + ":" +
2673 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002674 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002675 main.ONOSbench.handle.expect( "\$" )
2676
Jon Hall6aec96b2015-01-19 14:49:31 -08002677 # std*.log's
2678 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002679 logFolder = "/opt/onos/var/"
2680 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002681 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002682 dstDir = "~/packet_captures/"
2683 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002684 for node in nodes:
2685 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2686 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002687 teststationUser + "@" +
2688 teststationIP + ":" +
2689 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002690 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002691 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002692 # sleep so scp can finish
2693 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002694
2695 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002696 mnResult = main.Mininet1.stopNet()
2697 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2698 onpass="Mininet stopped",
2699 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002700
2701 main.step( "Checking ONOS Logs for errors" )
2702 for node in nodes:
2703 print colors[ 'purple' ] + "Checking logs for errors on " + \
2704 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002705 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002706
Jon Hall6aec96b2015-01-19 14:49:31 -08002707 main.step( "Packing and rotating pcap archives" )
2708 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002709
Jon Hallfeff3082015-05-19 10:23:26 -07002710 try:
2711 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hallc9eabec2015-06-10 14:33:14 -07002712 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2713 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
Jon Hallfeff3082015-05-19 10:23:26 -07002714 timerLog.close()
2715 except NameError, e:
2716 main.log.exception(e)
2717
Jon Hall6aec96b2015-01-19 14:49:31 -08002718 def CASE14( self, main ):
2719 """
Jon Hall669173b2014-12-17 11:36:30 -08002720 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002721 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002722 assert numControllers, "numControllers not defined"
2723 assert main, "main not defined"
2724 assert utilities.assert_equals, "utilities.assert_equals not defined"
2725 assert CLIs, "CLIs not defined"
2726 assert nodes, "nodes not defined"
2727
Jon Hall390696c2015-05-05 17:13:41 -07002728 main.case("Start Leadership Election app")
2729 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002730 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2731 utilities.assert_equals(
2732 expect=main.TRUE,
2733 actual=appResult,
2734 onpass="Election app installed",
2735 onfail="Something went wrong with installing Leadership election" )
2736
2737 main.step( "Run for election on each node" )
2738 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002739 leaders = []
2740 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002741 cli.electionTestRun()
2742 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002743 leader = cli.electionTestLeader()
2744 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002745 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002746 "should be an ONOS node, instead got '" +
2747 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002748 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002749 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002750 utilities.assert_equals(
2751 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002752 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002753 onpass="Successfully ran for leadership",
2754 onfail="Failed to run for leadership" )
2755
2756 main.step( "Check that each node shows the same leader" )
2757 sameLeader = main.TRUE
2758 if len( set( leaders ) ) != 1:
2759 sameLeader = main.FALSE
2760 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2761 str( leaders ) )
2762 utilities.assert_equals(
2763 expect=main.TRUE,
2764 actual=sameLeader,
2765 onpass="Leadership is consistent for the election topic",
2766 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002767
Jon Hall6aec96b2015-01-19 14:49:31 -08002768 def CASE15( self, main ):
2769 """
Jon Hall669173b2014-12-17 11:36:30 -08002770 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002771 """
Jon Hall390696c2015-05-05 17:13:41 -07002772 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002773 assert numControllers, "numControllers not defined"
2774 assert main, "main not defined"
2775 assert utilities.assert_equals, "utilities.assert_equals not defined"
2776 assert CLIs, "CLIs not defined"
2777 assert nodes, "nodes not defined"
2778
Jon Hall8f89dda2015-01-22 16:03:33 -08002779 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002780 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002781 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002782 # NOTE: Need to re-run since being a canidate is not persistant
2783 main.step( "Run for election on each node" )
2784 leaderResult = main.TRUE
2785 leaders = []
2786 for cli in CLIs:
2787 cli.electionTestRun()
2788 for cli in CLIs:
2789 leader = cli.electionTestLeader()
2790 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002791 main.log.error( cli.name + ": Leader for the election app " +
Jon Hallfeff3082015-05-19 10:23:26 -07002792 "should be an ONOS node, instead got '" +
2793 str( leader ) + "'" )
2794 leaderResult = main.FALSE
2795 leaders.append( leader )
2796 utilities.assert_equals(
2797 expect=main.TRUE,
2798 actual=leaderResult,
2799 onpass="Successfully ran for leadership",
2800 onfail="Failed to run for leadership" )
2801
2802 main.step( "Check that each node shows the same leader" )
2803 sameLeader = main.TRUE
2804 if len( set( leaders ) ) != 1:
2805 sameLeader = main.FALSE
2806 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2807 str( leaders ) )
2808 utilities.assert_equals(
2809 expect=main.TRUE,
2810 actual=sameLeader,
2811 onpass="Leadership is consistent for the election topic",
2812 onfail="Nodes have different leaders" )
2813
Jon Hall6aec96b2015-01-19 14:49:31 -08002814 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002815 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002816 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002817 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002818 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002819 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002820 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002821 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002822 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002823 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002824 for i in range( len( CLIs ) ):
2825 if leader == nodes[ i ].ip_address:
2826 oldLeader = CLIs[ i ]
2827 break
Jon Halla9d26da2015-03-30 16:45:32 -07002828 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002829 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002830 if oldLeader:
2831 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002832 utilities.assert_equals(
2833 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002834 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002835 onpass="Node was withdrawn from election",
2836 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002837
Jon Hall6aec96b2015-01-19 14:49:31 -08002838 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002839 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002840 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002841 for cli in CLIs:
2842 leaderN = cli.electionTestLeader()
2843 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002844 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002845 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002846 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002847 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002848 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002849 # error in response
2850 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002851 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002852 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002853 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002854 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002855 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002856 elif leaderN is None:
2857 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002858 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002859 leaderN = cli.electionTestLeader()
2860 leaderList.pop()
2861 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002862 consistentLeader = main.FALSE
2863 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002864 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002865 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002866 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002867 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002868 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002869 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002870 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002871 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002872 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002873 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002874 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002875 utilities.assert_equals(
2876 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002877 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002878 onpass="Leadership election passed",
2879 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002880
Jon Hall58c76b72015-02-23 11:09:24 -08002881 main.step( "Run for election on old leader( just so everyone " +
2882 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002883 if oldLeader:
2884 runResult = oldLeader.electionTestRun()
2885 else:
2886 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002887 utilities.assert_equals(
2888 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002889 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002890 onpass="App re-ran for election",
2891 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002892
Jon Hallfeff3082015-05-19 10:23:26 -07002893 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002894 afterRun = main.ONOScli1.electionTestLeader()
2895 # verify leader didn't just change
2896 if afterRun == leaderList[ 0 ]:
2897 afterResult = main.TRUE
2898 else:
2899 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002900
Jon Hall6aec96b2015-01-19 14:49:31 -08002901 utilities.assert_equals(
2902 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002903 actual=afterResult,
2904 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002905 onfail="Something went wrong with Leadership election after " +
2906 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002907
Jon Hall390696c2015-05-05 17:13:41 -07002908 def CASE16( self, main ):
2909 """
2910 Install Distributed Primitives app
2911 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002912 import time
Jon Hall390696c2015-05-05 17:13:41 -07002913 assert numControllers, "numControllers not defined"
2914 assert main, "main not defined"
2915 assert utilities.assert_equals, "utilities.assert_equals not defined"
2916 assert CLIs, "CLIs not defined"
2917 assert nodes, "nodes not defined"
2918
2919 # Variables for the distributed primitives tests
2920 global pCounterName
2921 global iCounterName
2922 global pCounterValue
2923 global iCounterValue
2924 global onosSet
2925 global onosSetName
2926 pCounterName = "TestON-Partitions"
2927 iCounterName = "TestON-inMemory"
2928 pCounterValue = 0
2929 iCounterValue = 0
2930 onosSet = set([])
2931 onosSetName = "TestON-set"
2932
2933 description = "Install Primitives app"
2934 main.case( description )
2935 main.step( "Install Primitives app" )
2936 appName = "org.onosproject.distributedprimitives"
2937 appResults = CLIs[0].activateApp( appName )
2938 utilities.assert_equals( expect=main.TRUE,
2939 actual=appResults,
2940 onpass="Primitives app activated",
2941 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002942 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002943
2944 def CASE17( self, main ):
2945 """
2946 Check for basic functionality with distributed primitives
2947 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002948 import json
Jon Hall390696c2015-05-05 17:13:41 -07002949 # Make sure variables are defined/set
2950 assert numControllers, "numControllers not defined"
2951 assert main, "main not defined"
2952 assert utilities.assert_equals, "utilities.assert_equals not defined"
2953 assert CLIs, "CLIs not defined"
2954 assert nodes, "nodes not defined"
2955 assert pCounterName, "pCounterName not defined"
2956 assert iCounterName, "iCounterName not defined"
2957 assert onosSetName, "onosSetName not defined"
2958 # NOTE: assert fails if value is 0/None/Empty/False
2959 try:
2960 pCounterValue
2961 except NameError:
2962 main.log.error( "pCounterValue not defined, setting to 0" )
2963 pCounterValue = 0
2964 try:
2965 iCounterValue
2966 except NameError:
2967 main.log.error( "iCounterValue not defined, setting to 0" )
2968 iCounterValue = 0
2969 try:
2970 onosSet
2971 except NameError:
2972 main.log.error( "onosSet not defined, setting to empty Set" )
2973 onosSet = set([])
2974 # Variables for the distributed primitives tests. These are local only
2975 addValue = "a"
2976 addAllValue = "a b c d e f"
2977 retainValue = "c d e f"
2978
2979 description = "Check for basic functionality with distributed " +\
2980 "primitives"
2981 main.case( description )
2982 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2983 # DISTRIBUTED ATOMIC COUNTERS
2984 main.step( "Increment and get a default counter on each node" )
2985 pCounters = []
2986 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002987 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002988 for i in range( numControllers ):
2989 t = main.Thread( target=CLIs[i].counterTestIncrement,
2990 name="counterIncrement-" + str( i ),
2991 args=[ pCounterName ] )
2992 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002993 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002994 threads.append( t )
2995 t.start()
2996
2997 for t in threads:
2998 t.join()
2999 pCounters.append( t.result )
3000 # Check that counter incremented numController times
3001 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07003002 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003003 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07003004 pCounterResults = pCounterResults and tmpResult
3005 if not tmpResult:
3006 main.log.error( str( i ) + " is not in partitioned "
3007 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07003008 utilities.assert_equals( expect=True,
3009 actual=pCounterResults,
3010 onpass="Default counter incremented",
3011 onfail="Error incrementing default" +
3012 " counter" )
3013
3014 main.step( "Increment and get an in memory counter on each node" )
3015 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07003016 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07003017 threads = []
3018 for i in range( numControllers ):
3019 t = main.Thread( target=CLIs[i].counterTestIncrement,
3020 name="icounterIncrement-" + str( i ),
3021 args=[ iCounterName ],
3022 kwargs={ "inMemory": True } )
3023 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07003024 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07003025 threads.append( t )
3026 t.start()
3027
3028 for t in threads:
3029 t.join()
3030 iCounters.append( t.result )
3031 # Check that counter incremented numController times
3032 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07003033 for i in addedIValues:
3034 tmpResult = i in iCounters
3035 iCounterResults = iCounterResults and tmpResult
3036 if not tmpResult:
3037 main.log.error( str( i ) + " is not in the in-memory "
3038 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07003039 utilities.assert_equals( expect=True,
3040 actual=iCounterResults,
3041 onpass="In memory counter incremented",
3042 onfail="Error incrementing in memory" +
3043 " counter" )
3044
3045 main.step( "Check counters are consistant across nodes" )
3046 onosCounters = []
3047 threads = []
3048 for i in range( numControllers ):
3049 t = main.Thread( target=CLIs[i].counters,
3050 name="counters-" + str( i ) )
3051 threads.append( t )
3052 t.start()
3053 for t in threads:
3054 t.join()
3055 onosCounters.append( t.result )
3056 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3057 if all( tmp ):
3058 main.log.info( "Counters are consistent across all nodes" )
3059 consistentCounterResults = main.TRUE
3060 else:
3061 main.log.error( "Counters are not consistent across all nodes" )
3062 consistentCounterResults = main.FALSE
3063 utilities.assert_equals( expect=main.TRUE,
3064 actual=consistentCounterResults,
3065 onpass="ONOS counters are consistent " +
3066 "across nodes",
3067 onfail="ONOS Counters are inconsistent " +
3068 "across nodes" )
3069
3070 main.step( "Counters we added have the correct values" )
3071 correctResults = main.TRUE
3072 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07003073 current = json.loads( onosCounters[i] )
3074 pValue = None
3075 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003076 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003077 for database in current:
3078 partitioned = database.get( 'partitionedDatabaseCounters' )
3079 if partitioned:
3080 for value in partitioned:
3081 if value.get( 'name' ) == pCounterName:
3082 pValue = value.get( 'value' )
3083 break
3084 inMemory = database.get( 'inMemoryDatabaseCounters' )
3085 if inMemory:
3086 for value in inMemory:
3087 if value.get( 'name' ) == iCounterName:
3088 iValue = value.get( 'value' )
3089 break
Jon Hall390696c2015-05-05 17:13:41 -07003090 except AttributeError, e:
3091 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3092 "is not as expected" )
3093 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003094 if pValue == pCounterValue:
3095 main.log.info( "Partitioned counter value is correct" )
3096 else:
3097 main.log.error( "Partitioned counter value is incorrect," +
3098 " expected value: " + str( pCounterValue )
3099 + " current value: " + str( pValue ) )
3100 correctResults = main.FALSE
3101 if iValue == iCounterValue:
3102 main.log.info( "In memory counter value is correct" )
3103 else:
3104 main.log.error( "In memory counter value is incorrect, " +
3105 "expected value: " + str( iCounterValue ) +
3106 " current value: " + str( iValue ) )
3107 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003108 utilities.assert_equals( expect=main.TRUE,
3109 actual=correctResults,
3110 onpass="Added counters are correct",
3111 onfail="Added counters are incorrect" )
3112 # DISTRIBUTED SETS
3113 main.step( "Distributed Set get" )
3114 size = len( onosSet )
3115 getResponses = []
3116 threads = []
3117 for i in range( numControllers ):
3118 t = main.Thread( target=CLIs[i].setTestGet,
3119 name="setTestGet-" + str( i ),
3120 args=[ onosSetName ] )
3121 threads.append( t )
3122 t.start()
3123 for t in threads:
3124 t.join()
3125 getResponses.append( t.result )
3126
3127 getResults = main.TRUE
3128 for i in range( numControllers ):
3129 if isinstance( getResponses[ i ], list):
3130 current = set( getResponses[ i ] )
3131 if len( current ) == len( getResponses[ i ] ):
3132 # no repeats
3133 if onosSet != current:
3134 main.log.error( "ONOS" + str( i + 1 ) +
3135 " has incorrect view" +
3136 " of set " + onosSetName + ":\n" +
3137 str( getResponses[ i ] ) )
3138 main.log.debug( "Expected: " + str( onosSet ) )
3139 main.log.debug( "Actual: " + str( current ) )
3140 getResults = main.FALSE
3141 else:
3142 # error, set is not a set
3143 main.log.error( "ONOS" + str( i + 1 ) +
3144 " has repeat elements in" +
3145 " set " + onosSetName + ":\n" +
3146 str( getResponses[ i ] ) )
3147 getResults = main.FALSE
3148 elif getResponses[ i ] == main.ERROR:
3149 getResults = main.FALSE
3150 utilities.assert_equals( expect=main.TRUE,
3151 actual=getResults,
3152 onpass="Set elements are correct",
3153 onfail="Set elements are incorrect" )
3154
3155 main.step( "Distributed Set size" )
3156 sizeResponses = []
3157 threads = []
3158 for i in range( numControllers ):
3159 t = main.Thread( target=CLIs[i].setTestSize,
3160 name="setTestSize-" + str( i ),
3161 args=[ onosSetName ] )
3162 threads.append( t )
3163 t.start()
3164 for t in threads:
3165 t.join()
3166 sizeResponses.append( t.result )
3167
3168 sizeResults = main.TRUE
3169 for i in range( numControllers ):
3170 if size != sizeResponses[ i ]:
3171 sizeResults = main.FALSE
3172 main.log.error( "ONOS" + str( i + 1 ) +
3173 " expected a size of " + str( size ) +
3174 " for set " + onosSetName +
3175 " but got " + str( sizeResponses[ i ] ) )
3176 utilities.assert_equals( expect=main.TRUE,
3177 actual=sizeResults,
3178 onpass="Set sizes are correct",
3179 onfail="Set sizes are incorrect" )
3180
3181 main.step( "Distributed Set add()" )
3182 onosSet.add( addValue )
3183 addResponses = []
3184 threads = []
3185 for i in range( numControllers ):
3186 t = main.Thread( target=CLIs[i].setTestAdd,
3187 name="setTestAdd-" + str( i ),
3188 args=[ onosSetName, addValue ] )
3189 threads.append( t )
3190 t.start()
3191 for t in threads:
3192 t.join()
3193 addResponses.append( t.result )
3194
3195 # main.TRUE = successfully changed the set
3196 # main.FALSE = action resulted in no change in set
3197 # main.ERROR - Some error in executing the function
3198 addResults = main.TRUE
3199 for i in range( numControllers ):
3200 if addResponses[ i ] == main.TRUE:
3201 # All is well
3202 pass
3203 elif addResponses[ i ] == main.FALSE:
3204 # Already in set, probably fine
3205 pass
3206 elif addResponses[ i ] == main.ERROR:
3207 # Error in execution
3208 addResults = main.FALSE
3209 else:
3210 # unexpected result
3211 addResults = main.FALSE
3212 if addResults != main.TRUE:
3213 main.log.error( "Error executing set add" )
3214
3215 # Check if set is still correct
3216 size = len( onosSet )
3217 getResponses = []
3218 threads = []
3219 for i in range( numControllers ):
3220 t = main.Thread( target=CLIs[i].setTestGet,
3221 name="setTestGet-" + str( i ),
3222 args=[ onosSetName ] )
3223 threads.append( t )
3224 t.start()
3225 for t in threads:
3226 t.join()
3227 getResponses.append( t.result )
3228 getResults = main.TRUE
3229 for i in range( numControllers ):
3230 if isinstance( getResponses[ i ], list):
3231 current = set( getResponses[ i ] )
3232 if len( current ) == len( getResponses[ i ] ):
3233 # no repeats
3234 if onosSet != current:
3235 main.log.error( "ONOS" + str( i + 1 ) +
3236 " has incorrect view" +
3237 " of set " + onosSetName + ":\n" +
3238 str( getResponses[ i ] ) )
3239 main.log.debug( "Expected: " + str( onosSet ) )
3240 main.log.debug( "Actual: " + str( current ) )
3241 getResults = main.FALSE
3242 else:
3243 # error, set is not a set
3244 main.log.error( "ONOS" + str( i + 1 ) +
3245 " has repeat elements in" +
3246 " set " + onosSetName + ":\n" +
3247 str( getResponses[ i ] ) )
3248 getResults = main.FALSE
3249 elif getResponses[ i ] == main.ERROR:
3250 getResults = main.FALSE
3251 sizeResponses = []
3252 threads = []
3253 for i in range( numControllers ):
3254 t = main.Thread( target=CLIs[i].setTestSize,
3255 name="setTestSize-" + str( i ),
3256 args=[ onosSetName ] )
3257 threads.append( t )
3258 t.start()
3259 for t in threads:
3260 t.join()
3261 sizeResponses.append( t.result )
3262 sizeResults = main.TRUE
3263 for i in range( numControllers ):
3264 if size != sizeResponses[ i ]:
3265 sizeResults = main.FALSE
3266 main.log.error( "ONOS" + str( i + 1 ) +
3267 " expected a size of " + str( size ) +
3268 " for set " + onosSetName +
3269 " but got " + str( sizeResponses[ i ] ) )
3270 addResults = addResults and getResults and sizeResults
3271 utilities.assert_equals( expect=main.TRUE,
3272 actual=addResults,
3273 onpass="Set add correct",
3274 onfail="Set add was incorrect" )
3275
3276 main.step( "Distributed Set addAll()" )
3277 onosSet.update( addAllValue.split() )
3278 addResponses = []
3279 threads = []
3280 for i in range( numControllers ):
3281 t = main.Thread( target=CLIs[i].setTestAdd,
3282 name="setTestAddAll-" + str( i ),
3283 args=[ onosSetName, addAllValue ] )
3284 threads.append( t )
3285 t.start()
3286 for t in threads:
3287 t.join()
3288 addResponses.append( t.result )
3289
3290 # main.TRUE = successfully changed the set
3291 # main.FALSE = action resulted in no change in set
3292 # main.ERROR - Some error in executing the function
3293 addAllResults = main.TRUE
3294 for i in range( numControllers ):
3295 if addResponses[ i ] == main.TRUE:
3296 # All is well
3297 pass
3298 elif addResponses[ i ] == main.FALSE:
3299 # Already in set, probably fine
3300 pass
3301 elif addResponses[ i ] == main.ERROR:
3302 # Error in execution
3303 addAllResults = main.FALSE
3304 else:
3305 # unexpected result
3306 addAllResults = main.FALSE
3307 if addAllResults != main.TRUE:
3308 main.log.error( "Error executing set addAll" )
3309
3310 # Check if set is still correct
3311 size = len( onosSet )
3312 getResponses = []
3313 threads = []
3314 for i in range( numControllers ):
3315 t = main.Thread( target=CLIs[i].setTestGet,
3316 name="setTestGet-" + str( i ),
3317 args=[ onosSetName ] )
3318 threads.append( t )
3319 t.start()
3320 for t in threads:
3321 t.join()
3322 getResponses.append( t.result )
3323 getResults = main.TRUE
3324 for i in range( numControllers ):
3325 if isinstance( getResponses[ i ], list):
3326 current = set( getResponses[ i ] )
3327 if len( current ) == len( getResponses[ i ] ):
3328 # no repeats
3329 if onosSet != current:
3330 main.log.error( "ONOS" + str( i + 1 ) +
3331 " has incorrect view" +
3332 " of set " + onosSetName + ":\n" +
3333 str( getResponses[ i ] ) )
3334 main.log.debug( "Expected: " + str( onosSet ) )
3335 main.log.debug( "Actual: " + str( current ) )
3336 getResults = main.FALSE
3337 else:
3338 # error, set is not a set
3339 main.log.error( "ONOS" + str( i + 1 ) +
3340 " has repeat elements in" +
3341 " set " + onosSetName + ":\n" +
3342 str( getResponses[ i ] ) )
3343 getResults = main.FALSE
3344 elif getResponses[ i ] == main.ERROR:
3345 getResults = main.FALSE
3346 sizeResponses = []
3347 threads = []
3348 for i in range( numControllers ):
3349 t = main.Thread( target=CLIs[i].setTestSize,
3350 name="setTestSize-" + str( i ),
3351 args=[ onosSetName ] )
3352 threads.append( t )
3353 t.start()
3354 for t in threads:
3355 t.join()
3356 sizeResponses.append( t.result )
3357 sizeResults = main.TRUE
3358 for i in range( numControllers ):
3359 if size != sizeResponses[ i ]:
3360 sizeResults = main.FALSE
3361 main.log.error( "ONOS" + str( i + 1 ) +
3362 " expected a size of " + str( size ) +
3363 " for set " + onosSetName +
3364 " but got " + str( sizeResponses[ i ] ) )
3365 addAllResults = addAllResults and getResults and sizeResults
3366 utilities.assert_equals( expect=main.TRUE,
3367 actual=addAllResults,
3368 onpass="Set addAll correct",
3369 onfail="Set addAll was incorrect" )
3370
3371 main.step( "Distributed Set contains()" )
3372 containsResponses = []
3373 threads = []
3374 for i in range( numControllers ):
3375 t = main.Thread( target=CLIs[i].setTestGet,
3376 name="setContains-" + str( i ),
3377 args=[ onosSetName ],
3378 kwargs={ "values": addValue } )
3379 threads.append( t )
3380 t.start()
3381 for t in threads:
3382 t.join()
3383 # NOTE: This is the tuple
3384 containsResponses.append( t.result )
3385
3386 containsResults = main.TRUE
3387 for i in range( numControllers ):
3388 if containsResponses[ i ] == main.ERROR:
3389 containsResults = main.FALSE
3390 else:
3391 containsResults = containsResults and\
3392 containsResponses[ i ][ 1 ]
3393 utilities.assert_equals( expect=main.TRUE,
3394 actual=containsResults,
3395 onpass="Set contains is functional",
3396 onfail="Set contains failed" )
3397
3398 main.step( "Distributed Set containsAll()" )
3399 containsAllResponses = []
3400 threads = []
3401 for i in range( numControllers ):
3402 t = main.Thread( target=CLIs[i].setTestGet,
3403 name="setContainsAll-" + str( i ),
3404 args=[ onosSetName ],
3405 kwargs={ "values": addAllValue } )
3406 threads.append( t )
3407 t.start()
3408 for t in threads:
3409 t.join()
3410 # NOTE: This is the tuple
3411 containsAllResponses.append( t.result )
3412
3413 containsAllResults = main.TRUE
3414 for i in range( numControllers ):
3415 if containsResponses[ i ] == main.ERROR:
3416 containsResults = main.FALSE
3417 else:
3418 containsResults = containsResults and\
3419 containsResponses[ i ][ 1 ]
3420 utilities.assert_equals( expect=main.TRUE,
3421 actual=containsAllResults,
3422 onpass="Set containsAll is functional",
3423 onfail="Set containsAll failed" )
3424
3425 main.step( "Distributed Set remove()" )
3426 onosSet.remove( addValue )
3427 removeResponses = []
3428 threads = []
3429 for i in range( numControllers ):
3430 t = main.Thread( target=CLIs[i].setTestRemove,
3431 name="setTestRemove-" + str( i ),
3432 args=[ onosSetName, addValue ] )
3433 threads.append( t )
3434 t.start()
3435 for t in threads:
3436 t.join()
3437 removeResponses.append( t.result )
3438
3439 # main.TRUE = successfully changed the set
3440 # main.FALSE = action resulted in no change in set
3441 # main.ERROR - Some error in executing the function
3442 removeResults = main.TRUE
3443 for i in range( numControllers ):
3444 if removeResponses[ i ] == main.TRUE:
3445 # All is well
3446 pass
3447 elif removeResponses[ i ] == main.FALSE:
3448 # not in set, probably fine
3449 pass
3450 elif removeResponses[ i ] == main.ERROR:
3451 # Error in execution
3452 removeResults = main.FALSE
3453 else:
3454 # unexpected result
3455 removeResults = main.FALSE
3456 if removeResults != main.TRUE:
3457 main.log.error( "Error executing set remove" )
3458
3459 # Check if set is still correct
3460 size = len( onosSet )
3461 getResponses = []
3462 threads = []
3463 for i in range( numControllers ):
3464 t = main.Thread( target=CLIs[i].setTestGet,
3465 name="setTestGet-" + str( i ),
3466 args=[ onosSetName ] )
3467 threads.append( t )
3468 t.start()
3469 for t in threads:
3470 t.join()
3471 getResponses.append( t.result )
3472 getResults = main.TRUE
3473 for i in range( numControllers ):
3474 if isinstance( getResponses[ i ], list):
3475 current = set( getResponses[ i ] )
3476 if len( current ) == len( getResponses[ i ] ):
3477 # no repeats
3478 if onosSet != current:
3479 main.log.error( "ONOS" + str( i + 1 ) +
3480 " has incorrect view" +
3481 " of set " + onosSetName + ":\n" +
3482 str( getResponses[ i ] ) )
3483 main.log.debug( "Expected: " + str( onosSet ) )
3484 main.log.debug( "Actual: " + str( current ) )
3485 getResults = main.FALSE
3486 else:
3487 # error, set is not a set
3488 main.log.error( "ONOS" + str( i + 1 ) +
3489 " has repeat elements in" +
3490 " set " + onosSetName + ":\n" +
3491 str( getResponses[ i ] ) )
3492 getResults = main.FALSE
3493 elif getResponses[ i ] == main.ERROR:
3494 getResults = main.FALSE
3495 sizeResponses = []
3496 threads = []
3497 for i in range( numControllers ):
3498 t = main.Thread( target=CLIs[i].setTestSize,
3499 name="setTestSize-" + str( i ),
3500 args=[ onosSetName ] )
3501 threads.append( t )
3502 t.start()
3503 for t in threads:
3504 t.join()
3505 sizeResponses.append( t.result )
3506 sizeResults = main.TRUE
3507 for i in range( numControllers ):
3508 if size != sizeResponses[ i ]:
3509 sizeResults = main.FALSE
3510 main.log.error( "ONOS" + str( i + 1 ) +
3511 " expected a size of " + str( size ) +
3512 " for set " + onosSetName +
3513 " but got " + str( sizeResponses[ i ] ) )
3514 removeResults = removeResults and getResults and sizeResults
3515 utilities.assert_equals( expect=main.TRUE,
3516 actual=removeResults,
3517 onpass="Set remove correct",
3518 onfail="Set remove was incorrect" )
3519
3520 main.step( "Distributed Set removeAll()" )
3521 onosSet.difference_update( addAllValue.split() )
3522 removeAllResponses = []
3523 threads = []
3524 try:
3525 for i in range( numControllers ):
3526 t = main.Thread( target=CLIs[i].setTestRemove,
3527 name="setTestRemoveAll-" + str( i ),
3528 args=[ onosSetName, addAllValue ] )
3529 threads.append( t )
3530 t.start()
3531 for t in threads:
3532 t.join()
3533 removeAllResponses.append( t.result )
3534 except Exception, e:
3535 main.log.exception(e)
3536
3537 # main.TRUE = successfully changed the set
3538 # main.FALSE = action resulted in no change in set
3539 # main.ERROR - Some error in executing the function
3540 removeAllResults = main.TRUE
3541 for i in range( numControllers ):
3542 if removeAllResponses[ i ] == main.TRUE:
3543 # All is well
3544 pass
3545 elif removeAllResponses[ i ] == main.FALSE:
3546 # not in set, probably fine
3547 pass
3548 elif removeAllResponses[ i ] == main.ERROR:
3549 # Error in execution
3550 removeAllResults = main.FALSE
3551 else:
3552 # unexpected result
3553 removeAllResults = main.FALSE
3554 if removeAllResults != main.TRUE:
3555 main.log.error( "Error executing set removeAll" )
3556
3557 # Check if set is still correct
3558 size = len( onosSet )
3559 getResponses = []
3560 threads = []
3561 for i in range( numControllers ):
3562 t = main.Thread( target=CLIs[i].setTestGet,
3563 name="setTestGet-" + str( i ),
3564 args=[ onosSetName ] )
3565 threads.append( t )
3566 t.start()
3567 for t in threads:
3568 t.join()
3569 getResponses.append( t.result )
3570 getResults = main.TRUE
3571 for i in range( numControllers ):
3572 if isinstance( getResponses[ i ], list):
3573 current = set( getResponses[ i ] )
3574 if len( current ) == len( getResponses[ i ] ):
3575 # no repeats
3576 if onosSet != current:
3577 main.log.error( "ONOS" + str( i + 1 ) +
3578 " has incorrect view" +
3579 " of set " + onosSetName + ":\n" +
3580 str( getResponses[ i ] ) )
3581 main.log.debug( "Expected: " + str( onosSet ) )
3582 main.log.debug( "Actual: " + str( current ) )
3583 getResults = main.FALSE
3584 else:
3585 # error, set is not a set
3586 main.log.error( "ONOS" + str( i + 1 ) +
3587 " has repeat elements in" +
3588 " set " + onosSetName + ":\n" +
3589 str( getResponses[ i ] ) )
3590 getResults = main.FALSE
3591 elif getResponses[ i ] == main.ERROR:
3592 getResults = main.FALSE
3593 sizeResponses = []
3594 threads = []
3595 for i in range( numControllers ):
3596 t = main.Thread( target=CLIs[i].setTestSize,
3597 name="setTestSize-" + str( i ),
3598 args=[ onosSetName ] )
3599 threads.append( t )
3600 t.start()
3601 for t in threads:
3602 t.join()
3603 sizeResponses.append( t.result )
3604 sizeResults = main.TRUE
3605 for i in range( numControllers ):
3606 if size != sizeResponses[ i ]:
3607 sizeResults = main.FALSE
3608 main.log.error( "ONOS" + str( i + 1 ) +
3609 " expected a size of " + str( size ) +
3610 " for set " + onosSetName +
3611 " but got " + str( sizeResponses[ i ] ) )
3612 removeAllResults = removeAllResults and getResults and sizeResults
3613 utilities.assert_equals( expect=main.TRUE,
3614 actual=removeAllResults,
3615 onpass="Set removeAll correct",
3616 onfail="Set removeAll was incorrect" )
3617
3618 main.step( "Distributed Set addAll()" )
3619 onosSet.update( addAllValue.split() )
3620 addResponses = []
3621 threads = []
3622 for i in range( numControllers ):
3623 t = main.Thread( target=CLIs[i].setTestAdd,
3624 name="setTestAddAll-" + str( i ),
3625 args=[ onosSetName, addAllValue ] )
3626 threads.append( t )
3627 t.start()
3628 for t in threads:
3629 t.join()
3630 addResponses.append( t.result )
3631
3632 # main.TRUE = successfully changed the set
3633 # main.FALSE = action resulted in no change in set
3634 # main.ERROR - Some error in executing the function
3635 addAllResults = main.TRUE
3636 for i in range( numControllers ):
3637 if addResponses[ i ] == main.TRUE:
3638 # All is well
3639 pass
3640 elif addResponses[ i ] == main.FALSE:
3641 # Already in set, probably fine
3642 pass
3643 elif addResponses[ i ] == main.ERROR:
3644 # Error in execution
3645 addAllResults = main.FALSE
3646 else:
3647 # unexpected result
3648 addAllResults = main.FALSE
3649 if addAllResults != main.TRUE:
3650 main.log.error( "Error executing set addAll" )
3651
3652 # Check if set is still correct
3653 size = len( onosSet )
3654 getResponses = []
3655 threads = []
3656 for i in range( numControllers ):
3657 t = main.Thread( target=CLIs[i].setTestGet,
3658 name="setTestGet-" + str( i ),
3659 args=[ onosSetName ] )
3660 threads.append( t )
3661 t.start()
3662 for t in threads:
3663 t.join()
3664 getResponses.append( t.result )
3665 getResults = main.TRUE
3666 for i in range( numControllers ):
3667 if isinstance( getResponses[ i ], list):
3668 current = set( getResponses[ i ] )
3669 if len( current ) == len( getResponses[ i ] ):
3670 # no repeats
3671 if onosSet != current:
3672 main.log.error( "ONOS" + str( i + 1 ) +
3673 " has incorrect view" +
3674 " of set " + onosSetName + ":\n" +
3675 str( getResponses[ i ] ) )
3676 main.log.debug( "Expected: " + str( onosSet ) )
3677 main.log.debug( "Actual: " + str( current ) )
3678 getResults = main.FALSE
3679 else:
3680 # error, set is not a set
3681 main.log.error( "ONOS" + str( i + 1 ) +
3682 " has repeat elements in" +
3683 " set " + onosSetName + ":\n" +
3684 str( getResponses[ i ] ) )
3685 getResults = main.FALSE
3686 elif getResponses[ i ] == main.ERROR:
3687 getResults = main.FALSE
3688 sizeResponses = []
3689 threads = []
3690 for i in range( numControllers ):
3691 t = main.Thread( target=CLIs[i].setTestSize,
3692 name="setTestSize-" + str( i ),
3693 args=[ onosSetName ] )
3694 threads.append( t )
3695 t.start()
3696 for t in threads:
3697 t.join()
3698 sizeResponses.append( t.result )
3699 sizeResults = main.TRUE
3700 for i in range( numControllers ):
3701 if size != sizeResponses[ i ]:
3702 sizeResults = main.FALSE
3703 main.log.error( "ONOS" + str( i + 1 ) +
3704 " expected a size of " + str( size ) +
3705 " for set " + onosSetName +
3706 " but got " + str( sizeResponses[ i ] ) )
3707 addAllResults = addAllResults and getResults and sizeResults
3708 utilities.assert_equals( expect=main.TRUE,
3709 actual=addAllResults,
3710 onpass="Set addAll correct",
3711 onfail="Set addAll was incorrect" )
3712
3713 main.step( "Distributed Set clear()" )
3714 onosSet.clear()
3715 clearResponses = []
3716 threads = []
3717 for i in range( numControllers ):
3718 t = main.Thread( target=CLIs[i].setTestRemove,
3719 name="setTestClear-" + str( i ),
3720 args=[ onosSetName, " "], # Values doesn't matter
3721 kwargs={ "clear": True } )
3722 threads.append( t )
3723 t.start()
3724 for t in threads:
3725 t.join()
3726 clearResponses.append( t.result )
3727
3728 # main.TRUE = successfully changed the set
3729 # main.FALSE = action resulted in no change in set
3730 # main.ERROR - Some error in executing the function
3731 clearResults = main.TRUE
3732 for i in range( numControllers ):
3733 if clearResponses[ i ] == main.TRUE:
3734 # All is well
3735 pass
3736 elif clearResponses[ i ] == main.FALSE:
3737 # Nothing set, probably fine
3738 pass
3739 elif clearResponses[ i ] == main.ERROR:
3740 # Error in execution
3741 clearResults = main.FALSE
3742 else:
3743 # unexpected result
3744 clearResults = main.FALSE
3745 if clearResults != main.TRUE:
3746 main.log.error( "Error executing set clear" )
3747
3748 # Check if set is still correct
3749 size = len( onosSet )
3750 getResponses = []
3751 threads = []
3752 for i in range( numControllers ):
3753 t = main.Thread( target=CLIs[i].setTestGet,
3754 name="setTestGet-" + str( i ),
3755 args=[ onosSetName ] )
3756 threads.append( t )
3757 t.start()
3758 for t in threads:
3759 t.join()
3760 getResponses.append( t.result )
3761 getResults = main.TRUE
3762 for i in range( numControllers ):
3763 if isinstance( getResponses[ i ], list):
3764 current = set( getResponses[ i ] )
3765 if len( current ) == len( getResponses[ i ] ):
3766 # no repeats
3767 if onosSet != current:
3768 main.log.error( "ONOS" + str( i + 1 ) +
3769 " has incorrect view" +
3770 " of set " + onosSetName + ":\n" +
3771 str( getResponses[ i ] ) )
3772 main.log.debug( "Expected: " + str( onosSet ) )
3773 main.log.debug( "Actual: " + str( current ) )
3774 getResults = main.FALSE
3775 else:
3776 # error, set is not a set
3777 main.log.error( "ONOS" + str( i + 1 ) +
3778 " has repeat elements in" +
3779 " set " + onosSetName + ":\n" +
3780 str( getResponses[ i ] ) )
3781 getResults = main.FALSE
3782 elif getResponses[ i ] == main.ERROR:
3783 getResults = main.FALSE
3784 sizeResponses = []
3785 threads = []
3786 for i in range( numControllers ):
3787 t = main.Thread( target=CLIs[i].setTestSize,
3788 name="setTestSize-" + str( i ),
3789 args=[ onosSetName ] )
3790 threads.append( t )
3791 t.start()
3792 for t in threads:
3793 t.join()
3794 sizeResponses.append( t.result )
3795 sizeResults = main.TRUE
3796 for i in range( numControllers ):
3797 if size != sizeResponses[ i ]:
3798 sizeResults = main.FALSE
3799 main.log.error( "ONOS" + str( i + 1 ) +
3800 " expected a size of " + str( size ) +
3801 " for set " + onosSetName +
3802 " but got " + str( sizeResponses[ i ] ) )
3803 clearResults = clearResults and getResults and sizeResults
3804 utilities.assert_equals( expect=main.TRUE,
3805 actual=clearResults,
3806 onpass="Set clear correct",
3807 onfail="Set clear was incorrect" )
3808
3809 main.step( "Distributed Set addAll()" )
3810 onosSet.update( addAllValue.split() )
3811 addResponses = []
3812 threads = []
3813 for i in range( numControllers ):
3814 t = main.Thread( target=CLIs[i].setTestAdd,
3815 name="setTestAddAll-" + str( i ),
3816 args=[ onosSetName, addAllValue ] )
3817 threads.append( t )
3818 t.start()
3819 for t in threads:
3820 t.join()
3821 addResponses.append( t.result )
3822
3823 # main.TRUE = successfully changed the set
3824 # main.FALSE = action resulted in no change in set
3825 # main.ERROR - Some error in executing the function
3826 addAllResults = main.TRUE
3827 for i in range( numControllers ):
3828 if addResponses[ i ] == main.TRUE:
3829 # All is well
3830 pass
3831 elif addResponses[ i ] == main.FALSE:
3832 # Already in set, probably fine
3833 pass
3834 elif addResponses[ i ] == main.ERROR:
3835 # Error in execution
3836 addAllResults = main.FALSE
3837 else:
3838 # unexpected result
3839 addAllResults = main.FALSE
3840 if addAllResults != main.TRUE:
3841 main.log.error( "Error executing set addAll" )
3842
3843 # Check if set is still correct
3844 size = len( onosSet )
3845 getResponses = []
3846 threads = []
3847 for i in range( numControllers ):
3848 t = main.Thread( target=CLIs[i].setTestGet,
3849 name="setTestGet-" + str( i ),
3850 args=[ onosSetName ] )
3851 threads.append( t )
3852 t.start()
3853 for t in threads:
3854 t.join()
3855 getResponses.append( t.result )
3856 getResults = main.TRUE
3857 for i in range( numControllers ):
3858 if isinstance( getResponses[ i ], list):
3859 current = set( getResponses[ i ] )
3860 if len( current ) == len( getResponses[ i ] ):
3861 # no repeats
3862 if onosSet != current:
3863 main.log.error( "ONOS" + str( i + 1 ) +
3864 " has incorrect view" +
3865 " of set " + onosSetName + ":\n" +
3866 str( getResponses[ i ] ) )
3867 main.log.debug( "Expected: " + str( onosSet ) )
3868 main.log.debug( "Actual: " + str( current ) )
3869 getResults = main.FALSE
3870 else:
3871 # error, set is not a set
3872 main.log.error( "ONOS" + str( i + 1 ) +
3873 " has repeat elements in" +
3874 " set " + onosSetName + ":\n" +
3875 str( getResponses[ i ] ) )
3876 getResults = main.FALSE
3877 elif getResponses[ i ] == main.ERROR:
3878 getResults = main.FALSE
3879 sizeResponses = []
3880 threads = []
3881 for i in range( numControllers ):
3882 t = main.Thread( target=CLIs[i].setTestSize,
3883 name="setTestSize-" + str( i ),
3884 args=[ onosSetName ] )
3885 threads.append( t )
3886 t.start()
3887 for t in threads:
3888 t.join()
3889 sizeResponses.append( t.result )
3890 sizeResults = main.TRUE
3891 for i in range( numControllers ):
3892 if size != sizeResponses[ i ]:
3893 sizeResults = main.FALSE
3894 main.log.error( "ONOS" + str( i + 1 ) +
3895 " expected a size of " + str( size ) +
3896 " for set " + onosSetName +
3897 " but got " + str( sizeResponses[ i ] ) )
3898 addAllResults = addAllResults and getResults and sizeResults
3899 utilities.assert_equals( expect=main.TRUE,
3900 actual=addAllResults,
3901 onpass="Set addAll correct",
3902 onfail="Set addAll was incorrect" )
3903
3904 main.step( "Distributed Set retain()" )
3905 onosSet.intersection_update( retainValue.split() )
3906 retainResponses = []
3907 threads = []
3908 for i in range( numControllers ):
3909 t = main.Thread( target=CLIs[i].setTestRemove,
3910 name="setTestRetain-" + str( i ),
3911 args=[ onosSetName, retainValue ],
3912 kwargs={ "retain": True } )
3913 threads.append( t )
3914 t.start()
3915 for t in threads:
3916 t.join()
3917 retainResponses.append( t.result )
3918
3919 # main.TRUE = successfully changed the set
3920 # main.FALSE = action resulted in no change in set
3921 # main.ERROR - Some error in executing the function
3922 retainResults = main.TRUE
3923 for i in range( numControllers ):
3924 if retainResponses[ i ] == main.TRUE:
3925 # All is well
3926 pass
3927 elif retainResponses[ i ] == main.FALSE:
3928 # Already in set, probably fine
3929 pass
3930 elif retainResponses[ i ] == main.ERROR:
3931 # Error in execution
3932 retainResults = main.FALSE
3933 else:
3934 # unexpected result
3935 retainResults = main.FALSE
3936 if retainResults != main.TRUE:
3937 main.log.error( "Error executing set retain" )
3938
3939 # Check if set is still correct
3940 size = len( onosSet )
3941 getResponses = []
3942 threads = []
3943 for i in range( numControllers ):
3944 t = main.Thread( target=CLIs[i].setTestGet,
3945 name="setTestGet-" + str( i ),
3946 args=[ onosSetName ] )
3947 threads.append( t )
3948 t.start()
3949 for t in threads:
3950 t.join()
3951 getResponses.append( t.result )
3952 getResults = main.TRUE
3953 for i in range( numControllers ):
3954 if isinstance( getResponses[ i ], list):
3955 current = set( getResponses[ i ] )
3956 if len( current ) == len( getResponses[ i ] ):
3957 # no repeats
3958 if onosSet != current:
3959 main.log.error( "ONOS" + str( i + 1 ) +
3960 " has incorrect view" +
3961 " of set " + onosSetName + ":\n" +
3962 str( getResponses[ i ] ) )
3963 main.log.debug( "Expected: " + str( onosSet ) )
3964 main.log.debug( "Actual: " + str( current ) )
3965 getResults = main.FALSE
3966 else:
3967 # error, set is not a set
3968 main.log.error( "ONOS" + str( i + 1 ) +
3969 " has repeat elements in" +
3970 " set " + onosSetName + ":\n" +
3971 str( getResponses[ i ] ) )
3972 getResults = main.FALSE
3973 elif getResponses[ i ] == main.ERROR:
3974 getResults = main.FALSE
3975 sizeResponses = []
3976 threads = []
3977 for i in range( numControllers ):
3978 t = main.Thread( target=CLIs[i].setTestSize,
3979 name="setTestSize-" + str( i ),
3980 args=[ onosSetName ] )
3981 threads.append( t )
3982 t.start()
3983 for t in threads:
3984 t.join()
3985 sizeResponses.append( t.result )
3986 sizeResults = main.TRUE
3987 for i in range( numControllers ):
3988 if size != sizeResponses[ i ]:
3989 sizeResults = main.FALSE
3990 main.log.error( "ONOS" + str( i + 1 ) +
3991 " expected a size of " +
3992 str( size ) + " for set " + onosSetName +
3993 " but got " + str( sizeResponses[ i ] ) )
3994 retainResults = retainResults and getResults and sizeResults
3995 utilities.assert_equals( expect=main.TRUE,
3996 actual=retainResults,
3997 onpass="Set retain correct",
3998 onfail="Set retain was incorrect" )
3999