blob: 306e5478959b062b807ee386f1ec2d1ed8836ba8 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hallb1290e82014-11-18 16:17:48 -05002Description: This test is to determine if the HA test setup is
3 working correctly. There are no failures so this test should
4 have a 100% pass rate
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
Jon Hallc9eabec2015-06-10 14:33:14 -07008CASE2: Assign devices to controllers
9CASE21: Assign mastership to controllers
Jon Hallb1290e82014-11-18 16:17:48 -050010CASE3: Assign intents
11CASE4: Ping across added host intents
12CASE5: Reading state of ONOS
13CASE6: The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall368769f2014-11-19 15:43:35 -080014CASE7: Check state after control plane failure
Jon Hallb1290e82014-11-18 16:17:48 -050015CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080021CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070023CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080025"""
Jon Hall8f89dda2015-01-22 16:03:33 -080026
27
Jon Hallb1290e82014-11-18 16:17:48 -050028class HATestSanity:
29
Jon Hall6aec96b2015-01-19 14:49:31 -080030 def __init__( self ):
Jon Hallb1290e82014-11-18 16:17:48 -050031 self.default = ''
32
Jon Hall6aec96b2015-01-19 14:49:31 -080033 def CASE1( self, main ):
34 """
Jon Hallb1290e82014-11-18 16:17:48 -050035 CASE1 is to compile ONOS and push it to the test machines
36
37 Startup sequence:
Jon Hallb1290e82014-11-18 16:17:48 -050038 cell <name>
39 onos-verify-cell
40 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080041 onos-uninstall
42 start mininet
43 git pull
44 mvn clean install
45 onos-package
Jon Hallb1290e82014-11-18 16:17:48 -050046 onos-install -f
47 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080048 start cli sessions
49 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080050 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070051 main.log.info( "ONOS HA Sanity test - initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080052 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 Hallb1290e82014-11-18 16:17:48 -050057
Jon Hall65844a32015-03-09 19:09:37 -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 Hall8f89dda2015-01-22 16:03:33 -080074 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall5cfd23c2015-03-19 11:40:57 -070075
Jon Hall65844a32015-03-09 19:09:37 -070076 # FIXME: just get controller port from params?
77 # TODO: do we really need all these?
78 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
79 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
80 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
81 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
82 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
83 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
84 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
85
86 global CLIs
87 CLIs = []
88 global nodes
89 nodes = []
90 for i in range( 1, numControllers + 1 ):
91 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
92 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -050093
Jon Hall6aec96b2015-01-19 14:49:31 -080094 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080095 cellResult = main.ONOSbench.setCell( cellName )
96 verifyResult = main.ONOSbench.verifyCell()
Jon Hall368769f2014-11-19 15:43:35 -080097
Jon Hall6aec96b2015-01-19 14:49:31 -080098 # FIXME:this is short term fix
Jon Hall40d2cbd2015-06-03 16:24:29 -070099 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall65844a32015-03-09 19:09:37 -0700101
Jon Hall40d2cbd2015-06-03 16:24:29 -0700102 main.log.info( "Uninstalling ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -0700103 for node in nodes:
104 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hallb1290e82014-11-18 16:17:48 -0500105
Jon Hall390696c2015-05-05 17:13:41 -0700106 # Make sure ONOS is DEAD
Jon Hall40d2cbd2015-06-03 16:24:29 -0700107 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700108 killResults = main.TRUE
109 for node in nodes:
110 killed = main.ONOSbench.onosKill( node.ip_address )
111 killResults = killResults and killed
112
Jon Hall8f89dda2015-01-22 16:03:33 -0800113 cleanInstallResult = main.TRUE
114 gitPullResult = main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -0500115
Jon Hall97f31752015-02-04 12:01:04 -0800116 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700117 mnResult = main.Mininet1.startNet( )
118 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
119 onpass="Mininet Started",
120 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800121
Jon Hallfeff3082015-05-19 10:23:26 -0700122 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800123 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800124 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800125 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700126 # values of 1 or 3 are good
127 utilities.assert_lesser( expect=0, actual=gitPullResult,
128 onpass="Git pull successful",
129 onfail="Git pull failed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700131
132 main.step( "Using mvn clean install" )
133 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700134 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700135 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700136 else:
137 main.log.warn( "Did not pull new code so skipping mvn " +
138 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700139 utilities.assert_equals( expect=main.TRUE,
140 actual=cleanInstallResult,
141 onpass="MCI successful",
142 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700143 # GRAPHS
144 # NOTE: important params here:
145 # job = name of Jenkins job
146 # Plot Name = Plot-HA, only can be used if multiple plots
147 # index = The number of the graph under plot name
148 job = "HASanity"
149 plotName = "Plot-HA"
150 graphs = '<ac:structured-macro ac:name="html">\n'
151 graphs += '<ac:plain-text-body><![CDATA[\n'
152 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
153 '/plot/' + plotName + '/getPlot?index=0' +\
154 '&width=500&height=300"' +\
155 'noborder="0" width="500" height="300" scrolling="yes" ' +\
156 'seamless="seamless"></iframe>\n'
157 graphs += ']]></ac:plain-text-body>\n'
158 graphs += '</ac:structured-macro>\n'
159 main.log.wiki(graphs)
Jon Hallb1290e82014-11-18 16:17:48 -0500160
Jon Hall6aec96b2015-01-19 14:49:31 -0800161 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800162 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700163 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
164 onpass="ONOS package successful",
165 onfail="ONOS package failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500166
Jon Hall6aec96b2015-01-19 14:49:31 -0800167 main.step( "Installing ONOS package" )
Jon Hall65844a32015-03-09 19:09:37 -0700168 onosInstallResult = main.TRUE
169 for node in nodes:
170 tmpResult = main.ONOSbench.onosInstall( options="-f",
171 node=node.ip_address )
172 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700173 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
174 onpass="ONOS install successful",
175 onfail="ONOS install failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500176
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800178 for i in range( 2 ):
Jon Hall65844a32015-03-09 19:09:37 -0700179 onosIsupResult = main.TRUE
180 for node in nodes:
181 started = main.ONOSbench.isup( node.ip_address )
182 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700183 main.log.error( node.name + " didn't start!" )
Jon Hall65844a32015-03-09 19:09:37 -0700184 main.ONOSbench.onosStop( node.ip_address )
185 main.ONOSbench.onosStart( node.ip_address )
186 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800187 if onosIsupResult == main.TRUE:
Jon Hallffb386d2014-11-21 13:43:38 -0800188 break
Jon Hall390696c2015-05-05 17:13:41 -0700189 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
190 onpass="ONOS startup successful",
191 onfail="ONOS startup failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500192
Jon Hall65844a32015-03-09 19:09:37 -0700193 main.log.step( "Starting ONOS CLI sessions" )
194 cliResults = main.TRUE
195 threads = []
196 for i in range( numControllers ):
197 t = main.Thread( target=CLIs[i].startOnosCli,
Jon Hall65844a32015-03-09 19:09:37 -0700198 name="startOnosCli-" + str( i ),
199 args=[nodes[i].ip_address] )
200 threads.append( t )
201 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700202
203 for t in threads:
204 t.join()
205 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700206 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
207 onpass="ONOS cli startup successful",
208 onfail="ONOS cli startup failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500209
Jon Hall40d2cbd2015-06-03 16:24:29 -0700210 if main.params[ 'tcpdump' ].lower() == "true":
211 main.step( "Start Packet Capture MN" )
212 main.Mininet2.startTcpdump(
213 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
214 + "-MN.pcap",
215 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
216 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hallb1290e82014-11-18 16:17:48 -0500217
Jon Hall390696c2015-05-05 17:13:41 -0700218 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700219 appCheck = main.TRUE
220 threads = []
221 for i in range( numControllers ):
222 t = main.Thread( target=CLIs[i].appToIDCheck,
223 name="appToIDCheck-" + str( i ),
224 args=[] )
225 threads.append( t )
226 t.start()
227
228 for t in threads:
229 t.join()
230 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700231 if appCheck != main.TRUE:
232 main.log.warn( CLIs[0].apps() )
233 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700234 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
235 onpass="App Ids seem to be correct",
236 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700237
Jon Hallfeff3082015-05-19 10:23:26 -0700238 if cliResults == main.FALSE:
239 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hallffb386d2014-11-21 13:43:38 -0800240 main.cleanup()
241 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -0500242
Jon Hall6aec96b2015-01-19 14:49:31 -0800243 def CASE2( self, main ):
244 """
Jon Hallc9eabec2015-06-10 14:33:14 -0700245 Assign devices to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800246 """
Jon Hallb1290e82014-11-18 16:17:48 -0500247 import re
Jon Hall390696c2015-05-05 17:13:41 -0700248 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700249 assert numControllers, "numControllers not defined"
250 assert main, "main not defined"
251 assert utilities.assert_equals, "utilities.assert_equals not defined"
252 assert CLIs, "CLIs not defined"
253 assert nodes, "nodes not defined"
254 assert ONOS1Port, "ONOS1Port not defined"
255 assert ONOS2Port, "ONOS2Port not defined"
256 assert ONOS3Port, "ONOS3Port not defined"
257 assert ONOS4Port, "ONOS4Port not defined"
258 assert ONOS5Port, "ONOS5Port not defined"
259 assert ONOS6Port, "ONOS6Port not defined"
260 assert ONOS7Port, "ONOS7Port not defined"
Jon Hallb1290e82014-11-18 16:17:48 -0500261
Jon Hallc9eabec2015-06-10 14:33:14 -0700262 main.case( "Assigning devices to controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700263 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
264 "and check that an ONOS node becomes the " +\
Jon Hallc9eabec2015-06-10 14:33:14 -0700265 "master of the device."
Jon Hall6aec96b2015-01-19 14:49:31 -0800266 main.step( "Assign switches to controllers" )
Jon Hallb1290e82014-11-18 16:17:48 -0500267
Jon Hall65844a32015-03-09 19:09:37 -0700268 # TODO: rewrite this function to take lists of ips and ports?
269 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800270 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800271 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800273 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -0700274 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
275 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
276 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
277 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
278 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
279 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
280 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hallb1290e82014-11-18 16:17:48 -0500281
Jon Hall8f89dda2015-01-22 16:03:33 -0800282 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800283 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800284 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800285 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800286 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800287 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800288 main.log.info( repr( response ) )
Jon Hall65844a32015-03-09 19:09:37 -0700289 for node in nodes:
290 if re.search( "tcp:" + node.ip_address, response ):
291 mastershipCheck = mastershipCheck and main.TRUE
292 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700293 main.log.error( "Error, node " + node.ip_address + " is " +
294 "not in the list of controllers s" +
295 str( i ) + " is connecting to." )
Jon Hall65844a32015-03-09 19:09:37 -0700296 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800297 utilities.assert_equals(
298 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800299 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800300 onpass="Switch mastership assigned correctly",
301 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700302
Jon Hallc9eabec2015-06-10 14:33:14 -0700303 def CASE21( self, main ):
304 """
305 Assign mastership to controllers
306 """
307 import re
308 import time
309 assert numControllers, "numControllers not defined"
310 assert main, "main not defined"
311 assert utilities.assert_equals, "utilities.assert_equals not defined"
312 assert CLIs, "CLIs not defined"
313 assert nodes, "nodes not defined"
314 assert ONOS1Port, "ONOS1Port not defined"
315 assert ONOS2Port, "ONOS2Port not defined"
316 assert ONOS3Port, "ONOS3Port not defined"
317 assert ONOS4Port, "ONOS4Port not defined"
318 assert ONOS5Port, "ONOS5Port not defined"
319 assert ONOS6Port, "ONOS6Port not defined"
320 assert ONOS7Port, "ONOS7Port not defined"
321
322 main.case( "Assigning Controller roles for switches" )
323 main.caseExplaination = "Check that ONOS is connected to each " +\
324 "device. Then manually assign" +\
325 " mastership to specific ONOS nodes using" +\
326 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700327 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800328 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800329 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700330
331 ipList = [ ]
332 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800333 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700334 for i in range( 1, 29 ): # switches 1 through 28
335 # set up correct variables:
336 if i == 1:
337 ip = nodes[ 0 ].ip_address # ONOS1
338 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
339 elif i == 2:
340 ip = nodes[ 1 ].ip_address # ONOS2
341 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
342 elif i == 3:
343 ip = nodes[ 1 ].ip_address # ONOS2
344 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
345 elif i == 4:
346 ip = nodes[ 3 ].ip_address # ONOS4
347 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
348 elif i == 5:
349 ip = nodes[ 2 ].ip_address # ONOS3
350 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
351 elif i == 6:
352 ip = nodes[ 2 ].ip_address # ONOS3
353 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
354 elif i == 7:
355 ip = nodes[ 5 ].ip_address # ONOS6
356 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
357 elif i >= 8 and i <= 17:
358 ip = nodes[ 4 ].ip_address # ONOS5
359 dpid = '3' + str( i ).zfill( 3 )
360 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
361 elif i >= 18 and i <= 27:
362 ip = nodes[ 6 ].ip_address # ONOS7
363 dpid = '6' + str( i ).zfill( 3 )
364 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
365 elif i == 28:
366 ip = nodes[ 0 ].ip_address # ONOS1
367 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
368 else:
369 main.log.error( "You didn't write an else statement for " +
370 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700371 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700372 # Assign switch
373 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
374 # TODO: make this controller dynamic
375 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
376 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700377 ipList.append( ip )
378 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800379 except ( AttributeError, AssertionError ):
380 main.log.exception( "Something is wrong with ONOS device view" )
381 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800382 utilities.assert_equals(
383 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800384 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800386 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800387
Jon Hall390696c2015-05-05 17:13:41 -0700388 main.step( "Check mastership was correctly assigned" )
389 roleCheck = main.TRUE
390 # NOTE: This is due to the fact that device mastership change is not
391 # atomic and is actually a multi step process
392 time.sleep( 5 )
393 for i in range( len( ipList ) ):
394 ip = ipList[i]
395 deviceId = deviceList[i]
396 # Check assignment
397 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
398 if ip in master:
399 roleCheck = roleCheck and main.TRUE
400 else:
401 roleCheck = roleCheck and main.FALSE
402 main.log.error( "Error, controller " + ip + " is not" +
403 " master " + "of device " +
404 str( deviceId ) + ". Master is " +
405 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800406 utilities.assert_equals(
407 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800408 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800409 onpass="Switches were successfully reassigned to designated " +
410 "controller",
411 onfail="Switches were not successfully reassigned" )
Jon Hallb1290e82014-11-18 16:17:48 -0500412
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 def CASE3( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500414 """
415 Assign intents
Jon Hallb1290e82014-11-18 16:17:48 -0500416 """
417 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800418 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700419 assert numControllers, "numControllers not defined"
420 assert main, "main not defined"
421 assert utilities.assert_equals, "utilities.assert_equals not defined"
422 assert CLIs, "CLIs not defined"
423 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800424 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700425 main.caseExplaination = "Discover hosts by using pingall then " +\
426 "assign predetermined host-to-host intents." +\
427 " After installation, check that the intent" +\
428 " is distributed to all nodes and the state" +\
429 " is INSTALLED"
Jon Hallb1290e82014-11-18 16:17:48 -0500430
Jon Hall6aec96b2015-01-19 14:49:31 -0800431 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700432 main.step( "Install reactive forwarding app" )
433 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
434 utilities.assert_equals( expect=main.TRUE, actual=installResults,
435 onpass="Install fwd successful",
436 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700437
Jon Hallfeff3082015-05-19 10:23:26 -0700438 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700439 appCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700440 threads = []
441 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700442 t = main.Thread( target=CLIs[i].appToIDCheck,
443 name="appToIDCheck-" + str( i ),
444 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700445 threads.append( t )
446 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700447
448 for t in threads:
449 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700450 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700451 if appCheck != main.TRUE:
452 main.log.warn( CLIs[0].apps() )
453 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700454 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
455 onpass="App Ids seem to be correct",
456 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800457
Jon Hallfeff3082015-05-19 10:23:26 -0700458 main.step( "Discovering Hosts( Via pingall for now )" )
459 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800460 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800461 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700462 for i in range(2): # Retry if pingall fails first time
463 time1 = time.time()
464 pingResult = main.Mininet1.pingall()
465 utilities.assert_equals(
466 expect=main.TRUE,
467 actual=pingResult,
468 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700469 onfail="Reactive Pingall failed, " +
470 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700471 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700472 main.log.info( "Time for pingall: %2f seconds" %
473 ( time2 - time1 ) )
474 # timeout for fwd flows
475 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800476 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700477 main.step( "Uninstall reactive forwarding app" )
478 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
479 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
480 onpass="Uninstall fwd successful",
481 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700482 '''
483 main.Mininet1.handle.sendline( "py [ h.cmd( \"arping -c 1 10.1.1.1 \" ) for h in net.hosts ] ")
484 import time
485 time.sleep(60)
486 '''
487
488 main.step( "Check app ids" )
Jon Hall65844a32015-03-09 19:09:37 -0700489 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700490 appCheck2 = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700491 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700492 t = main.Thread( target=CLIs[i].appToIDCheck,
493 name="appToIDCheck-" + str( i ),
494 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700495 threads.append( t )
496 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700497
498 for t in threads:
499 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700500 appCheck2 = appCheck2 and t.result
501 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700502 main.log.warn( CLIs[0].apps() )
503 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700504 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700505 onpass="App Ids seem to be correct",
506 onfail="Something is wrong with app Ids" )
Jon Hallb1290e82014-11-18 16:17:48 -0500507
Jon Hallfeff3082015-05-19 10:23:26 -0700508 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800509 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800510 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800511 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800512 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800513 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800514 for i in range( 8, 18 ):
515 main.log.info( "Adding host intent between h" + str( i ) +
516 " and h" + str( i + 10 ) )
517 host1 = "00:00:00:00:00:" + \
518 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
519 host2 = "00:00:00:00:00:" + \
520 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800521 # NOTE: getHost can return None
Jon Hall5cfd23c2015-03-19 11:40:57 -0700522 host1Dict = main.ONOScli1.getHost( host1 )
523 host2Dict = main.ONOScli1.getHost( host2 )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800524 host1Id = None
525 host2Id = None
526 if host1Dict and host2Dict:
527 host1Id = host1Dict.get( 'id', None )
528 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800529 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700530 nodeNum = ( i % 7 )
531 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800532 if tmpId:
533 main.log.info( "Added intent with id: " + tmpId )
534 intentIds.append( tmpId )
535 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700536 main.log.error( "addHostIntent returned: " +
537 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800538 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700539 main.log.error( "Error, getHost() failed for h" + str( i ) +
540 " and/or h" + str( i + 10 ) )
541 hosts = CLIs[ 0 ].hosts()
542 main.log.warn( "Hosts output: " )
543 try:
544 main.log.warn( json.dumps( json.loads( hosts ),
545 sort_keys=True,
546 indent=4,
547 separators=( ',', ': ' ) ) )
548 except ( ValueError, TypeError ):
549 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800550 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700551 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
552 onpass="Found a host id for each host",
553 onfail="Error looking up host ids" )
554
Jon Hall5cfd23c2015-03-19 11:40:57 -0700555 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800556 onosIds = main.ONOScli1.getAllIntentsId()
557 main.log.info( "Submitted intents: " + str( intentIds ) )
558 main.log.info( "Intents in ONOS: " + str( onosIds ) )
559 for intent in intentIds:
560 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700561 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800562 else:
563 intentAddResult = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700564 if intentAddResult:
565 intentStop = time.time()
566 else:
567 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800568 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800569 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800570 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -0700571 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800572 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
573 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700574 try:
575 for intent in json.loads( intents ):
576 state = intent.get( 'state', None )
577 if "INSTALLED" not in state:
578 installedCheck = False
579 intentId = intent.get( 'id', None )
580 intentStates.append( ( intentId, state ) )
581 except ( ValueError, TypeError ):
582 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800583 # add submitted intents not in the store
584 tmplist = [ i for i, s in intentStates ]
585 missingIntents = False
586 for i in intentIds:
587 if i not in tmplist:
588 intentStates.append( ( i, " - " ) )
589 missingIntents = True
590 intentStates.sort()
591 for i, s in intentStates:
592 count += 1
593 main.log.info( "%-6s%-15s%-15s" %
594 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700595 leaders = main.ONOScli1.leaders()
596 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700597 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700598 if leaders:
599 parsedLeaders = json.loads( leaders )
600 main.log.warn( json.dumps( parsedLeaders,
601 sort_keys=True,
602 indent=4,
603 separators=( ',', ': ' ) ) )
604 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700605 topics = []
606 for i in range( 14 ):
607 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700608 main.log.debug( topics )
609 ONOStopics = [ j['topic'] for j in parsedLeaders ]
610 for topic in topics:
611 if topic not in ONOStopics:
612 main.log.error( "Error: " + topic +
613 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700614 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700615 else:
616 main.log.error( "leaders() returned None" )
617 except ( ValueError, TypeError ):
618 main.log.exception( "Error parsing leaders" )
619 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700620 # Check all nodes
621 if missing:
622 for node in CLIs:
623 response = node.leaders( jsonFormat=False)
624 main.log.warn( str( node.name ) + " leaders output: \n" +
625 str( response ) )
626
Jon Hall5cfd23c2015-03-19 11:40:57 -0700627 partitions = main.ONOScli1.partitions()
628 try:
629 if partitions :
630 parsedPartitions = json.loads( partitions )
631 main.log.warn( json.dumps( parsedPartitions,
632 sort_keys=True,
633 indent=4,
634 separators=( ',', ': ' ) ) )
635 # TODO check for a leader in all paritions
636 # TODO check for consistency among nodes
637 else:
638 main.log.error( "partitions() returned None" )
639 except ( ValueError, TypeError ):
640 main.log.exception( "Error parsing partitions" )
641 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800642 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700643 try:
644 if pendingMap :
645 parsedPending = json.loads( pendingMap )
646 main.log.warn( json.dumps( parsedPending,
647 sort_keys=True,
648 indent=4,
649 separators=( ',', ': ' ) ) )
650 # TODO check something here?
651 else:
652 main.log.error( "pendingMap() returned None" )
653 except ( ValueError, TypeError ):
654 main.log.exception( "Error parsing pending map" )
655 main.log.error( repr( pendingMap ) )
656
Jon Hallfeff3082015-05-19 10:23:26 -0700657 intentAddResult = bool( intentAddResult and not missingIntents and
658 installedCheck )
659 if not intentAddResult:
660 main.log.error( "Error in pushing host intents to ONOS" )
661
Jon Hall390696c2015-05-05 17:13:41 -0700662 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700663 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700664 correct = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700665 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700666 for cli in CLIs:
667 onosIds = []
668 ids = cli.getAllIntentsId()
669 onosIds.append( ids )
670 main.log.debug( "Intents in " + cli.name + ": " +
671 str( sorted( onosIds ) ) )
672 if sorted( ids ) != sorted( intentIds ):
Jon Hall40d2cbd2015-06-03 16:24:29 -0700673 main.log.debug( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700674 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700675 break
676 else:
677 intents = json.loads( cli.intents() )
678 for intent in intents:
679 if intent[ 'state' ] != "INSTALLED":
680 main.log.warn( "Intent " + intent[ 'id' ] +
681 " is " + intent[ 'state' ] )
682 correct = False
683 break
Jon Hall390696c2015-05-05 17:13:41 -0700684 if correct:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700685 break
Jon Hallc9eabec2015-06-10 14:33:14 -0700686 else:
687 time.sleep(1)
Jon Hall5cfd23c2015-03-19 11:40:57 -0700688 if not intentStop:
689 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700690 global gossipTime
Jon Hall5cfd23c2015-03-19 11:40:57 -0700691 gossipTime = intentStop - intentStart
692 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700693 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700694 # FIXME: make this time configurable/calculate based off of number of
695 # nodes and gossip rounds
Jon Hall5cfd23c2015-03-19 11:40:57 -0700696 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700697 expect=40, actual=gossipTime,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700698 onpass="ECM anti-entropy for intents worked within " +
699 "expected time",
700 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700701 if gossipTime <= 40:
Jon Halla9d26da2015-03-30 16:45:32 -0700702 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800703
Jon Hall63604932015-02-26 17:09:50 -0800704 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800705 import time
Jon Hall63604932015-02-26 17:09:50 -0800706 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800707 main.log.info( "Sleeping 60 seconds to see if intents are found" )
708 time.sleep( 60 )
709 onosIds = main.ONOScli1.getAllIntentsId()
710 main.log.info( "Submitted intents: " + str( intentIds ) )
711 main.log.info( "Intents in ONOS: " + str( onosIds ) )
712 # Print the intent states
713 intents = main.ONOScli1.intents()
714 intentStates = []
715 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
716 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700717 try:
718 for intent in json.loads( intents ):
719 # Iter through intents of a node
720 state = intent.get( 'state', None )
721 if "INSTALLED" not in state:
722 installedCheck = False
723 intentId = intent.get( 'id', None )
724 intentStates.append( ( intentId, state ) )
725 except ( ValueError, TypeError ):
726 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800727 # add submitted intents not in the store
728 tmplist = [ i for i, s in intentStates ]
729 for i in intentIds:
730 if i not in tmplist:
731 intentStates.append( ( i, " - " ) )
732 intentStates.sort()
733 for i, s in intentStates:
734 count += 1
735 main.log.info( "%-6s%-15s%-15s" %
736 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700737 leaders = main.ONOScli1.leaders()
738 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700739 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700740 if leaders:
741 parsedLeaders = json.loads( leaders )
742 main.log.warn( json.dumps( parsedLeaders,
743 sort_keys=True,
744 indent=4,
745 separators=( ',', ': ' ) ) )
746 # check for all intent partitions
747 # check for election
748 topics = []
749 for i in range( 14 ):
750 topics.append( "intent-partition-" + str( i ) )
751 # FIXME: this should only be after we start the app
752 topics.append( "org.onosproject.election" )
753 main.log.debug( topics )
754 ONOStopics = [ j['topic'] for j in parsedLeaders ]
755 for topic in topics:
756 if topic not in ONOStopics:
757 main.log.error( "Error: " + topic +
758 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700759 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700760 else:
761 main.log.error( "leaders() returned None" )
762 except ( ValueError, TypeError ):
763 main.log.exception( "Error parsing leaders" )
764 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700765 # Check all nodes
766 if missing:
767 for node in CLIs:
768 response = node.leaders( jsonFormat=False)
769 main.log.warn( str( node.name ) + " leaders output: \n" +
770 str( response ) )
771
Jon Hall5cfd23c2015-03-19 11:40:57 -0700772 partitions = main.ONOScli1.partitions()
773 try:
774 if partitions :
775 parsedPartitions = json.loads( partitions )
776 main.log.warn( json.dumps( parsedPartitions,
777 sort_keys=True,
778 indent=4,
779 separators=( ',', ': ' ) ) )
780 # TODO check for a leader in all paritions
781 # TODO check for consistency among nodes
782 else:
783 main.log.error( "partitions() returned None" )
784 except ( ValueError, TypeError ):
785 main.log.exception( "Error parsing partitions" )
786 main.log.error( repr( partitions ) )
787 pendingMap = main.ONOScli1.pendingMap()
788 try:
789 if pendingMap :
790 parsedPending = json.loads( pendingMap )
791 main.log.warn( json.dumps( parsedPending,
792 sort_keys=True,
793 indent=4,
794 separators=( ',', ': ' ) ) )
795 # TODO check something here?
796 else:
797 main.log.error( "pendingMap() returned None" )
798 except ( ValueError, TypeError ):
799 main.log.exception( "Error parsing pending map" )
800 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500801
Jon Hall6aec96b2015-01-19 14:49:31 -0800802 def CASE4( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500803 """
804 Ping across added host intents
805 """
Jon Hall58c76b72015-02-23 11:09:24 -0800806 import json
Jon Hall65844a32015-03-09 19:09:37 -0700807 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700808 assert numControllers, "numControllers not defined"
809 assert main, "main not defined"
810 assert utilities.assert_equals, "utilities.assert_equals not defined"
811 assert CLIs, "CLIs not defined"
812 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700813 main.case( "Verify connectivity by sendind traffic across Intents" )
814 main.caseExplaination = "Ping across added host intents to check " +\
815 "functionality and check the state of " +\
816 "the intent"
817 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800818 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800819 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800820 ping = main.Mininet1.pingHost( src="h" + str( i ),
821 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800822 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800823 if ping == main.FALSE:
824 main.log.warn( "Ping failed between h" + str( i ) +
825 " and h" + str( i + 10 ) )
826 elif ping == main.TRUE:
827 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800828 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800829 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700830 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800831 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800832 # TODO: pretty print
Jon Hall65844a32015-03-09 19:09:37 -0700833 main.log.warn( "ONOS1 intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700834 try:
835 tmpIntents = main.ONOScli1.intents()
836 main.log.warn( json.dumps( json.loads( tmpIntents ),
837 sort_keys=True,
838 indent=4,
839 separators=( ',', ': ' ) ) )
840 except ( ValueError, TypeError ):
841 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800842 utilities.assert_equals(
843 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800844 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800845 onpass="Intents have been installed correctly and pings work",
846 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallb1290e82014-11-18 16:17:48 -0500847
Jon Hallfeff3082015-05-19 10:23:26 -0700848 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700849 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700850 loopCount = 0
851 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700852 installedCheck = True
853 # Print the intent states
854 intents = main.ONOScli1.intents()
855 intentStates = []
856 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700857 # Iter through intents of a node
858 try:
859 for intent in json.loads( intents ):
860 state = intent.get( 'state', None )
861 if "INSTALLED" not in state:
862 installedCheck = False
863 intentId = intent.get( 'id', None )
864 intentStates.append( ( intentId, state ) )
865 except ( ValueError, TypeError ):
866 main.log.exception( "Error parsing intents." )
867 # Print states
868 intentStates.sort()
869 for i, s in intentStates:
870 count += 1
871 main.log.info( "%-6s%-15s%-15s" %
872 ( str( count ), str( i ), str( s ) ) )
873 if not installedCheck:
874 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700875 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700876 utilities.assert_equals( expect=True, actual=installedCheck,
877 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700878 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700879 "INSTALLED state" )
880
881 main.step( "Check leadership of topics" )
882 leaders = main.ONOScli1.leaders()
883 topicCheck = main.TRUE
884 try:
885 if leaders:
886 parsedLeaders = json.loads( leaders )
887 main.log.warn( json.dumps( parsedLeaders,
888 sort_keys=True,
889 indent=4,
890 separators=( ',', ': ' ) ) )
891 # check for all intent partitions
892 # check for election
893 # TODO: Look at Devices as topics now that it uses this system
894 topics = []
895 for i in range( 14 ):
896 topics.append( "intent-partition-" + str( i ) )
897 # FIXME: this should only be after we start the app
898 # FIXME: topics.append( "org.onosproject.election" )
899 # Print leaders output
900 main.log.debug( topics )
901 ONOStopics = [ j['topic'] for j in parsedLeaders ]
902 for topic in topics:
903 if topic not in ONOStopics:
904 main.log.error( "Error: " + topic +
905 " not in leaders" )
906 topicCheck = main.FALSE
907 else:
908 main.log.error( "leaders() returned None" )
909 topicCheck = main.FALSE
910 except ( ValueError, TypeError ):
911 topicCheck = main.FALSE
912 main.log.exception( "Error parsing leaders" )
913 main.log.error( repr( leaders ) )
914 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700915 # Check all nodes
916 if topicCheck:
917 for node in CLIs:
918 response = node.leaders( jsonFormat=False)
919 main.log.warn( str( node.name ) + " leaders output: \n" +
920 str( response ) )
921
Jon Hallfeff3082015-05-19 10:23:26 -0700922 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
923 onpass="intent Partitions is in leaders",
924 onfail="Some topics were lost " )
925 # Print partitions
926 partitions = main.ONOScli1.partitions()
927 try:
928 if partitions :
929 parsedPartitions = json.loads( partitions )
930 main.log.warn( json.dumps( parsedPartitions,
931 sort_keys=True,
932 indent=4,
933 separators=( ',', ': ' ) ) )
934 # TODO check for a leader in all paritions
935 # TODO check for consistency among nodes
936 else:
937 main.log.error( "partitions() returned None" )
938 except ( ValueError, TypeError ):
939 main.log.exception( "Error parsing partitions" )
940 main.log.error( repr( partitions ) )
941 # Print Pending Map
942 pendingMap = main.ONOScli1.pendingMap()
943 try:
944 if pendingMap :
945 parsedPending = json.loads( pendingMap )
946 main.log.warn( json.dumps( parsedPending,
947 sort_keys=True,
948 indent=4,
949 separators=( ',', ': ' ) ) )
950 # TODO check something here?
951 else:
952 main.log.error( "pendingMap() returned None" )
953 except ( ValueError, TypeError ):
954 main.log.exception( "Error parsing pending map" )
955 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700956
Jon Hall63604932015-02-26 17:09:50 -0800957 if not installedCheck:
Jon Hall65844a32015-03-09 19:09:37 -0700958 main.log.info( "Waiting 60 seconds to see if the state of " +
959 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800960 time.sleep( 60 )
961 # Print the intent states
962 intents = main.ONOScli1.intents()
963 intentStates = []
964 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
965 count = 0
966 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700967 try:
968 for intent in json.loads( intents ):
969 state = intent.get( 'state', None )
970 if "INSTALLED" not in state:
971 installedCheck = False
972 intentId = intent.get( 'id', None )
973 intentStates.append( ( intentId, state ) )
974 except ( ValueError, TypeError ):
975 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800976 intentStates.sort()
977 for i, s in intentStates:
978 count += 1
979 main.log.info( "%-6s%-15s%-15s" %
980 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700981 leaders = main.ONOScli1.leaders()
982 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700983 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700984 if leaders:
985 parsedLeaders = json.loads( leaders )
986 main.log.warn( json.dumps( parsedLeaders,
987 sort_keys=True,
988 indent=4,
989 separators=( ',', ': ' ) ) )
990 # check for all intent partitions
991 # check for election
992 topics = []
993 for i in range( 14 ):
994 topics.append( "intent-partition-" + str( i ) )
995 # FIXME: this should only be after we start the app
996 topics.append( "org.onosproject.election" )
997 main.log.debug( topics )
998 ONOStopics = [ j['topic'] for j in parsedLeaders ]
999 for topic in topics:
1000 if topic not in ONOStopics:
1001 main.log.error( "Error: " + topic +
1002 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -07001003 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -07001004 else:
1005 main.log.error( "leaders() returned None" )
1006 except ( ValueError, TypeError ):
1007 main.log.exception( "Error parsing leaders" )
1008 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001009 if missing:
1010 for node in CLIs:
1011 response = node.leaders( jsonFormat=False)
1012 main.log.warn( str( node.name ) + " leaders output: \n" +
1013 str( response ) )
1014
Jon Hall5cfd23c2015-03-19 11:40:57 -07001015 partitions = main.ONOScli1.partitions()
1016 try:
1017 if partitions :
1018 parsedPartitions = json.loads( partitions )
1019 main.log.warn( json.dumps( parsedPartitions,
1020 sort_keys=True,
1021 indent=4,
1022 separators=( ',', ': ' ) ) )
1023 # TODO check for a leader in all paritions
1024 # TODO check for consistency among nodes
1025 else:
1026 main.log.error( "partitions() returned None" )
1027 except ( ValueError, TypeError ):
1028 main.log.exception( "Error parsing partitions" )
1029 main.log.error( repr( partitions ) )
1030 pendingMap = main.ONOScli1.pendingMap()
1031 try:
1032 if pendingMap :
1033 parsedPending = json.loads( pendingMap )
1034 main.log.warn( json.dumps( parsedPending,
1035 sort_keys=True,
1036 indent=4,
1037 separators=( ',', ': ' ) ) )
1038 # TODO check something here?
1039 else:
1040 main.log.error( "pendingMap() returned None" )
1041 except ( ValueError, TypeError ):
1042 main.log.exception( "Error parsing pending map" )
1043 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001044 # Print flowrules
1045 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001046 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001047 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001048 PingResult = main.TRUE
1049 for i in range( 8, 18 ):
1050 ping = main.Mininet1.pingHost( src="h" + str( i ),
1051 target="h" + str( i + 10 ) )
1052 PingResult = PingResult and ping
1053 if ping == main.FALSE:
1054 main.log.warn( "Ping failed between h" + str( i ) +
1055 " and h" + str( i + 10 ) )
1056 elif ping == main.TRUE:
1057 main.log.info( "Ping test passed!" )
1058 # Don't set PingResult or you'd override failures
1059 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001060 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001061 "Intents have not been installed correctly, pings failed." )
1062 # TODO: pretty print
1063 main.log.warn( "ONOS1 intents: " )
1064 try:
1065 tmpIntents = main.ONOScli1.intents()
1066 main.log.warn( json.dumps( json.loads( tmpIntents ),
1067 sort_keys=True,
1068 indent=4,
1069 separators=( ',', ': ' ) ) )
1070 except ( ValueError, TypeError ):
1071 main.log.warn( repr( tmpIntents ) )
1072 utilities.assert_equals(
1073 expect=main.TRUE,
1074 actual=PingResult,
1075 onpass="Intents have been installed correctly and pings work",
1076 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallfeff3082015-05-19 10:23:26 -07001077
Jon Hall6aec96b2015-01-19 14:49:31 -08001078 def CASE5( self, main ):
1079 """
Jon Hallb1290e82014-11-18 16:17:48 -05001080 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001081 """
Jon Hallb1290e82014-11-18 16:17:48 -05001082 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001083 import time
1084 assert numControllers, "numControllers not defined"
1085 assert main, "main not defined"
1086 assert utilities.assert_equals, "utilities.assert_equals not defined"
1087 assert CLIs, "CLIs not defined"
1088 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001089 # assumes that sts is already in you PYTHONPATH
1090 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001091
Jon Hall6aec96b2015-01-19 14:49:31 -08001092 main.case( "Setting up and gathering data for current state" )
1093 # The general idea for this test case is to pull the state of
1094 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -07001095 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -05001096
Jon Hall65844a32015-03-09 19:09:37 -07001097 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001098 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001099 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001100
Jon Hall6aec96b2015-01-19 14:49:31 -08001101 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001102 rolesNotNull = main.TRUE
1103 threads = []
1104 for i in range( numControllers ):
1105 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001106 name="rolesNotNull-" + str( i ),
1107 args=[] )
1108 threads.append( t )
1109 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001110
1111 for t in threads:
1112 t.join()
1113 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001114 utilities.assert_equals(
1115 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001116 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001117 onpass="Each device has a master",
1118 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001119
Jon Hall65844a32015-03-09 19:09:37 -07001120 main.step( "Get the Mastership of each switch from each controller" )
1121 ONOSMastership = []
1122 mastershipCheck = main.FALSE
1123 consistentMastership = True
1124 rolesResults = True
1125 threads = []
1126 for i in range( numControllers ):
1127 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001128 name="roles-" + str( i ),
1129 args=[] )
1130 threads.append( t )
1131 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001132
1133 for t in threads:
1134 t.join()
1135 ONOSMastership.append( t.result )
1136
1137 for i in range( numControllers ):
1138 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001139 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001140 " roles" )
1141 main.log.warn(
1142 "ONOS" + str( i + 1 ) + " mastership response: " +
1143 repr( ONOSMastership[i] ) )
1144 rolesResults = False
1145 utilities.assert_equals(
1146 expect=True,
1147 actual=rolesResults,
1148 onpass="No error in reading roles output",
1149 onfail="Error in reading roles from ONOS" )
1150
1151 main.step( "Check for consistency in roles from each controller" )
1152 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001153 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001154 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001155 else:
Jon Hall65844a32015-03-09 19:09:37 -07001156 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001157 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001158 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001159 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001160 onpass="Switch roles are consistent across all ONOS nodes",
1161 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001162
Jon Hall65844a32015-03-09 19:09:37 -07001163 if rolesResults and not consistentMastership:
1164 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001165 try:
1166 main.log.warn(
1167 "ONOS" + str( i + 1 ) + " roles: ",
1168 json.dumps(
1169 json.loads( ONOSMastership[ i ] ),
1170 sort_keys=True,
1171 indent=4,
1172 separators=( ',', ': ' ) ) )
1173 except ( ValueError, TypeError ):
1174 main.log.warn( repr( ONOSMastership[ i ] ) )
1175 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001176 mastershipCheck = main.TRUE
1177 mastershipState = ONOSMastership[ 0 ]
1178
Jon Hall6aec96b2015-01-19 14:49:31 -08001179 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001180 global intentState
1181 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001182 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001183 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001184 consistentIntents = True
1185 intentsResults = True
1186 threads = []
1187 for i in range( numControllers ):
1188 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001189 name="intents-" + str( i ),
1190 args=[],
1191 kwargs={ 'jsonFormat': True } )
1192 threads.append( t )
1193 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001194
1195 for t in threads:
1196 t.join()
1197 ONOSIntents.append( t.result )
1198
1199 for i in range( numControllers ):
1200 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001201 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001202 " intents" )
1203 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1204 repr( ONOSIntents[ i ] ) )
1205 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001206 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001207 expect=True,
1208 actual=intentsResults,
1209 onpass="No error in reading intents output",
1210 onfail="Error in reading intents from ONOS" )
1211
1212 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001213 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001214 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001215 "nodes" )
1216 else:
1217 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001218 main.log.error( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001219 utilities.assert_equals(
1220 expect=True,
1221 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001222 onpass="Intents are consistent across all ONOS nodes",
1223 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001224
Jon Hall390696c2015-05-05 17:13:41 -07001225 if intentsResults:
1226 # Try to make it easy to figure out what is happening
1227 #
1228 # Intent ONOS1 ONOS2 ...
1229 # 0x01 INSTALLED INSTALLING
1230 # ... ... ...
1231 # ... ... ...
1232 title = " Id"
1233 for n in range( numControllers ):
1234 title += " " * 10 + "ONOS" + str( n + 1 )
1235 main.log.warn( title )
Jon Hall390696c2015-05-05 17:13:41 -07001236 keys = []
Jon Hall40d2cbd2015-06-03 16:24:29 -07001237 try:
1238 # Get the set of all intent keys
Jon Hall390696c2015-05-05 17:13:41 -07001239 for nodeStr in ONOSIntents:
1240 node = json.loads( nodeStr )
1241 for intent in node:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001242 keys.append( intent.get( 'id' ) )
1243 keys = set( keys )
1244 # For each intent key, print the state on each node
1245 for key in keys:
1246 row = "%-13s" % key
1247 for nodeStr in ONOSIntents:
1248 node = json.loads( nodeStr )
1249 for intent in node:
1250 if intent.get( 'id', "Error" ) == key:
1251 row += "%-15s" % intent.get( 'state' )
1252 main.log.warn( row )
1253 # End of intent state table
1254 except ValueError as e:
1255 main.log.exception( e )
1256 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall390696c2015-05-05 17:13:41 -07001257
Jon Hall65844a32015-03-09 19:09:37 -07001258 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001259 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001260 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001261 main.log.debug( "ONOS" + str( n ) + " intents: " )
1262 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1263 sort_keys=True,
1264 indent=4,
1265 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001266 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001267 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001268 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1269 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1270 sort_keys=True,
1271 indent=4,
1272 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001273 else:
Jon Hall390696c2015-05-05 17:13:41 -07001274 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1275 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001276 elif intentsResults and consistentIntents:
1277 intentCheck = main.TRUE
1278 intentState = ONOSIntents[ 0 ]
1279
Jon Hall6aec96b2015-01-19 14:49:31 -08001280 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001281 global flowState
1282 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001283 ONOSFlows = []
1284 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001285 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001286 consistentFlows = True
1287 flowsResults = True
1288 threads = []
1289 for i in range( numControllers ):
1290 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001291 name="flows-" + str( i ),
1292 args=[],
1293 kwargs={ 'jsonFormat': True } )
1294 threads.append( t )
1295 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001296
Jon Halla9d26da2015-03-30 16:45:32 -07001297 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001298 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001299 for t in threads:
1300 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001301 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001302 ONOSFlows.append( result )
1303
1304 for i in range( numControllers ):
1305 num = str( i + 1 )
1306 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001307 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall65844a32015-03-09 19:09:37 -07001308 main.log.warn( "ONOS" + num + " flows response: " +
1309 repr( ONOSFlows[ i ] ) )
1310 flowsResults = False
1311 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001312 else:
Jon Hall65844a32015-03-09 19:09:37 -07001313 try:
1314 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1315 except ( ValueError, TypeError ):
1316 # FIXME: change this to log.error?
1317 main.log.exception( "Error in parsing ONOS" + num +
1318 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001319 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001320 ONOSFlowsJson.append( None )
1321 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001322 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001323 expect=True,
1324 actual=flowsResults,
1325 onpass="No error in reading flows output",
1326 onfail="Error in reading flows from ONOS" )
1327
1328 main.step( "Check for consistency in Flows from each controller" )
1329 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1330 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001331 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001332 else:
1333 consistentFlows = False
1334 utilities.assert_equals(
1335 expect=True,
1336 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001337 onpass="The flow count is consistent across all ONOS nodes",
1338 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001339
Jon Hall65844a32015-03-09 19:09:37 -07001340 if flowsResults and not consistentFlows:
1341 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001342 try:
1343 main.log.warn(
1344 "ONOS" + str( i + 1 ) + " flows: " +
1345 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1346 indent=4, separators=( ',', ': ' ) ) )
1347 except ( ValueError, TypeError ):
1348 main.log.warn(
1349 "ONOS" + str( i + 1 ) + " flows: " +
1350 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001351 elif flowsResults and consistentFlows:
1352 flowCheck = main.TRUE
1353 flowState = ONOSFlows[ 0 ]
1354
Jon Hall6aec96b2015-01-19 14:49:31 -08001355 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001356 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001357 flows = []
1358 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001359 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001360 if flowCheck == main.FALSE:
1361 for table in flows:
1362 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001363 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001364
Jon Hall6aec96b2015-01-19 14:49:31 -08001365 main.step( "Start continuous pings" )
1366 main.Mininet2.pingLong(
1367 src=main.params[ 'PING' ][ 'source1' ],
1368 target=main.params[ 'PING' ][ 'target1' ],
1369 pingTime=500 )
1370 main.Mininet2.pingLong(
1371 src=main.params[ 'PING' ][ 'source2' ],
1372 target=main.params[ 'PING' ][ 'target2' ],
1373 pingTime=500 )
1374 main.Mininet2.pingLong(
1375 src=main.params[ 'PING' ][ 'source3' ],
1376 target=main.params[ 'PING' ][ 'target3' ],
1377 pingTime=500 )
1378 main.Mininet2.pingLong(
1379 src=main.params[ 'PING' ][ 'source4' ],
1380 target=main.params[ 'PING' ][ 'target4' ],
1381 pingTime=500 )
1382 main.Mininet2.pingLong(
1383 src=main.params[ 'PING' ][ 'source5' ],
1384 target=main.params[ 'PING' ][ 'target5' ],
1385 pingTime=500 )
1386 main.Mininet2.pingLong(
1387 src=main.params[ 'PING' ][ 'source6' ],
1388 target=main.params[ 'PING' ][ 'target6' ],
1389 pingTime=500 )
1390 main.Mininet2.pingLong(
1391 src=main.params[ 'PING' ][ 'source7' ],
1392 target=main.params[ 'PING' ][ 'target7' ],
1393 pingTime=500 )
1394 main.Mininet2.pingLong(
1395 src=main.params[ 'PING' ][ 'source8' ],
1396 target=main.params[ 'PING' ][ 'target8' ],
1397 pingTime=500 )
1398 main.Mininet2.pingLong(
1399 src=main.params[ 'PING' ][ 'source9' ],
1400 target=main.params[ 'PING' ][ 'target9' ],
1401 pingTime=500 )
1402 main.Mininet2.pingLong(
1403 src=main.params[ 'PING' ][ 'source10' ],
1404 target=main.params[ 'PING' ][ 'target10' ],
1405 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001406
Jon Hall6aec96b2015-01-19 14:49:31 -08001407 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001408 ctrls = []
Jon Hall65844a32015-03-09 19:09:37 -07001409 for node in nodes:
1410 temp = ( node, node.name, node.ip_address, 6633 )
Jon Hall65844a32015-03-09 19:09:37 -07001411 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001412 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001413
Jon Hall6aec96b2015-01-19 14:49:31 -08001414 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001415 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001416 threads = []
1417 for i in range( numControllers ):
1418 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001419 name="devices-" + str( i ),
1420 args=[ ] )
1421 threads.append( t )
1422 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001423
1424 for t in threads:
1425 t.join()
1426 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001427 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001428 threads = []
1429 for i in range( numControllers ):
1430 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001431 name="hosts-" + str( i ),
1432 args=[ ] )
1433 threads.append( t )
1434 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001435
1436 for t in threads:
1437 t.join()
1438 try:
1439 hosts.append( json.loads( t.result ) )
1440 except ( ValueError, TypeError ):
1441 # FIXME: better handling of this, print which node
1442 # Maybe use thread name?
1443 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001444 # FIXME: should this be an empty json object instead?
1445 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001446
Jon Hallb1290e82014-11-18 16:17:48 -05001447 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001448 threads = []
1449 for i in range( numControllers ):
1450 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001451 name="ports-" + str( i ),
1452 args=[ ] )
1453 threads.append( t )
1454 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001455
1456 for t in threads:
1457 t.join()
1458 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001459 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001460 threads = []
1461 for i in range( numControllers ):
1462 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001463 name="links-" + str( i ),
1464 args=[ ] )
1465 threads.append( t )
1466 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001467
1468 for t in threads:
1469 t.join()
1470 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001471 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001472 threads = []
1473 for i in range( numControllers ):
1474 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001475 name="clusters-" + str( i ),
1476 args=[ ] )
1477 threads.append( t )
1478 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001479
1480 for t in threads:
1481 t.join()
1482 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001483 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001484
Jon Hall6aec96b2015-01-19 14:49:31 -08001485 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001486 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001487 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001488 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001489 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001490 if "Error" not in hosts[ controller ]:
1491 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001492 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001493 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001494 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001495 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001496 " is inconsistent with ONOS1" )
1497 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001498 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001499
1500 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001501 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001502 controllerStr )
1503 consistentHostsResult = main.FALSE
1504 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001505 " hosts response: " +
1506 repr( hosts[ controller ] ) )
1507 utilities.assert_equals(
1508 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001509 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001510 onpass="Hosts view is consistent across all ONOS nodes",
1511 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001512
Jon Hall390696c2015-05-05 17:13:41 -07001513 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001514 ipResult = main.TRUE
1515 for controller in range( 0, len( hosts ) ):
1516 controllerStr = str( controller + 1 )
1517 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001518 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001519 main.log.error( "DEBUG:Error with host ips on controller" +
1520 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001521 ipResult = main.FALSE
1522 utilities.assert_equals(
1523 expect=main.TRUE,
1524 actual=ipResult,
1525 onpass="The ips of the hosts aren't empty",
1526 onfail="The ip of at least one host is missing" )
1527
Jon Hall6aec96b2015-01-19 14:49:31 -08001528 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001529 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001530 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001531 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001532 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001533 if "Error" not in clusters[ controller ]:
1534 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001535 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001536 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001537 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001538 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001539 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001540
1541 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001542 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001543 "from ONOS" + controllerStr )
1544 consistentClustersResult = main.FALSE
1545 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001546 " clusters response: " +
1547 repr( clusters[ controller ] ) )
1548 utilities.assert_equals(
1549 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001550 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 onpass="Clusters view is consistent across all ONOS nodes",
1552 onfail="ONOS nodes have different views of clusters" )
1553 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001554 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001555 try:
1556 numClusters = len( json.loads( clusters[ 0 ] ) )
1557 except ( ValueError, TypeError ):
1558 main.log.exception( "Error parsing clusters[0]: " +
1559 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001560 clusterResults = main.FALSE
1561 if numClusters == 1:
1562 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001563 utilities.assert_equals(
1564 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001565 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001566 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001567 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001568
Jon Hall6aec96b2015-01-19 14:49:31 -08001569 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001570 devicesResults = main.TRUE
1571 portsResults = main.TRUE
1572 linksResults = main.TRUE
1573 for controller in range( numControllers ):
1574 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001575 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001576 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001577 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001578 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001579 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001580 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001581 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001582 actual=currentDevicesResult,
1583 onpass="ONOS" + controllerStr +
1584 " Switches view is correct",
1585 onfail="ONOS" + controllerStr +
1586 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001587
Jon Hall6aec96b2015-01-19 14:49:31 -08001588 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001589 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001590 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001591 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001592 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001593 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001594 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001595 actual=currentPortsResult,
1596 onpass="ONOS" + controllerStr +
1597 " ports view is correct",
1598 onfail="ONOS" + controllerStr +
1599 " ports view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001600
Jon Hall6aec96b2015-01-19 14:49:31 -08001601 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001602 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001603 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001604 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001605 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001606 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001607 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001608 actual=currentLinksResult,
1609 onpass="ONOS" + controllerStr +
1610 " links view is correct",
1611 onfail="ONOS" + controllerStr +
1612 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001613
Jon Hall8f89dda2015-01-22 16:03:33 -08001614 devicesResults = devicesResults and currentDevicesResult
1615 portsResults = portsResults and currentPortsResult
1616 linksResults = linksResults and currentLinksResult
Jon Hallb1290e82014-11-18 16:17:48 -05001617
Jon Hall65844a32015-03-09 19:09:37 -07001618 topoResult = ( devicesResults and portsResults and linksResults
1619 and consistentHostsResult and consistentClustersResult
1620 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001621 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001622 onpass="Topology Check Test successful",
1623 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001624
Jon Hall6aec96b2015-01-19 14:49:31 -08001625 def CASE6( self, main ):
1626 """
Jon Hallb1290e82014-11-18 16:17:48 -05001627 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001628 """
Jon Hall368769f2014-11-19 15:43:35 -08001629 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001630 assert numControllers, "numControllers not defined"
1631 assert main, "main not defined"
1632 assert utilities.assert_equals, "utilities.assert_equals not defined"
1633 assert CLIs, "CLIs not defined"
1634 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001635 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001636 time.sleep( 60 )
1637 utilities.assert_equals(
1638 expect=main.TRUE,
1639 actual=main.TRUE,
1640 onpass="Sleeping 60 seconds",
1641 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001642
Jon Hall6aec96b2015-01-19 14:49:31 -08001643 def CASE7( self, main ):
1644 """
Jon Hall368769f2014-11-19 15:43:35 -08001645 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001646 """
Jon Hallb1290e82014-11-18 16:17:48 -05001647 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001648 assert numControllers, "numControllers not defined"
1649 assert main, "main not defined"
1650 assert utilities.assert_equals, "utilities.assert_equals not defined"
1651 assert CLIs, "CLIs not defined"
1652 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001653 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001654
Jon Hall65844a32015-03-09 19:09:37 -07001655 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001656 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001657 rolesNotNull = main.TRUE
1658 threads = []
1659 for i in range( numControllers ):
1660 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001661 name="rolesNotNull-" + str( i ),
1662 args=[ ] )
1663 threads.append( t )
1664 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001665
1666 for t in threads:
1667 t.join()
1668 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001669 utilities.assert_equals(
1670 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001671 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001672 onpass="Each device has a master",
1673 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001674
Jon Hall390696c2015-05-05 17:13:41 -07001675 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001676 ONOSMastership = []
1677 mastershipCheck = main.FALSE
1678 consistentMastership = True
1679 rolesResults = True
1680 threads = []
1681 for i in range( numControllers ):
1682 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001683 name="roles-" + str( i ),
1684 args=[] )
1685 threads.append( t )
1686 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001687
1688 for t in threads:
1689 t.join()
1690 ONOSMastership.append( t.result )
1691
1692 for i in range( numControllers ):
1693 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001694 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001695 " roles" )
1696 main.log.warn(
1697 "ONOS" + str( i + 1 ) + " mastership response: " +
1698 repr( ONOSMastership[i] ) )
1699 rolesResults = False
1700 utilities.assert_equals(
1701 expect=True,
1702 actual=rolesResults,
1703 onpass="No error in reading roles output",
1704 onfail="Error in reading roles from ONOS" )
1705
1706 main.step( "Check for consistency in roles from each controller" )
1707 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001708 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001710 else:
Jon Hall65844a32015-03-09 19:09:37 -07001711 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001712 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001713 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001714 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001715 onpass="Switch roles are consistent across all ONOS nodes",
1716 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001717
Jon Hall65844a32015-03-09 19:09:37 -07001718 if rolesResults and not consistentMastership:
1719 for i in range( numControllers ):
1720 main.log.warn(
1721 "ONOS" + str( i + 1 ) + " roles: ",
1722 json.dumps(
1723 json.loads( ONOSMastership[ i ] ),
1724 sort_keys=True,
1725 indent=4,
1726 separators=( ',', ': ' ) ) )
1727 elif rolesResults and not consistentMastership:
1728 mastershipCheck = main.TRUE
1729
Jon Hallb1290e82014-11-18 16:17:48 -05001730 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001731 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001732 try:
1733 currentJson = json.loads( ONOSMastership[0] )
1734 oldJson = json.loads( mastershipState )
1735 except ( ValueError, TypeError ):
1736 main.log.exception( "Something is wrong with parsing " +
1737 "ONOSMastership[0] or mastershipState" )
1738 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1739 main.log.error( "mastershipState" + repr( mastershipState ) )
1740 main.cleanup()
1741 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001742 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001743 for i in range( 1, 29 ):
1744 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001745 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001746 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001747 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001748 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001749 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001750 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001751 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001752 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001753 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001754 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001755 utilities.assert_equals(
1756 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001757 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001758 onpass="Mastership of Switches was not changed",
1759 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001760 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001761
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001763 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001764 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001765 consistentIntents = True
1766 intentsResults = True
1767 threads = []
1768 for i in range( numControllers ):
1769 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001770 name="intents-" + str( i ),
1771 args=[],
1772 kwargs={ 'jsonFormat': True } )
1773 threads.append( t )
1774 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001775
1776 for t in threads:
1777 t.join()
1778 ONOSIntents.append( t.result )
1779
1780 for i in range( numControllers ):
1781 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001782 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001783 " intents" )
1784 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1785 repr( ONOSIntents[ i ] ) )
1786 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001787 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001788 expect=True,
1789 actual=intentsResults,
1790 onpass="No error in reading intents output",
1791 onfail="Error in reading intents from ONOS" )
1792
1793 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001794 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001795 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001796 "nodes" )
1797 else:
1798 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001799
1800 # Try to make it easy to figure out what is happening
1801 #
1802 # Intent ONOS1 ONOS2 ...
1803 # 0x01 INSTALLED INSTALLING
1804 # ... ... ...
1805 # ... ... ...
1806 title = " ID"
1807 for n in range( numControllers ):
1808 title += " " * 10 + "ONOS" + str( n + 1 )
1809 main.log.warn( title )
1810 # get all intent keys in the cluster
1811 keys = []
1812 for nodeStr in ONOSIntents:
1813 node = json.loads( nodeStr )
1814 for intent in node:
1815 keys.append( intent.get( 'id' ) )
1816 keys = set( keys )
1817 for key in keys:
1818 row = "%-13s" % key
1819 for nodeStr in ONOSIntents:
1820 node = json.loads( nodeStr )
1821 for intent in node:
1822 if intent.get( 'id' ) == key:
1823 row += "%-15s" % intent.get( 'state' )
1824 main.log.warn( row )
1825 # End table view
1826
Jon Hall65844a32015-03-09 19:09:37 -07001827 utilities.assert_equals(
1828 expect=True,
1829 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001830 onpass="Intents are consistent across all ONOS nodes",
1831 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001832 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001833 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001834 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001835 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001836 try:
1837 for intent in json.loads( node ):
1838 nodeStates.append( intent[ 'state' ] )
1839 except ( ValueError, TypeError ):
1840 main.log.exception( "Error in parsing intents" )
1841 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001842 intentStates.append( nodeStates )
1843 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1844 main.log.info( dict( out ) )
1845
Jon Hall65844a32015-03-09 19:09:37 -07001846 if intentsResults and not consistentIntents:
1847 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001848 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1849 main.log.warn( json.dumps(
1850 json.loads( ONOSIntents[ i ] ),
1851 sort_keys=True,
1852 indent=4,
1853 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001854 elif intentsResults and consistentIntents:
1855 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001856
Jon Hall58c76b72015-02-23 11:09:24 -08001857 # NOTE: Store has no durability, so intents are lost across system
1858 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001859 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001860 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001861 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001862 sameIntents = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001863 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001864 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001865 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001866 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001867 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001868 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1869 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001870 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001871 before = json.loads( intentState )
1872 after = json.loads( ONOSIntents[ 0 ] )
1873 for intent in before:
1874 if intent not in after:
1875 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001876 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001877 "(at least in the same form):" )
1878 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001879 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001880 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001881 main.log.debug( repr( ONOSIntents[0] ) )
1882 main.log.debug( repr( intentState ) )
1883 if sameIntents == main.FALSE:
1884 try:
1885 main.log.debug( "ONOS intents before: " )
1886 main.log.debug( json.dumps( json.loads( intentState ),
1887 sort_keys=True, indent=4,
1888 separators=( ',', ': ' ) ) )
1889 main.log.debug( "Current ONOS intents: " )
1890 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1891 sort_keys=True, indent=4,
1892 separators=( ',', ': ' ) ) )
1893 except ( ValueError, TypeError ):
1894 main.log.exception( "Exception printing intents" )
1895 main.log.debug( repr( ONOSIntents[0] ) )
1896 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001897 utilities.assert_equals(
1898 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001899 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001900 onpass="Intents are consistent with before failure",
1901 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001902 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001903
Jon Hall6aec96b2015-01-19 14:49:31 -08001904 main.step( "Get the OF Table entries and compare to before " +
1905 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001906 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001907 flows2 = []
1908 for i in range( 28 ):
1909 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001910 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1911 flows2.append( tmpFlows )
1912 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001913 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001914 flow2=tmpFlows )
1915 FlowTables = FlowTables and tempResult
1916 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001917 main.log.info( "Differences in flow table for switch: s" +
1918 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001919 utilities.assert_equals(
1920 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001921 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001922 onpass="No changes were found in the flow tables",
1923 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001924
Jon Hall6aec96b2015-01-19 14:49:31 -08001925 main.step( "Check the continuous pings to ensure that no packets " +
1926 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001927 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1928 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001929 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001930 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1931 for i in range( 8, 18 ):
1932 main.log.info(
1933 "Checking for a loss in pings along flow from s" +
1934 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001935 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001936 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001937 str( i ) ) or LossInPings
1938 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001940 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001941 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001942 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001943 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001944 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001945 utilities.assert_equals(
1946 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001947 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 onpass="No Loss of connectivity",
1949 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001950
Jon Hall390696c2015-05-05 17:13:41 -07001951 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001952 # Test of LeadershipElection
1953 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001954 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001955 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001956 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001957 for cli in CLIs:
1958 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001959 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001960 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001961 # all is well
1962 # NOTE: In failure scenario, this could be a new node, maybe
1963 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001964 pass
1965 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001966 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001967 main.log.error( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001968 "electionTestLeader function, check the" +
1969 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001970 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001971 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001972 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001973 main.log.error( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001974 " as the leader of the election app. " +
1975 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001976 utilities.assert_equals(
1977 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001978 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001979 onpass="Leadership election passed",
1980 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001981
Jon Hall6aec96b2015-01-19 14:49:31 -08001982 def CASE8( self, main ):
1983 """
Jon Hallb1290e82014-11-18 16:17:48 -05001984 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001985 """
Jon Hallb1290e82014-11-18 16:17:48 -05001986 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001987 # FIXME add this path to params
1988 sys.path.append( "/home/admin/sts" )
1989 # assumes that sts is already in you PYTHONPATH
1990 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001991 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001992 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001993 assert numControllers, "numControllers not defined"
1994 assert main, "main not defined"
1995 assert utilities.assert_equals, "utilities.assert_equals not defined"
1996 assert CLIs, "CLIs not defined"
1997 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05001998
Jon Hallfeff3082015-05-19 10:23:26 -07001999 main.case( "Compare ONOS Topology view to Mininet topology" )
2000 main.caseExplaination = "Compare topology objects between Mininet" +\
2001 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08002002 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07002003 try:
2004 ctrls = []
2005 for node in nodes:
2006 temp = ( node, node.name, node.ip_address, 6633 )
2007 ctrls.append( temp )
2008 MNTopo = TestONTopology( main.Mininet1, ctrls )
2009 except Exception:
2010 objResult = main.FALSE
2011 else:
2012 objResult = main.TRUE
2013 utilities.assert_equals( expect=main.TRUE, actual=objResult,
2014 onpass="Created TestONTopology object",
2015 onfail="Exception while creating " +
2016 "TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05002017
Jon Hallfeff3082015-05-19 10:23:26 -07002018 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002019 devicesResults = main.TRUE
2020 portsResults = main.TRUE
2021 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002022 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002023 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002024 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002025 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002026 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002027 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002028 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002029 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002030 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07002031 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08002032 if count > 1:
Jon Hall65844a32015-03-09 19:09:37 -07002033 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08002034 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002035 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002036 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07002037 threads = []
2038 for i in range( numControllers ):
2039 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07002040 name="devices-" + str( i ),
2041 args=[ ] )
2042 threads.append( t )
2043 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002044
2045 for t in threads:
2046 t.join()
2047 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002048 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002049 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07002050 threads = []
2051 for i in range( numControllers ):
2052 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07002053 name="hosts-" + str( i ),
2054 args=[ ] )
2055 threads.append( t )
2056 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002057
2058 for t in threads:
2059 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002060 try:
2061 hosts.append( json.loads( t.result ) )
2062 except ( ValueError, TypeError ):
2063 main.log.exception( "Error parsing hosts results" )
2064 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002065 for controller in range( 0, len( hosts ) ):
2066 controllerStr = str( controller + 1 )
2067 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002068 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002069 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002070 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002071 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002072 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002073 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07002074 threads = []
2075 for i in range( numControllers ):
2076 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07002077 name="ports-" + str( i ),
2078 args=[ ] )
2079 threads.append( t )
2080 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002081
2082 for t in threads:
2083 t.join()
2084 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002085 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002086 threads = []
2087 for i in range( numControllers ):
2088 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002089 name="links-" + str( i ),
2090 args=[ ] )
2091 threads.append( t )
2092 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002093
2094 for t in threads:
2095 t.join()
2096 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002097 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002098 threads = []
2099 for i in range( numControllers ):
2100 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002101 name="clusters-" + str( i ),
2102 args=[ ] )
2103 threads.append( t )
2104 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002105
2106 for t in threads:
2107 t.join()
2108 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002109
Jon Hall8f89dda2015-01-22 16:03:33 -08002110 elapsed = time.time() - startTime
2111 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002112 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002113 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002114
Jon Hall21270ac2015-02-16 17:59:55 -08002115 for controller in range( numControllers ):
2116 controllerStr = str( controller + 1 )
2117 if devices[ controller ] or "Error" not in devices[
2118 controller ]:
2119 currentDevicesResult = main.Mininet1.compareSwitches(
2120 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002121 json.loads( devices[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002122 else:
2123 currentDevicesResult = main.FALSE
2124 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002125 actual=currentDevicesResult,
2126 onpass="ONOS" + controllerStr +
2127 " Switches view is correct",
2128 onfail="ONOS" + controllerStr +
2129 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002130
Jon Hall21270ac2015-02-16 17:59:55 -08002131 if ports[ controller ] or "Error" not in ports[ controller ]:
2132 currentPortsResult = main.Mininet1.comparePorts(
2133 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002134 json.loads( ports[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002135 else:
2136 currentPortsResult = main.FALSE
2137 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002138 actual=currentPortsResult,
2139 onpass="ONOS" + controllerStr +
2140 " ports view is correct",
2141 onfail="ONOS" + controllerStr +
2142 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002143
Jon Hall21270ac2015-02-16 17:59:55 -08002144 if links[ controller ] or "Error" not in links[ controller ]:
2145 currentLinksResult = main.Mininet1.compareLinks(
2146 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002147 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002148 else:
2149 currentLinksResult = main.FALSE
2150 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002151 actual=currentLinksResult,
2152 onpass="ONOS" + controllerStr +
2153 " links view is correct",
2154 onfail="ONOS" + controllerStr +
2155 " links view is incorrect" )
2156
2157 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2158 currentHostsResult = main.Mininet1.compareHosts(
2159 MNTopo, hosts[ controller ] )
2160 else:
2161 currentHostsResult = main.FALSE
2162 utilities.assert_equals( expect=main.TRUE,
2163 actual=currentHostsResult,
2164 onpass="ONOS" + controllerStr +
2165 " hosts exist in Mininet",
2166 onfail="ONOS" + controllerStr +
2167 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002168 # CHECKING HOST ATTACHMENT POINTS
2169 hostAttachment = True
2170 noHosts = False
2171 # FIXME: topo-HA/obelisk specific mappings:
2172 # key is mac and value is dpid
2173 mappings = {}
2174 for i in range( 1, 29 ): # hosts 1 through 28
2175 # set up correct variables:
2176 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2177 if i == 1:
2178 deviceId = "1000".zfill(16)
2179 elif i == 2:
2180 deviceId = "2000".zfill(16)
2181 elif i == 3:
2182 deviceId = "3000".zfill(16)
2183 elif i == 4:
2184 deviceId = "3004".zfill(16)
2185 elif i == 5:
2186 deviceId = "5000".zfill(16)
2187 elif i == 6:
2188 deviceId = "6000".zfill(16)
2189 elif i == 7:
2190 deviceId = "6007".zfill(16)
2191 elif i >= 8 and i <= 17:
2192 dpid = '3' + str( i ).zfill( 3 )
2193 deviceId = dpid.zfill(16)
2194 elif i >= 18 and i <= 27:
2195 dpid = '6' + str( i ).zfill( 3 )
2196 deviceId = dpid.zfill(16)
2197 elif i == 28:
2198 deviceId = "2800".zfill(16)
2199 mappings[ macId ] = deviceId
2200 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2201 if hosts[ controller ] == []:
2202 main.log.warn( "There are no hosts discovered" )
2203 noHosts = True
2204 else:
2205 for host in hosts[ controller ]:
2206 mac = None
2207 location = None
2208 device = None
2209 port = None
2210 try:
2211 mac = host.get( 'mac' )
2212 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002213
Jon Hallc9eabec2015-06-10 14:33:14 -07002214 location = host.get( 'location' )
2215 assert location, "location field could not be found for this host object"
2216
2217 # Trim the protocol identifier off deviceId
2218 device = str( location.get( 'elementId' ) ).split(':')[1]
2219 assert device, "elementId field could not be found for this host location object"
2220
2221 port = location.get( 'port' )
2222 assert port, "port field could not be found for this host location object"
2223
2224 # Now check if this matches where they should be
2225 if mac and device and port:
2226 if str( port ) != "1":
2227 main.log.error( "The attachment port is incorrect for " +
2228 "host " + str( mac ) +
2229 ". Expected: 1 Actual: " + str( port) )
2230 hostAttachment = False
2231 if device != mappings[ str( mac ) ]:
2232 main.log.error( "The attachment device is incorrect for " +
2233 "host " + str( mac ) +
2234 ". Expected: " + mappings[ str( mac ) ] +
2235 " Actual: " + device )
2236 hostAttachment = False
2237 else:
2238 hostAttachment = False
2239 except AssertionError:
2240 main.log.exception( "Json object not as expected" )
2241 main.log.error( repr( host ) )
2242 hostAttachment = False
2243 else:
2244 main.log.error( "No hosts json output or \"Error\"" +
2245 " in output. hosts = " +
2246 repr( hosts[ controller ] ) )
2247 if noHosts is False:
2248 hostAttachment = True
2249
2250 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002251 devicesResults = devicesResults and currentDevicesResult
2252 portsResults = portsResults and currentPortsResult
2253 linksResults = linksResults and currentLinksResult
2254 hostsResults = hostsResults and currentHostsResult
Jon Hallc9eabec2015-06-10 14:33:14 -07002255 hostAttachmentResults = hostAttachmentResults and hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002256
Jon Hallc9eabec2015-06-10 14:33:14 -07002257 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002258
Jon Hallc9eabec2015-06-10 14:33:14 -07002259 # hosts
2260 main.step( "Hosts view is consistent across all ONOS nodes" )
2261 consistentHostsResult = main.TRUE
2262 for controller in range( len( hosts ) ):
2263 controllerStr = str( controller + 1 )
2264 if "Error" not in hosts[ controller ]:
2265 if hosts[ controller ] == hosts[ 0 ]:
2266 continue
2267 else: # hosts not consistent
2268 main.log.error( "hosts from ONOS" + controllerStr +
2269 " is inconsistent with ONOS1" )
2270 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002271 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002272
Jon Hallc9eabec2015-06-10 14:33:14 -07002273 else:
2274 main.log.error( "Error in getting ONOS hosts from ONOS" +
2275 controllerStr )
2276 consistentHostsResult = main.FALSE
2277 main.log.warn( "ONOS" + controllerStr +
2278 " hosts response: " +
2279 repr( hosts[ controller ] ) )
2280 utilities.assert_equals(
2281 expect=main.TRUE,
2282 actual=consistentHostsResult,
2283 onpass="Hosts view is consistent across all ONOS nodes",
2284 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002285
Jon Hallc9eabec2015-06-10 14:33:14 -07002286 main.step( "Hosts information is correct" )
2287 hostsResults = hostsResults and ipResult
2288 utilities.assert_equals(
2289 expect=main.TRUE,
2290 actual=hostsResults,
2291 onpass="Host information is correct",
2292 onfail="Host information is incorrect" )
2293
2294 main.step( "Host attachment points to the network" )
2295 utilities.assert_equals(
2296 expect=True,
2297 actual=hostAttachmentResults,
2298 onpass="Hosts are correctly attached to the network",
2299 onfail="ONOS did not correctly attach hosts to the network" )
2300
2301 # Strongly connected clusters of devices
2302 main.step( "Clusters view is consistent across all ONOS nodes" )
2303 consistentClustersResult = main.TRUE
2304 for controller in range( len( clusters ) ):
2305 controllerStr = str( controller + 1 )
2306 if "Error" not in clusters[ controller ]:
2307 if clusters[ controller ] == clusters[ 0 ]:
2308 continue
2309 else: # clusters not consistent
2310 main.log.error( "clusters from ONOS" +
2311 controllerStr +
2312 " is inconsistent with ONOS1" )
Jon Hall21270ac2015-02-16 17:59:55 -08002313 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002314
Jon Hallc9eabec2015-06-10 14:33:14 -07002315 else:
2316 main.log.error( "Error in getting dataplane clusters " +
2317 "from ONOS" + controllerStr )
2318 consistentClustersResult = main.FALSE
2319 main.log.warn( "ONOS" + controllerStr +
2320 " clusters response: " +
2321 repr( clusters[ controller ] ) )
2322 utilities.assert_equals(
2323 expect=main.TRUE,
2324 actual=consistentClustersResult,
2325 onpass="Clusters view is consistent across all ONOS nodes",
2326 onfail="ONOS nodes have different views of clusters" )
2327
2328 main.step( "There is only one SCC" )
2329 # there should always only be one cluster
2330 try:
2331 numClusters = len( json.loads( clusters[ 0 ] ) )
2332 except ( ValueError, TypeError ):
2333 main.log.exception( "Error parsing clusters[0]: " +
2334 repr( clusters[0] ) )
2335 clusterResults = main.FALSE
2336 if numClusters == 1:
2337 clusterResults = main.TRUE
2338 utilities.assert_equals(
2339 expect=1,
2340 actual=numClusters,
2341 onpass="ONOS shows 1 SCC",
2342 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2343
2344 topoResult = ( devicesResults and portsResults and linksResults
2345 and hostsResults and consistentHostsResult
2346 and consistentClustersResult and clusterResults
2347 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002348
Jon Hall21270ac2015-02-16 17:59:55 -08002349 topoResult = topoResult and int( count <= 2 )
2350 note = "note it takes about " + str( int( cliTime ) ) + \
2351 " seconds for the test to make all the cli calls to fetch " +\
2352 "the topology from each ONOS instance"
2353 main.log.info(
2354 "Very crass estimate for topology discovery/convergence( " +
2355 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2356 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002357
2358 main.step( "Device information is correct" )
2359 utilities.assert_equals(
2360 expect=main.TRUE,
2361 actual=devicesResults,
2362 onpass="Device information is correct",
2363 onfail="Device information is incorrect" )
2364
2365 main.step( "Port information is correct" )
2366 utilities.assert_equals(
2367 expect=main.TRUE,
2368 actual=portsResults,
2369 onpass="Port information is correct",
2370 onfail="Port information is incorrect" )
2371
2372 main.step( "Links are correct" )
2373 utilities.assert_equals(
2374 expect=main.TRUE,
2375 actual=linksResults,
2376 onpass="Link are correct",
2377 onfail="Links are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002378
Jon Halla9d26da2015-03-30 16:45:32 -07002379 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002380 main.step( "Checking ONOS nodes" )
2381 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002382 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002383 threads = []
2384 for i in range( numControllers ):
2385 t = main.Thread( target=CLIs[i].nodes,
2386 name="nodes-" + str( i ),
2387 args=[ ] )
2388 threads.append( t )
2389 t.start()
2390
2391 for t in threads:
2392 t.join()
2393 nodesOutput.append( t.result )
2394 ips = [ node.ip_address for node in nodes ]
2395 for i in nodesOutput:
2396 try:
2397 current = json.loads( i )
2398 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002399 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002400 if node['ip'] in ips: # node in nodes() output is in cell
2401 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002402 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002403 else:
2404 main.log.error( "Error in ONOS node availability" )
2405 main.log.error(
2406 json.dumps( current,
2407 sort_keys=True,
2408 indent=4,
2409 separators=( ',', ': ' ) ) )
2410 break
Jon Hall390696c2015-05-05 17:13:41 -07002411 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002412 except ( ValueError, TypeError ):
2413 main.log.error( "Error parsing nodes output" )
2414 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002415 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2416 onpass="Nodes check successful",
2417 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002418
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 def CASE9( self, main ):
2420 """
Jon Hallb1290e82014-11-18 16:17:48 -05002421 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002422 """
2423 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002424 assert numControllers, "numControllers not defined"
2425 assert main, "main not defined"
2426 assert utilities.assert_equals, "utilities.assert_equals not defined"
2427 assert CLIs, "CLIs not defined"
2428 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002430
Jon Hall8f89dda2015-01-22 16:03:33 -08002431 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002432
Jon Hall6aec96b2015-01-19 14:49:31 -08002433 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002434 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002435 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002436
Jon Hall6aec96b2015-01-19 14:49:31 -08002437 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002438 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002439 main.log.info( "Waiting " + str( linkSleep ) +
2440 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002441 time.sleep( linkSleep )
2442 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002443 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002444 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002445 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002446
Jon Hall6aec96b2015-01-19 14:49:31 -08002447 def CASE10( self, main ):
2448 """
Jon Hallb1290e82014-11-18 16:17:48 -05002449 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002450 """
2451 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002452 assert numControllers, "numControllers not defined"
2453 assert main, "main not defined"
2454 assert utilities.assert_equals, "utilities.assert_equals not defined"
2455 assert CLIs, "CLIs not defined"
2456 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002457 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002458
Jon Hall8f89dda2015-01-22 16:03:33 -08002459 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002460
Jon Hall6aec96b2015-01-19 14:49:31 -08002461 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002462 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002463 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002464
Jon Hall6aec96b2015-01-19 14:49:31 -08002465 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002466 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002467 main.log.info( "Waiting " + str( linkSleep ) +
2468 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002469 time.sleep( linkSleep )
2470 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002471 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002472 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002473 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002474
Jon Hall6aec96b2015-01-19 14:49:31 -08002475 def CASE11( self, main ):
2476 """
Jon Hallb1290e82014-11-18 16:17:48 -05002477 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002478 """
2479 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002480 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002481 assert numControllers, "numControllers not defined"
2482 assert main, "main not defined"
2483 assert utilities.assert_equals, "utilities.assert_equals not defined"
2484 assert CLIs, "CLIs not defined"
2485 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002486
Jon Hall8f89dda2015-01-22 16:03:33 -08002487 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002488
2489 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002490 main.case( description )
2491 switch = main.params[ 'kill' ][ 'switch' ]
2492 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002493
Jon Hall6aec96b2015-01-19 14:49:31 -08002494 # TODO: Make this switch parameterizable
2495 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002496 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002497 main.Mininet1.delSwitch( switch )
2498 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002499 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002500 time.sleep( switchSleep )
2501 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002502 # Peek at the deleted switch
2503 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002504 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002505 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002506 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002507 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002508 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002509 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002510
Jon Hall6aec96b2015-01-19 14:49:31 -08002511 def CASE12( self, main ):
2512 """
Jon Hallb1290e82014-11-18 16:17:48 -05002513 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002514 """
2515 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002516 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002517 assert numControllers, "numControllers not defined"
2518 assert main, "main not defined"
2519 assert utilities.assert_equals, "utilities.assert_equals not defined"
2520 assert CLIs, "CLIs not defined"
2521 assert nodes, "nodes not defined"
2522 assert ONOS1Port, "ONOS1Port not defined"
2523 assert ONOS2Port, "ONOS2Port not defined"
2524 assert ONOS3Port, "ONOS3Port not defined"
2525 assert ONOS4Port, "ONOS4Port not defined"
2526 assert ONOS5Port, "ONOS5Port not defined"
2527 assert ONOS6Port, "ONOS6Port not defined"
2528 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002529
Jon Hall8f89dda2015-01-22 16:03:33 -08002530 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002531 switch = main.params[ 'kill' ][ 'switch' ]
2532 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2533 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002534 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002535 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002536
Jon Hall6aec96b2015-01-19 14:49:31 -08002537 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002538 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002539 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002540 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002541 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2542 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -07002543 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002544 port1=ONOS1Port,
Jon Hall65844a32015-03-09 19:09:37 -07002545 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002546 port2=ONOS2Port,
Jon Hall65844a32015-03-09 19:09:37 -07002547 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002548 port3=ONOS3Port,
Jon Hall65844a32015-03-09 19:09:37 -07002549 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002550 port4=ONOS4Port,
Jon Hall65844a32015-03-09 19:09:37 -07002551 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002552 port5=ONOS5Port,
Jon Hall65844a32015-03-09 19:09:37 -07002553 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002554 port6=ONOS6Port,
Jon Hall65844a32015-03-09 19:09:37 -07002555 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002556 port7=ONOS7Port )
2557 main.log.info( "Waiting " + str( switchSleep ) +
2558 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002559 time.sleep( switchSleep )
2560 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002561 # Peek at the deleted switch
2562 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002563 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002564 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002565 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002566 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002567 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002568 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002569
Jon Hall6aec96b2015-01-19 14:49:31 -08002570 def CASE13( self, main ):
2571 """
Jon Hallb1290e82014-11-18 16:17:48 -05002572 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002573 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002574 import os
2575 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002576 assert numControllers, "numControllers not defined"
2577 assert main, "main not defined"
2578 assert utilities.assert_equals, "utilities.assert_equals not defined"
2579 assert CLIs, "CLIs not defined"
2580 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002581
2582 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002583 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2584 'blue': '\033[94m', 'green': '\033[92m',
2585 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002586 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002587 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002588 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002589
Jon Hall6aec96b2015-01-19 14:49:31 -08002590 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002591 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002592 teststationUser = main.params[ 'TESTONUSER' ]
2593 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002594 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002595 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002596 # FIXME: scp
2597 # mn files
2598 # TODO: Load these from params
2599 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002600 logFolder = "/opt/onos/log/"
2601 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002602 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002603 dstDir = "~/packet_captures/"
2604 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002605 for node in nodes:
2606 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2607 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002608 teststationUser + "@" +
2609 teststationIP + ":" +
2610 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002611 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002612 main.ONOSbench.handle.expect( "\$" )
2613
Jon Hall6aec96b2015-01-19 14:49:31 -08002614 # std*.log's
2615 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002616 logFolder = "/opt/onos/var/"
2617 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002618 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002619 dstDir = "~/packet_captures/"
2620 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002621 for node in nodes:
2622 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2623 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002624 teststationUser + "@" +
2625 teststationIP + ":" +
2626 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002627 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002628 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002629 # sleep so scp can finish
2630 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002631
2632 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002633 mnResult = main.Mininet1.stopNet()
2634 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2635 onpass="Mininet stopped",
2636 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002637
2638 main.step( "Checking ONOS Logs for errors" )
2639 for node in nodes:
2640 print colors[ 'purple' ] + "Checking logs for errors on " + \
2641 node.name + ":" + colors[ 'end' ]
2642 print main.ONOSbench.checkLogs( node.ip_address )
2643
Jon Hall6aec96b2015-01-19 14:49:31 -08002644 main.step( "Packing and rotating pcap archives" )
2645 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002646
Jon Hall390696c2015-05-05 17:13:41 -07002647 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002648 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002649 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002650 labels = "Gossip Intents"
2651 data = str( gossipTime )
2652 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002653 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002654 except NameError, e:
2655 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002656
Jon Hall6aec96b2015-01-19 14:49:31 -08002657 def CASE14( self, main ):
2658 """
Jon Hall94fd0472014-12-08 11:52:42 -08002659 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002660 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002661 assert numControllers, "numControllers not defined"
2662 assert main, "main not defined"
2663 assert utilities.assert_equals, "utilities.assert_equals not defined"
2664 assert CLIs, "CLIs not defined"
2665 assert nodes, "nodes not defined"
2666
Jon Hall390696c2015-05-05 17:13:41 -07002667 main.case("Start Leadership Election app")
2668 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002669 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2670 utilities.assert_equals(
2671 expect=main.TRUE,
2672 actual=appResult,
2673 onpass="Election app installed",
2674 onfail="Something went wrong with installing Leadership election" )
2675
2676 main.step( "Run for election on each node" )
2677 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002678 leaders = []
2679 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002680 cli.electionTestRun()
2681 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002682 leader = cli.electionTestLeader()
2683 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002684 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002685 "should be an ONOS node, instead got '" +
2686 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002687 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002688 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002689 utilities.assert_equals(
2690 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002691 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002692 onpass="Successfully ran for leadership",
2693 onfail="Failed to run for leadership" )
2694
2695 main.step( "Check that each node shows the same leader" )
2696 sameLeader = main.TRUE
2697 if len( set( leaders ) ) != 1:
2698 sameLeader = main.FALSE
2699 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2700 str( leaders ) )
2701 utilities.assert_equals(
2702 expect=main.TRUE,
2703 actual=sameLeader,
2704 onpass="Leadership is consistent for the election topic",
2705 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002706
Jon Hall6aec96b2015-01-19 14:49:31 -08002707 def CASE15( self, main ):
2708 """
Jon Hall669173b2014-12-17 11:36:30 -08002709 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002710 """
Jon Hall390696c2015-05-05 17:13:41 -07002711 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002712 assert numControllers, "numControllers not defined"
2713 assert main, "main not defined"
2714 assert utilities.assert_equals, "utilities.assert_equals not defined"
2715 assert CLIs, "CLIs not defined"
2716 assert nodes, "nodes not defined"
2717
Jon Hall8f89dda2015-01-22 16:03:33 -08002718 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002719 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002720 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002721
2722 main.step( "Check that each node shows the same leader" )
2723 sameLeader = main.TRUE
2724 leaders = []
2725 for cli in CLIs:
2726 leader = cli.electionTestLeader()
2727 leaders.append( leader )
2728 if len( set( leaders ) ) != 1:
2729 sameLeader = main.FALSE
2730 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2731 str( leaders ) )
2732 utilities.assert_equals(
2733 expect=main.TRUE,
2734 actual=sameLeader,
2735 onpass="Leadership is consistent for the election topic",
2736 onfail="Nodes have different leaders" )
2737
Jon Hall6aec96b2015-01-19 14:49:31 -08002738 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002739 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002740 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002741 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002742 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002743 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002744 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002745 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002746 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002747 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002748 for i in range( len( CLIs ) ):
2749 if leader == nodes[ i ].ip_address:
2750 oldLeader = CLIs[ i ]
2751 break
Jon Halla9d26da2015-03-30 16:45:32 -07002752 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002753 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002754 if oldLeader:
2755 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002756 utilities.assert_equals(
2757 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002758 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002759 onpass="Node was withdrawn from election",
2760 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002761
Jon Hall6aec96b2015-01-19 14:49:31 -08002762 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002763 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002764 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002765 for cli in CLIs:
2766 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002767 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002768 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002769 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002770 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002771 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002772 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002773 # error in response
2774 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002775 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002776 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002777 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002778 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002779 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002780 elif leaderN is None:
2781 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002782 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002783 leaderN = cli.electionTestLeader()
2784 leaderList.pop()
2785 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002786 consistentLeader = main.FALSE
2787 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002788 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002789 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002790 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002791 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002792 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002793 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002794 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002795 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002796 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002797 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002798 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002799 utilities.assert_equals(
2800 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002801 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002802 onpass="Leadership election passed",
2803 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002804
Jon Hall58c76b72015-02-23 11:09:24 -08002805 main.step( "Run for election on old leader( just so everyone " +
2806 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002807 if oldLeader:
2808 runResult = oldLeader.electionTestRun()
2809 else:
2810 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002811 utilities.assert_equals(
2812 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002813 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002814 onpass="App re-ran for election",
2815 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002816
Jon Hallfeff3082015-05-19 10:23:26 -07002817 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002818 afterRun = main.ONOScli1.electionTestLeader()
2819 # verify leader didn't just change
2820 if afterRun == leaderList[ 0 ]:
2821 afterResult = main.TRUE
2822 else:
2823 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002824
Jon Hall6aec96b2015-01-19 14:49:31 -08002825 utilities.assert_equals(
2826 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002827 actual=afterResult,
2828 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002829 onfail="Something went wrong with Leadership election after " +
2830 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002831
Jon Hall390696c2015-05-05 17:13:41 -07002832 def CASE16( self, main ):
2833 """
2834 Install Distributed Primitives app
2835 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002836 import time
Jon Hall390696c2015-05-05 17:13:41 -07002837 assert numControllers, "numControllers not defined"
2838 assert main, "main not defined"
2839 assert utilities.assert_equals, "utilities.assert_equals not defined"
2840 assert CLIs, "CLIs not defined"
2841 assert nodes, "nodes not defined"
2842
2843 # Variables for the distributed primitives tests
2844 global pCounterName
2845 global iCounterName
2846 global pCounterValue
2847 global iCounterValue
2848 global onosSet
2849 global onosSetName
2850 pCounterName = "TestON-Partitions"
2851 iCounterName = "TestON-inMemory"
2852 pCounterValue = 0
2853 iCounterValue = 0
2854 onosSet = set([])
2855 onosSetName = "TestON-set"
2856
2857 description = "Install Primitives app"
2858 main.case( description )
2859 main.step( "Install Primitives app" )
2860 appName = "org.onosproject.distributedprimitives"
2861 appResults = CLIs[0].activateApp( appName )
2862 utilities.assert_equals( expect=main.TRUE,
2863 actual=appResults,
2864 onpass="Primitives app activated",
2865 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002866 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002867
2868 def CASE17( self, main ):
2869 """
2870 Check for basic functionality with distributed primitives
2871 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002872 import json
Jon Hall390696c2015-05-05 17:13:41 -07002873 # Make sure variables are defined/set
2874 assert numControllers, "numControllers not defined"
2875 assert main, "main not defined"
2876 assert utilities.assert_equals, "utilities.assert_equals not defined"
2877 assert CLIs, "CLIs not defined"
2878 assert nodes, "nodes not defined"
2879 assert pCounterName, "pCounterName not defined"
2880 assert iCounterName, "iCounterName not defined"
2881 assert onosSetName, "onosSetName not defined"
2882 # NOTE: assert fails if value is 0/None/Empty/False
2883 try:
2884 pCounterValue
2885 except NameError:
2886 main.log.error( "pCounterValue not defined, setting to 0" )
2887 pCounterValue = 0
2888 try:
2889 iCounterValue
2890 except NameError:
2891 main.log.error( "iCounterValue not defined, setting to 0" )
2892 iCounterValue = 0
2893 try:
2894 onosSet
2895 except NameError:
2896 main.log.error( "onosSet not defined, setting to empty Set" )
2897 onosSet = set([])
2898 # Variables for the distributed primitives tests. These are local only
2899 addValue = "a"
2900 addAllValue = "a b c d e f"
2901 retainValue = "c d e f"
2902
2903 description = "Check for basic functionality with distributed " +\
2904 "primitives"
2905 main.case( description )
2906 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2907 # DISTRIBUTED ATOMIC COUNTERS
2908 main.step( "Increment and get a default counter on each node" )
2909 pCounters = []
2910 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002911 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002912 for i in range( numControllers ):
2913 t = main.Thread( target=CLIs[i].counterTestIncrement,
2914 name="counterIncrement-" + str( i ),
2915 args=[ pCounterName ] )
2916 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002917 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002918 threads.append( t )
2919 t.start()
2920
2921 for t in threads:
2922 t.join()
2923 pCounters.append( t.result )
2924 # Check that counter incremented numController times
2925 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002926 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002927 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002928 pCounterResults = pCounterResults and tmpResult
2929 if not tmpResult:
2930 main.log.error( str( i ) + " is not in partitioned "
2931 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002932 utilities.assert_equals( expect=True,
2933 actual=pCounterResults,
2934 onpass="Default counter incremented",
2935 onfail="Error incrementing default" +
2936 " counter" )
2937
2938 main.step( "Increment and get an in memory counter on each node" )
2939 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002940 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002941 threads = []
2942 for i in range( numControllers ):
2943 t = main.Thread( target=CLIs[i].counterTestIncrement,
2944 name="icounterIncrement-" + str( i ),
2945 args=[ iCounterName ],
2946 kwargs={ "inMemory": True } )
2947 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002948 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002949 threads.append( t )
2950 t.start()
2951
2952 for t in threads:
2953 t.join()
2954 iCounters.append( t.result )
2955 # Check that counter incremented numController times
2956 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002957 for i in addedIValues:
2958 tmpResult = i in iCounters
2959 iCounterResults = iCounterResults and tmpResult
2960 if not tmpResult:
2961 main.log.error( str( i ) + " is not in the in-memory "
2962 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002963 utilities.assert_equals( expect=True,
2964 actual=iCounterResults,
2965 onpass="In memory counter incremented",
2966 onfail="Error incrementing in memory" +
2967 " counter" )
2968
2969 main.step( "Check counters are consistant across nodes" )
2970 onosCounters = []
2971 threads = []
2972 for i in range( numControllers ):
2973 t = main.Thread( target=CLIs[i].counters,
2974 name="counters-" + str( i ) )
2975 threads.append( t )
2976 t.start()
2977 for t in threads:
2978 t.join()
2979 onosCounters.append( t.result )
2980 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2981 if all( tmp ):
2982 main.log.info( "Counters are consistent across all nodes" )
2983 consistentCounterResults = main.TRUE
2984 else:
2985 main.log.error( "Counters are not consistent across all nodes" )
2986 consistentCounterResults = main.FALSE
2987 utilities.assert_equals( expect=main.TRUE,
2988 actual=consistentCounterResults,
2989 onpass="ONOS counters are consistent " +
2990 "across nodes",
2991 onfail="ONOS Counters are inconsistent " +
2992 "across nodes" )
2993
2994 main.step( "Counters we added have the correct values" )
2995 correctResults = main.TRUE
2996 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002997 current = json.loads( onosCounters[i] )
2998 pValue = None
2999 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003000 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003001 for database in current:
3002 partitioned = database.get( 'partitionedDatabaseCounters' )
3003 if partitioned:
3004 for value in partitioned:
3005 if value.get( 'name' ) == pCounterName:
3006 pValue = value.get( 'value' )
3007 break
3008 inMemory = database.get( 'inMemoryDatabaseCounters' )
3009 if inMemory:
3010 for value in inMemory:
3011 if value.get( 'name' ) == iCounterName:
3012 iValue = value.get( 'value' )
3013 break
Jon Hall390696c2015-05-05 17:13:41 -07003014 except AttributeError, e:
3015 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3016 "is not as expected" )
3017 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003018 if pValue == pCounterValue:
3019 main.log.info( "Partitioned counter value is correct" )
3020 else:
3021 main.log.error( "Partitioned counter value is incorrect," +
3022 " expected value: " + str( pCounterValue )
3023 + " current value: " + str( pValue ) )
3024 correctResults = main.FALSE
3025 if iValue == iCounterValue:
3026 main.log.info( "In memory counter value is correct" )
3027 else:
3028 main.log.error( "In memory counter value is incorrect, " +
3029 "expected value: " + str( iCounterValue ) +
3030 " current value: " + str( iValue ) )
3031 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003032 utilities.assert_equals( expect=main.TRUE,
3033 actual=correctResults,
3034 onpass="Added counters are correct",
3035 onfail="Added counters are incorrect" )
3036 # DISTRIBUTED SETS
3037 main.step( "Distributed Set get" )
3038 size = len( onosSet )
3039 getResponses = []
3040 threads = []
3041 for i in range( numControllers ):
3042 t = main.Thread( target=CLIs[i].setTestGet,
3043 name="setTestGet-" + str( i ),
3044 args=[ onosSetName ] )
3045 threads.append( t )
3046 t.start()
3047 for t in threads:
3048 t.join()
3049 getResponses.append( t.result )
3050
3051 getResults = main.TRUE
3052 for i in range( numControllers ):
3053 if isinstance( getResponses[ i ], list):
3054 current = set( getResponses[ i ] )
3055 if len( current ) == len( getResponses[ i ] ):
3056 # no repeats
3057 if onosSet != current:
3058 main.log.error( "ONOS" + str( i + 1 ) +
3059 " has incorrect view" +
3060 " of set " + onosSetName + ":\n" +
3061 str( getResponses[ i ] ) )
3062 main.log.debug( "Expected: " + str( onosSet ) )
3063 main.log.debug( "Actual: " + str( current ) )
3064 getResults = main.FALSE
3065 else:
3066 # error, set is not a set
3067 main.log.error( "ONOS" + str( i + 1 ) +
3068 " has repeat elements in" +
3069 " set " + onosSetName + ":\n" +
3070 str( getResponses[ i ] ) )
3071 getResults = main.FALSE
3072 elif getResponses[ i ] == main.ERROR:
3073 getResults = main.FALSE
3074 utilities.assert_equals( expect=main.TRUE,
3075 actual=getResults,
3076 onpass="Set elements are correct",
3077 onfail="Set elements are incorrect" )
3078
3079 main.step( "Distributed Set size" )
3080 sizeResponses = []
3081 threads = []
3082 for i in range( numControllers ):
3083 t = main.Thread( target=CLIs[i].setTestSize,
3084 name="setTestSize-" + str( i ),
3085 args=[ onosSetName ] )
3086 threads.append( t )
3087 t.start()
3088 for t in threads:
3089 t.join()
3090 sizeResponses.append( t.result )
3091
3092 sizeResults = main.TRUE
3093 for i in range( numControllers ):
3094 if size != sizeResponses[ i ]:
3095 sizeResults = main.FALSE
3096 main.log.error( "ONOS" + str( i + 1 ) +
3097 " expected a size of " + str( size ) +
3098 " for set " + onosSetName +
3099 " but got " + str( sizeResponses[ i ] ) )
3100 utilities.assert_equals( expect=main.TRUE,
3101 actual=sizeResults,
3102 onpass="Set sizes are correct",
3103 onfail="Set sizes are incorrect" )
3104
3105 main.step( "Distributed Set add()" )
3106 onosSet.add( addValue )
3107 addResponses = []
3108 threads = []
3109 for i in range( numControllers ):
3110 t = main.Thread( target=CLIs[i].setTestAdd,
3111 name="setTestAdd-" + str( i ),
3112 args=[ onosSetName, addValue ] )
3113 threads.append( t )
3114 t.start()
3115 for t in threads:
3116 t.join()
3117 addResponses.append( t.result )
3118
3119 # main.TRUE = successfully changed the set
3120 # main.FALSE = action resulted in no change in set
3121 # main.ERROR - Some error in executing the function
3122 addResults = main.TRUE
3123 for i in range( numControllers ):
3124 if addResponses[ i ] == main.TRUE:
3125 # All is well
3126 pass
3127 elif addResponses[ i ] == main.FALSE:
3128 # Already in set, probably fine
3129 pass
3130 elif addResponses[ i ] == main.ERROR:
3131 # Error in execution
3132 addResults = main.FALSE
3133 else:
3134 # unexpected result
3135 addResults = main.FALSE
3136 if addResults != main.TRUE:
3137 main.log.error( "Error executing set add" )
3138
3139 # Check if set is still correct
3140 size = len( onosSet )
3141 getResponses = []
3142 threads = []
3143 for i in range( numControllers ):
3144 t = main.Thread( target=CLIs[i].setTestGet,
3145 name="setTestGet-" + str( i ),
3146 args=[ onosSetName ] )
3147 threads.append( t )
3148 t.start()
3149 for t in threads:
3150 t.join()
3151 getResponses.append( t.result )
3152 getResults = main.TRUE
3153 for i in range( numControllers ):
3154 if isinstance( getResponses[ i ], list):
3155 current = set( getResponses[ i ] )
3156 if len( current ) == len( getResponses[ i ] ):
3157 # no repeats
3158 if onosSet != current:
3159 main.log.error( "ONOS" + str( i + 1 ) +
3160 " has incorrect view" +
3161 " of set " + onosSetName + ":\n" +
3162 str( getResponses[ i ] ) )
3163 main.log.debug( "Expected: " + str( onosSet ) )
3164 main.log.debug( "Actual: " + str( current ) )
3165 getResults = main.FALSE
3166 else:
3167 # error, set is not a set
3168 main.log.error( "ONOS" + str( i + 1 ) +
3169 " has repeat elements in" +
3170 " set " + onosSetName + ":\n" +
3171 str( getResponses[ i ] ) )
3172 getResults = main.FALSE
3173 elif getResponses[ i ] == main.ERROR:
3174 getResults = main.FALSE
3175 sizeResponses = []
3176 threads = []
3177 for i in range( numControllers ):
3178 t = main.Thread( target=CLIs[i].setTestSize,
3179 name="setTestSize-" + str( i ),
3180 args=[ onosSetName ] )
3181 threads.append( t )
3182 t.start()
3183 for t in threads:
3184 t.join()
3185 sizeResponses.append( t.result )
3186 sizeResults = main.TRUE
3187 for i in range( numControllers ):
3188 if size != sizeResponses[ i ]:
3189 sizeResults = main.FALSE
3190 main.log.error( "ONOS" + str( i + 1 ) +
3191 " expected a size of " + str( size ) +
3192 " for set " + onosSetName +
3193 " but got " + str( sizeResponses[ i ] ) )
3194 addResults = addResults and getResults and sizeResults
3195 utilities.assert_equals( expect=main.TRUE,
3196 actual=addResults,
3197 onpass="Set add correct",
3198 onfail="Set add was incorrect" )
3199
3200 main.step( "Distributed Set addAll()" )
3201 onosSet.update( addAllValue.split() )
3202 addResponses = []
3203 threads = []
3204 for i in range( numControllers ):
3205 t = main.Thread( target=CLIs[i].setTestAdd,
3206 name="setTestAddAll-" + str( i ),
3207 args=[ onosSetName, addAllValue ] )
3208 threads.append( t )
3209 t.start()
3210 for t in threads:
3211 t.join()
3212 addResponses.append( t.result )
3213
3214 # main.TRUE = successfully changed the set
3215 # main.FALSE = action resulted in no change in set
3216 # main.ERROR - Some error in executing the function
3217 addAllResults = main.TRUE
3218 for i in range( numControllers ):
3219 if addResponses[ i ] == main.TRUE:
3220 # All is well
3221 pass
3222 elif addResponses[ i ] == main.FALSE:
3223 # Already in set, probably fine
3224 pass
3225 elif addResponses[ i ] == main.ERROR:
3226 # Error in execution
3227 addAllResults = main.FALSE
3228 else:
3229 # unexpected result
3230 addAllResults = main.FALSE
3231 if addAllResults != main.TRUE:
3232 main.log.error( "Error executing set addAll" )
3233
3234 # Check if set is still correct
3235 size = len( onosSet )
3236 getResponses = []
3237 threads = []
3238 for i in range( numControllers ):
3239 t = main.Thread( target=CLIs[i].setTestGet,
3240 name="setTestGet-" + str( i ),
3241 args=[ onosSetName ] )
3242 threads.append( t )
3243 t.start()
3244 for t in threads:
3245 t.join()
3246 getResponses.append( t.result )
3247 getResults = main.TRUE
3248 for i in range( numControllers ):
3249 if isinstance( getResponses[ i ], list):
3250 current = set( getResponses[ i ] )
3251 if len( current ) == len( getResponses[ i ] ):
3252 # no repeats
3253 if onosSet != current:
3254 main.log.error( "ONOS" + str( i + 1 ) +
3255 " has incorrect view" +
3256 " of set " + onosSetName + ":\n" +
3257 str( getResponses[ i ] ) )
3258 main.log.debug( "Expected: " + str( onosSet ) )
3259 main.log.debug( "Actual: " + str( current ) )
3260 getResults = main.FALSE
3261 else:
3262 # error, set is not a set
3263 main.log.error( "ONOS" + str( i + 1 ) +
3264 " has repeat elements in" +
3265 " set " + onosSetName + ":\n" +
3266 str( getResponses[ i ] ) )
3267 getResults = main.FALSE
3268 elif getResponses[ i ] == main.ERROR:
3269 getResults = main.FALSE
3270 sizeResponses = []
3271 threads = []
3272 for i in range( numControllers ):
3273 t = main.Thread( target=CLIs[i].setTestSize,
3274 name="setTestSize-" + str( i ),
3275 args=[ onosSetName ] )
3276 threads.append( t )
3277 t.start()
3278 for t in threads:
3279 t.join()
3280 sizeResponses.append( t.result )
3281 sizeResults = main.TRUE
3282 for i in range( numControllers ):
3283 if size != sizeResponses[ i ]:
3284 sizeResults = main.FALSE
3285 main.log.error( "ONOS" + str( i + 1 ) +
3286 " expected a size of " + str( size ) +
3287 " for set " + onosSetName +
3288 " but got " + str( sizeResponses[ i ] ) )
3289 addAllResults = addAllResults and getResults and sizeResults
3290 utilities.assert_equals( expect=main.TRUE,
3291 actual=addAllResults,
3292 onpass="Set addAll correct",
3293 onfail="Set addAll was incorrect" )
3294
3295 main.step( "Distributed Set contains()" )
3296 containsResponses = []
3297 threads = []
3298 for i in range( numControllers ):
3299 t = main.Thread( target=CLIs[i].setTestGet,
3300 name="setContains-" + str( i ),
3301 args=[ onosSetName ],
3302 kwargs={ "values": addValue } )
3303 threads.append( t )
3304 t.start()
3305 for t in threads:
3306 t.join()
3307 # NOTE: This is the tuple
3308 containsResponses.append( t.result )
3309
3310 containsResults = main.TRUE
3311 for i in range( numControllers ):
3312 if containsResponses[ i ] == main.ERROR:
3313 containsResults = main.FALSE
3314 else:
3315 containsResults = containsResults and\
3316 containsResponses[ i ][ 1 ]
3317 utilities.assert_equals( expect=main.TRUE,
3318 actual=containsResults,
3319 onpass="Set contains is functional",
3320 onfail="Set contains failed" )
3321
3322 main.step( "Distributed Set containsAll()" )
3323 containsAllResponses = []
3324 threads = []
3325 for i in range( numControllers ):
3326 t = main.Thread( target=CLIs[i].setTestGet,
3327 name="setContainsAll-" + str( i ),
3328 args=[ onosSetName ],
3329 kwargs={ "values": addAllValue } )
3330 threads.append( t )
3331 t.start()
3332 for t in threads:
3333 t.join()
3334 # NOTE: This is the tuple
3335 containsAllResponses.append( t.result )
3336
3337 containsAllResults = main.TRUE
3338 for i in range( numControllers ):
3339 if containsResponses[ i ] == main.ERROR:
3340 containsResults = main.FALSE
3341 else:
3342 containsResults = containsResults and\
3343 containsResponses[ i ][ 1 ]
3344 utilities.assert_equals( expect=main.TRUE,
3345 actual=containsAllResults,
3346 onpass="Set containsAll is functional",
3347 onfail="Set containsAll failed" )
3348
3349 main.step( "Distributed Set remove()" )
3350 onosSet.remove( addValue )
3351 removeResponses = []
3352 threads = []
3353 for i in range( numControllers ):
3354 t = main.Thread( target=CLIs[i].setTestRemove,
3355 name="setTestRemove-" + str( i ),
3356 args=[ onosSetName, addValue ] )
3357 threads.append( t )
3358 t.start()
3359 for t in threads:
3360 t.join()
3361 removeResponses.append( t.result )
3362
3363 # main.TRUE = successfully changed the set
3364 # main.FALSE = action resulted in no change in set
3365 # main.ERROR - Some error in executing the function
3366 removeResults = main.TRUE
3367 for i in range( numControllers ):
3368 if removeResponses[ i ] == main.TRUE:
3369 # All is well
3370 pass
3371 elif removeResponses[ i ] == main.FALSE:
3372 # not in set, probably fine
3373 pass
3374 elif removeResponses[ i ] == main.ERROR:
3375 # Error in execution
3376 removeResults = main.FALSE
3377 else:
3378 # unexpected result
3379 removeResults = main.FALSE
3380 if removeResults != main.TRUE:
3381 main.log.error( "Error executing set remove" )
3382
3383 # Check if set is still correct
3384 size = len( onosSet )
3385 getResponses = []
3386 threads = []
3387 for i in range( numControllers ):
3388 t = main.Thread( target=CLIs[i].setTestGet,
3389 name="setTestGet-" + str( i ),
3390 args=[ onosSetName ] )
3391 threads.append( t )
3392 t.start()
3393 for t in threads:
3394 t.join()
3395 getResponses.append( t.result )
3396 getResults = main.TRUE
3397 for i in range( numControllers ):
3398 if isinstance( getResponses[ i ], list):
3399 current = set( getResponses[ i ] )
3400 if len( current ) == len( getResponses[ i ] ):
3401 # no repeats
3402 if onosSet != current:
3403 main.log.error( "ONOS" + str( i + 1 ) +
3404 " has incorrect view" +
3405 " of set " + onosSetName + ":\n" +
3406 str( getResponses[ i ] ) )
3407 main.log.debug( "Expected: " + str( onosSet ) )
3408 main.log.debug( "Actual: " + str( current ) )
3409 getResults = main.FALSE
3410 else:
3411 # error, set is not a set
3412 main.log.error( "ONOS" + str( i + 1 ) +
3413 " has repeat elements in" +
3414 " set " + onosSetName + ":\n" +
3415 str( getResponses[ i ] ) )
3416 getResults = main.FALSE
3417 elif getResponses[ i ] == main.ERROR:
3418 getResults = main.FALSE
3419 sizeResponses = []
3420 threads = []
3421 for i in range( numControllers ):
3422 t = main.Thread( target=CLIs[i].setTestSize,
3423 name="setTestSize-" + str( i ),
3424 args=[ onosSetName ] )
3425 threads.append( t )
3426 t.start()
3427 for t in threads:
3428 t.join()
3429 sizeResponses.append( t.result )
3430 sizeResults = main.TRUE
3431 for i in range( numControllers ):
3432 if size != sizeResponses[ i ]:
3433 sizeResults = main.FALSE
3434 main.log.error( "ONOS" + str( i + 1 ) +
3435 " expected a size of " + str( size ) +
3436 " for set " + onosSetName +
3437 " but got " + str( sizeResponses[ i ] ) )
3438 removeResults = removeResults and getResults and sizeResults
3439 utilities.assert_equals( expect=main.TRUE,
3440 actual=removeResults,
3441 onpass="Set remove correct",
3442 onfail="Set remove was incorrect" )
3443
3444 main.step( "Distributed Set removeAll()" )
3445 onosSet.difference_update( addAllValue.split() )
3446 removeAllResponses = []
3447 threads = []
3448 try:
3449 for i in range( numControllers ):
3450 t = main.Thread( target=CLIs[i].setTestRemove,
3451 name="setTestRemoveAll-" + str( i ),
3452 args=[ onosSetName, addAllValue ] )
3453 threads.append( t )
3454 t.start()
3455 for t in threads:
3456 t.join()
3457 removeAllResponses.append( t.result )
3458 except Exception, e:
3459 main.log.exception(e)
3460
3461 # main.TRUE = successfully changed the set
3462 # main.FALSE = action resulted in no change in set
3463 # main.ERROR - Some error in executing the function
3464 removeAllResults = main.TRUE
3465 for i in range( numControllers ):
3466 if removeAllResponses[ i ] == main.TRUE:
3467 # All is well
3468 pass
3469 elif removeAllResponses[ i ] == main.FALSE:
3470 # not in set, probably fine
3471 pass
3472 elif removeAllResponses[ i ] == main.ERROR:
3473 # Error in execution
3474 removeAllResults = main.FALSE
3475 else:
3476 # unexpected result
3477 removeAllResults = main.FALSE
3478 if removeAllResults != main.TRUE:
3479 main.log.error( "Error executing set removeAll" )
3480
3481 # Check if set is still correct
3482 size = len( onosSet )
3483 getResponses = []
3484 threads = []
3485 for i in range( numControllers ):
3486 t = main.Thread( target=CLIs[i].setTestGet,
3487 name="setTestGet-" + str( i ),
3488 args=[ onosSetName ] )
3489 threads.append( t )
3490 t.start()
3491 for t in threads:
3492 t.join()
3493 getResponses.append( t.result )
3494 getResults = main.TRUE
3495 for i in range( numControllers ):
3496 if isinstance( getResponses[ i ], list):
3497 current = set( getResponses[ i ] )
3498 if len( current ) == len( getResponses[ i ] ):
3499 # no repeats
3500 if onosSet != current:
3501 main.log.error( "ONOS" + str( i + 1 ) +
3502 " has incorrect view" +
3503 " of set " + onosSetName + ":\n" +
3504 str( getResponses[ i ] ) )
3505 main.log.debug( "Expected: " + str( onosSet ) )
3506 main.log.debug( "Actual: " + str( current ) )
3507 getResults = main.FALSE
3508 else:
3509 # error, set is not a set
3510 main.log.error( "ONOS" + str( i + 1 ) +
3511 " has repeat elements in" +
3512 " set " + onosSetName + ":\n" +
3513 str( getResponses[ i ] ) )
3514 getResults = main.FALSE
3515 elif getResponses[ i ] == main.ERROR:
3516 getResults = main.FALSE
3517 sizeResponses = []
3518 threads = []
3519 for i in range( numControllers ):
3520 t = main.Thread( target=CLIs[i].setTestSize,
3521 name="setTestSize-" + str( i ),
3522 args=[ onosSetName ] )
3523 threads.append( t )
3524 t.start()
3525 for t in threads:
3526 t.join()
3527 sizeResponses.append( t.result )
3528 sizeResults = main.TRUE
3529 for i in range( numControllers ):
3530 if size != sizeResponses[ i ]:
3531 sizeResults = main.FALSE
3532 main.log.error( "ONOS" + str( i + 1 ) +
3533 " expected a size of " + str( size ) +
3534 " for set " + onosSetName +
3535 " but got " + str( sizeResponses[ i ] ) )
3536 removeAllResults = removeAllResults and getResults and sizeResults
3537 utilities.assert_equals( expect=main.TRUE,
3538 actual=removeAllResults,
3539 onpass="Set removeAll correct",
3540 onfail="Set removeAll was incorrect" )
3541
3542 main.step( "Distributed Set addAll()" )
3543 onosSet.update( addAllValue.split() )
3544 addResponses = []
3545 threads = []
3546 for i in range( numControllers ):
3547 t = main.Thread( target=CLIs[i].setTestAdd,
3548 name="setTestAddAll-" + str( i ),
3549 args=[ onosSetName, addAllValue ] )
3550 threads.append( t )
3551 t.start()
3552 for t in threads:
3553 t.join()
3554 addResponses.append( t.result )
3555
3556 # main.TRUE = successfully changed the set
3557 # main.FALSE = action resulted in no change in set
3558 # main.ERROR - Some error in executing the function
3559 addAllResults = main.TRUE
3560 for i in range( numControllers ):
3561 if addResponses[ i ] == main.TRUE:
3562 # All is well
3563 pass
3564 elif addResponses[ i ] == main.FALSE:
3565 # Already in set, probably fine
3566 pass
3567 elif addResponses[ i ] == main.ERROR:
3568 # Error in execution
3569 addAllResults = main.FALSE
3570 else:
3571 # unexpected result
3572 addAllResults = main.FALSE
3573 if addAllResults != main.TRUE:
3574 main.log.error( "Error executing set addAll" )
3575
3576 # Check if set is still correct
3577 size = len( onosSet )
3578 getResponses = []
3579 threads = []
3580 for i in range( numControllers ):
3581 t = main.Thread( target=CLIs[i].setTestGet,
3582 name="setTestGet-" + str( i ),
3583 args=[ onosSetName ] )
3584 threads.append( t )
3585 t.start()
3586 for t in threads:
3587 t.join()
3588 getResponses.append( t.result )
3589 getResults = main.TRUE
3590 for i in range( numControllers ):
3591 if isinstance( getResponses[ i ], list):
3592 current = set( getResponses[ i ] )
3593 if len( current ) == len( getResponses[ i ] ):
3594 # no repeats
3595 if onosSet != current:
3596 main.log.error( "ONOS" + str( i + 1 ) +
3597 " has incorrect view" +
3598 " of set " + onosSetName + ":\n" +
3599 str( getResponses[ i ] ) )
3600 main.log.debug( "Expected: " + str( onosSet ) )
3601 main.log.debug( "Actual: " + str( current ) )
3602 getResults = main.FALSE
3603 else:
3604 # error, set is not a set
3605 main.log.error( "ONOS" + str( i + 1 ) +
3606 " has repeat elements in" +
3607 " set " + onosSetName + ":\n" +
3608 str( getResponses[ i ] ) )
3609 getResults = main.FALSE
3610 elif getResponses[ i ] == main.ERROR:
3611 getResults = main.FALSE
3612 sizeResponses = []
3613 threads = []
3614 for i in range( numControllers ):
3615 t = main.Thread( target=CLIs[i].setTestSize,
3616 name="setTestSize-" + str( i ),
3617 args=[ onosSetName ] )
3618 threads.append( t )
3619 t.start()
3620 for t in threads:
3621 t.join()
3622 sizeResponses.append( t.result )
3623 sizeResults = main.TRUE
3624 for i in range( numControllers ):
3625 if size != sizeResponses[ i ]:
3626 sizeResults = main.FALSE
3627 main.log.error( "ONOS" + str( i + 1 ) +
3628 " expected a size of " + str( size ) +
3629 " for set " + onosSetName +
3630 " but got " + str( sizeResponses[ i ] ) )
3631 addAllResults = addAllResults and getResults and sizeResults
3632 utilities.assert_equals( expect=main.TRUE,
3633 actual=addAllResults,
3634 onpass="Set addAll correct",
3635 onfail="Set addAll was incorrect" )
3636
3637 main.step( "Distributed Set clear()" )
3638 onosSet.clear()
3639 clearResponses = []
3640 threads = []
3641 for i in range( numControllers ):
3642 t = main.Thread( target=CLIs[i].setTestRemove,
3643 name="setTestClear-" + str( i ),
3644 args=[ onosSetName, " "], # Values doesn't matter
3645 kwargs={ "clear": True } )
3646 threads.append( t )
3647 t.start()
3648 for t in threads:
3649 t.join()
3650 clearResponses.append( t.result )
3651
3652 # main.TRUE = successfully changed the set
3653 # main.FALSE = action resulted in no change in set
3654 # main.ERROR - Some error in executing the function
3655 clearResults = main.TRUE
3656 for i in range( numControllers ):
3657 if clearResponses[ i ] == main.TRUE:
3658 # All is well
3659 pass
3660 elif clearResponses[ i ] == main.FALSE:
3661 # Nothing set, probably fine
3662 pass
3663 elif clearResponses[ i ] == main.ERROR:
3664 # Error in execution
3665 clearResults = main.FALSE
3666 else:
3667 # unexpected result
3668 clearResults = main.FALSE
3669 if clearResults != main.TRUE:
3670 main.log.error( "Error executing set clear" )
3671
3672 # Check if set is still correct
3673 size = len( onosSet )
3674 getResponses = []
3675 threads = []
3676 for i in range( numControllers ):
3677 t = main.Thread( target=CLIs[i].setTestGet,
3678 name="setTestGet-" + str( i ),
3679 args=[ onosSetName ] )
3680 threads.append( t )
3681 t.start()
3682 for t in threads:
3683 t.join()
3684 getResponses.append( t.result )
3685 getResults = main.TRUE
3686 for i in range( numControllers ):
3687 if isinstance( getResponses[ i ], list):
3688 current = set( getResponses[ i ] )
3689 if len( current ) == len( getResponses[ i ] ):
3690 # no repeats
3691 if onosSet != current:
3692 main.log.error( "ONOS" + str( i + 1 ) +
3693 " has incorrect view" +
3694 " of set " + onosSetName + ":\n" +
3695 str( getResponses[ i ] ) )
3696 main.log.debug( "Expected: " + str( onosSet ) )
3697 main.log.debug( "Actual: " + str( current ) )
3698 getResults = main.FALSE
3699 else:
3700 # error, set is not a set
3701 main.log.error( "ONOS" + str( i + 1 ) +
3702 " has repeat elements in" +
3703 " set " + onosSetName + ":\n" +
3704 str( getResponses[ i ] ) )
3705 getResults = main.FALSE
3706 elif getResponses[ i ] == main.ERROR:
3707 getResults = main.FALSE
3708 sizeResponses = []
3709 threads = []
3710 for i in range( numControllers ):
3711 t = main.Thread( target=CLIs[i].setTestSize,
3712 name="setTestSize-" + str( i ),
3713 args=[ onosSetName ] )
3714 threads.append( t )
3715 t.start()
3716 for t in threads:
3717 t.join()
3718 sizeResponses.append( t.result )
3719 sizeResults = main.TRUE
3720 for i in range( numControllers ):
3721 if size != sizeResponses[ i ]:
3722 sizeResults = main.FALSE
3723 main.log.error( "ONOS" + str( i + 1 ) +
3724 " expected a size of " + str( size ) +
3725 " for set " + onosSetName +
3726 " but got " + str( sizeResponses[ i ] ) )
3727 clearResults = clearResults and getResults and sizeResults
3728 utilities.assert_equals( expect=main.TRUE,
3729 actual=clearResults,
3730 onpass="Set clear correct",
3731 onfail="Set clear was incorrect" )
3732
3733 main.step( "Distributed Set addAll()" )
3734 onosSet.update( addAllValue.split() )
3735 addResponses = []
3736 threads = []
3737 for i in range( numControllers ):
3738 t = main.Thread( target=CLIs[i].setTestAdd,
3739 name="setTestAddAll-" + str( i ),
3740 args=[ onosSetName, addAllValue ] )
3741 threads.append( t )
3742 t.start()
3743 for t in threads:
3744 t.join()
3745 addResponses.append( t.result )
3746
3747 # main.TRUE = successfully changed the set
3748 # main.FALSE = action resulted in no change in set
3749 # main.ERROR - Some error in executing the function
3750 addAllResults = main.TRUE
3751 for i in range( numControllers ):
3752 if addResponses[ i ] == main.TRUE:
3753 # All is well
3754 pass
3755 elif addResponses[ i ] == main.FALSE:
3756 # Already in set, probably fine
3757 pass
3758 elif addResponses[ i ] == main.ERROR:
3759 # Error in execution
3760 addAllResults = main.FALSE
3761 else:
3762 # unexpected result
3763 addAllResults = main.FALSE
3764 if addAllResults != main.TRUE:
3765 main.log.error( "Error executing set addAll" )
3766
3767 # Check if set is still correct
3768 size = len( onosSet )
3769 getResponses = []
3770 threads = []
3771 for i in range( numControllers ):
3772 t = main.Thread( target=CLIs[i].setTestGet,
3773 name="setTestGet-" + str( i ),
3774 args=[ onosSetName ] )
3775 threads.append( t )
3776 t.start()
3777 for t in threads:
3778 t.join()
3779 getResponses.append( t.result )
3780 getResults = main.TRUE
3781 for i in range( numControllers ):
3782 if isinstance( getResponses[ i ], list):
3783 current = set( getResponses[ i ] )
3784 if len( current ) == len( getResponses[ i ] ):
3785 # no repeats
3786 if onosSet != current:
3787 main.log.error( "ONOS" + str( i + 1 ) +
3788 " has incorrect view" +
3789 " of set " + onosSetName + ":\n" +
3790 str( getResponses[ i ] ) )
3791 main.log.debug( "Expected: " + str( onosSet ) )
3792 main.log.debug( "Actual: " + str( current ) )
3793 getResults = main.FALSE
3794 else:
3795 # error, set is not a set
3796 main.log.error( "ONOS" + str( i + 1 ) +
3797 " has repeat elements in" +
3798 " set " + onosSetName + ":\n" +
3799 str( getResponses[ i ] ) )
3800 getResults = main.FALSE
3801 elif getResponses[ i ] == main.ERROR:
3802 getResults = main.FALSE
3803 sizeResponses = []
3804 threads = []
3805 for i in range( numControllers ):
3806 t = main.Thread( target=CLIs[i].setTestSize,
3807 name="setTestSize-" + str( i ),
3808 args=[ onosSetName ] )
3809 threads.append( t )
3810 t.start()
3811 for t in threads:
3812 t.join()
3813 sizeResponses.append( t.result )
3814 sizeResults = main.TRUE
3815 for i in range( numControllers ):
3816 if size != sizeResponses[ i ]:
3817 sizeResults = main.FALSE
3818 main.log.error( "ONOS" + str( i + 1 ) +
3819 " expected a size of " + str( size ) +
3820 " for set " + onosSetName +
3821 " but got " + str( sizeResponses[ i ] ) )
3822 addAllResults = addAllResults and getResults and sizeResults
3823 utilities.assert_equals( expect=main.TRUE,
3824 actual=addAllResults,
3825 onpass="Set addAll correct",
3826 onfail="Set addAll was incorrect" )
3827
3828 main.step( "Distributed Set retain()" )
3829 onosSet.intersection_update( retainValue.split() )
3830 retainResponses = []
3831 threads = []
3832 for i in range( numControllers ):
3833 t = main.Thread( target=CLIs[i].setTestRemove,
3834 name="setTestRetain-" + str( i ),
3835 args=[ onosSetName, retainValue ],
3836 kwargs={ "retain": True } )
3837 threads.append( t )
3838 t.start()
3839 for t in threads:
3840 t.join()
3841 retainResponses.append( t.result )
3842
3843 # main.TRUE = successfully changed the set
3844 # main.FALSE = action resulted in no change in set
3845 # main.ERROR - Some error in executing the function
3846 retainResults = main.TRUE
3847 for i in range( numControllers ):
3848 if retainResponses[ i ] == main.TRUE:
3849 # All is well
3850 pass
3851 elif retainResponses[ i ] == main.FALSE:
3852 # Already in set, probably fine
3853 pass
3854 elif retainResponses[ i ] == main.ERROR:
3855 # Error in execution
3856 retainResults = main.FALSE
3857 else:
3858 # unexpected result
3859 retainResults = main.FALSE
3860 if retainResults != main.TRUE:
3861 main.log.error( "Error executing set retain" )
3862
3863 # Check if set is still correct
3864 size = len( onosSet )
3865 getResponses = []
3866 threads = []
3867 for i in range( numControllers ):
3868 t = main.Thread( target=CLIs[i].setTestGet,
3869 name="setTestGet-" + str( i ),
3870 args=[ onosSetName ] )
3871 threads.append( t )
3872 t.start()
3873 for t in threads:
3874 t.join()
3875 getResponses.append( t.result )
3876 getResults = main.TRUE
3877 for i in range( numControllers ):
3878 if isinstance( getResponses[ i ], list):
3879 current = set( getResponses[ i ] )
3880 if len( current ) == len( getResponses[ i ] ):
3881 # no repeats
3882 if onosSet != current:
3883 main.log.error( "ONOS" + str( i + 1 ) +
3884 " has incorrect view" +
3885 " of set " + onosSetName + ":\n" +
3886 str( getResponses[ i ] ) )
3887 main.log.debug( "Expected: " + str( onosSet ) )
3888 main.log.debug( "Actual: " + str( current ) )
3889 getResults = main.FALSE
3890 else:
3891 # error, set is not a set
3892 main.log.error( "ONOS" + str( i + 1 ) +
3893 " has repeat elements in" +
3894 " set " + onosSetName + ":\n" +
3895 str( getResponses[ i ] ) )
3896 getResults = main.FALSE
3897 elif getResponses[ i ] == main.ERROR:
3898 getResults = main.FALSE
3899 sizeResponses = []
3900 threads = []
3901 for i in range( numControllers ):
3902 t = main.Thread( target=CLIs[i].setTestSize,
3903 name="setTestSize-" + str( i ),
3904 args=[ onosSetName ] )
3905 threads.append( t )
3906 t.start()
3907 for t in threads:
3908 t.join()
3909 sizeResponses.append( t.result )
3910 sizeResults = main.TRUE
3911 for i in range( numControllers ):
3912 if size != sizeResponses[ i ]:
3913 sizeResults = main.FALSE
3914 main.log.error( "ONOS" + str( i + 1 ) +
3915 " expected a size of " +
3916 str( size ) + " for set " + onosSetName +
3917 " but got " + str( sizeResponses[ i ] ) )
3918 retainResults = retainResults and getResults and sizeResults
3919 utilities.assert_equals( expect=main.TRUE,
3920 actual=retainResults,
3921 onpass="Set retain correct",
3922 onfail="Set retain was incorrect" )
3923