blob: 626d061d9a395f10a42b82180cbaed94744a5157 [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 Hallb6a54872015-06-12 14:02:42 -0700673 main.log.warn( "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( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001408 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001409 threads = []
1410 for i in range( numControllers ):
1411 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001412 name="devices-" + str( i ),
1413 args=[ ] )
1414 threads.append( t )
1415 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001416
1417 for t in threads:
1418 t.join()
1419 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001420 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001421 threads = []
1422 for i in range( numControllers ):
1423 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001424 name="hosts-" + str( i ),
1425 args=[ ] )
1426 threads.append( t )
1427 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001428
1429 for t in threads:
1430 t.join()
1431 try:
1432 hosts.append( json.loads( t.result ) )
1433 except ( ValueError, TypeError ):
1434 # FIXME: better handling of this, print which node
1435 # Maybe use thread name?
1436 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001437 # FIXME: should this be an empty json object instead?
1438 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001439
Jon Hallb1290e82014-11-18 16:17:48 -05001440 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001441 threads = []
1442 for i in range( numControllers ):
1443 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001444 name="ports-" + str( i ),
1445 args=[ ] )
1446 threads.append( t )
1447 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001448
1449 for t in threads:
1450 t.join()
1451 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001452 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001453 threads = []
1454 for i in range( numControllers ):
1455 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001456 name="links-" + str( i ),
1457 args=[ ] )
1458 threads.append( t )
1459 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001460
1461 for t in threads:
1462 t.join()
1463 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001464 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001465 threads = []
1466 for i in range( numControllers ):
1467 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001468 name="clusters-" + str( i ),
1469 args=[ ] )
1470 threads.append( t )
1471 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001472
1473 for t in threads:
1474 t.join()
1475 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001476 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001477
Jon Hall6aec96b2015-01-19 14:49:31 -08001478 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001479 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001480 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001481 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001482 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001483 if "Error" not in hosts[ controller ]:
1484 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001485 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001486 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001487 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001488 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 " is inconsistent with ONOS1" )
1490 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001491 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001492
1493 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001494 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001495 controllerStr )
1496 consistentHostsResult = main.FALSE
1497 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001498 " hosts response: " +
1499 repr( hosts[ controller ] ) )
1500 utilities.assert_equals(
1501 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001502 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001503 onpass="Hosts view is consistent across all ONOS nodes",
1504 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001505
Jon Hall390696c2015-05-05 17:13:41 -07001506 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001507 ipResult = main.TRUE
1508 for controller in range( 0, len( hosts ) ):
1509 controllerStr = str( controller + 1 )
1510 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001511 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001512 main.log.error( "DEBUG:Error with host ips on controller" +
1513 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001514 ipResult = main.FALSE
1515 utilities.assert_equals(
1516 expect=main.TRUE,
1517 actual=ipResult,
1518 onpass="The ips of the hosts aren't empty",
1519 onfail="The ip of at least one host is missing" )
1520
Jon Hall6aec96b2015-01-19 14:49:31 -08001521 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001522 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001523 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001524 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001525 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001526 if "Error" not in clusters[ controller ]:
1527 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001528 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001529 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001530 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001531 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001532 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001533
1534 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001535 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001536 "from ONOS" + controllerStr )
1537 consistentClustersResult = main.FALSE
1538 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001539 " clusters response: " +
1540 repr( clusters[ controller ] ) )
1541 utilities.assert_equals(
1542 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001543 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001544 onpass="Clusters view is consistent across all ONOS nodes",
1545 onfail="ONOS nodes have different views of clusters" )
1546 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001547 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001548 try:
1549 numClusters = len( json.loads( clusters[ 0 ] ) )
1550 except ( ValueError, TypeError ):
1551 main.log.exception( "Error parsing clusters[0]: " +
1552 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001553 clusterResults = main.FALSE
1554 if numClusters == 1:
1555 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 utilities.assert_equals(
1557 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001558 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001559 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001560 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001561
Jon Hall6aec96b2015-01-19 14:49:31 -08001562 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001563 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001564 linksResults = main.TRUE
Jon Hallb6a54872015-06-12 14:02:42 -07001565 hostsResults = main.TRUE
1566 mnSwitches = main.Mininet1.getSwitches()
1567 mnLinks = main.Mininet1.getLinks()
1568 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001569 for controller in range( numControllers ):
1570 controllerStr = str( controller + 1 )
Jon Hallb6a54872015-06-12 14:02:42 -07001571 if devices[ controller ] and ports[ controller ] and\
1572 "Error" not in devices[ controller ] and\
1573 "Error" not in ports[ controller ]:
1574
Jon Hall8f89dda2015-01-22 16:03:33 -08001575 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallb6a54872015-06-12 14:02:42 -07001576 mnSwitches,
1577 json.loads( devices[ controller ] ),
1578 json.loads( ports[ 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 Hallb6a54872015-06-12 14:02:42 -07001587 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001588 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallb6a54872015-06-12 14:02:42 -07001589 mnSwitches, mnLinks,
1590 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001591 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001592 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001593 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001594 actual=currentLinksResult,
1595 onpass="ONOS" + controllerStr +
1596 " links view is correct",
1597 onfail="ONOS" + controllerStr +
1598 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001599
Jon Hallb6a54872015-06-12 14:02:42 -07001600 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1601 currentHostsResult = main.Mininet1.compareHosts(
1602 mnHosts,
1603 hosts[ controller ] )
1604 else:
1605 currentHostsResult = main.FALSE
1606 utilities.assert_equals( expect=main.TRUE,
1607 actual=currentHostsResult,
1608 onpass="ONOS" + controllerStr +
1609 " hosts exist in Mininet",
1610 onfail="ONOS" + controllerStr +
1611 " hosts don't match Mininet" )
Jon Hallb1290e82014-11-18 16:17:48 -05001612
Jon Hallb6a54872015-06-12 14:02:42 -07001613 devicesResults = devicesResults and currentDevicesResult
1614 linksResults = linksResults and currentLinksResult
1615 hostsResults = hostsResults and currentHostsResult
1616
1617 main.step( "Device information is correct" )
1618 utilities.assert_equals(
1619 expect=main.TRUE,
1620 actual=devicesResults,
1621 onpass="Device information is correct",
1622 onfail="Device information is incorrect" )
1623
1624 main.step( "Links are correct" )
1625 utilities.assert_equals(
1626 expect=main.TRUE,
1627 actual=linksResults,
1628 onpass="Link are correct",
1629 onfail="Links are incorrect" )
1630
1631 main.step( "Hosts are correct" )
1632 utilities.assert_equals(
1633 expect=main.TRUE,
1634 actual=hostsResults,
1635 onpass="Hosts are correct",
1636 onfail="Hosts are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001637
Jon Hall6aec96b2015-01-19 14:49:31 -08001638 def CASE6( self, main ):
1639 """
Jon Hallb1290e82014-11-18 16:17:48 -05001640 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001641 """
Jon Hall368769f2014-11-19 15:43:35 -08001642 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001643 assert numControllers, "numControllers not defined"
1644 assert main, "main not defined"
1645 assert utilities.assert_equals, "utilities.assert_equals not defined"
1646 assert CLIs, "CLIs not defined"
1647 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001648 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001649 time.sleep( 60 )
1650 utilities.assert_equals(
1651 expect=main.TRUE,
1652 actual=main.TRUE,
1653 onpass="Sleeping 60 seconds",
1654 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001655
Jon Hall6aec96b2015-01-19 14:49:31 -08001656 def CASE7( self, main ):
1657 """
Jon Hall368769f2014-11-19 15:43:35 -08001658 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001659 """
Jon Hallb1290e82014-11-18 16:17:48 -05001660 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001661 assert numControllers, "numControllers not defined"
1662 assert main, "main not defined"
1663 assert utilities.assert_equals, "utilities.assert_equals not defined"
1664 assert CLIs, "CLIs not defined"
1665 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001666 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001667
Jon Hall65844a32015-03-09 19:09:37 -07001668 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001669 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001670 rolesNotNull = main.TRUE
1671 threads = []
1672 for i in range( numControllers ):
1673 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001674 name="rolesNotNull-" + str( i ),
1675 args=[ ] )
1676 threads.append( t )
1677 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001678
1679 for t in threads:
1680 t.join()
1681 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001682 utilities.assert_equals(
1683 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001684 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001685 onpass="Each device has a master",
1686 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001687
Jon Hall390696c2015-05-05 17:13:41 -07001688 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001689 ONOSMastership = []
1690 mastershipCheck = main.FALSE
1691 consistentMastership = True
1692 rolesResults = True
1693 threads = []
1694 for i in range( numControllers ):
1695 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001696 name="roles-" + str( i ),
1697 args=[] )
1698 threads.append( t )
1699 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001700
1701 for t in threads:
1702 t.join()
1703 ONOSMastership.append( t.result )
1704
1705 for i in range( numControllers ):
1706 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001707 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001708 " roles" )
1709 main.log.warn(
1710 "ONOS" + str( i + 1 ) + " mastership response: " +
1711 repr( ONOSMastership[i] ) )
1712 rolesResults = False
1713 utilities.assert_equals(
1714 expect=True,
1715 actual=rolesResults,
1716 onpass="No error in reading roles output",
1717 onfail="Error in reading roles from ONOS" )
1718
1719 main.step( "Check for consistency in roles from each controller" )
1720 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001721 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001722 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001723 else:
Jon Hall65844a32015-03-09 19:09:37 -07001724 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001725 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001726 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001727 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001728 onpass="Switch roles are consistent across all ONOS nodes",
1729 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001730
Jon Hall65844a32015-03-09 19:09:37 -07001731 if rolesResults and not consistentMastership:
1732 for i in range( numControllers ):
1733 main.log.warn(
1734 "ONOS" + str( i + 1 ) + " roles: ",
1735 json.dumps(
1736 json.loads( ONOSMastership[ i ] ),
1737 sort_keys=True,
1738 indent=4,
1739 separators=( ',', ': ' ) ) )
1740 elif rolesResults and not consistentMastership:
1741 mastershipCheck = main.TRUE
1742
Jon Hallb1290e82014-11-18 16:17:48 -05001743 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001744 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001745 try:
1746 currentJson = json.loads( ONOSMastership[0] )
1747 oldJson = json.loads( mastershipState )
1748 except ( ValueError, TypeError ):
1749 main.log.exception( "Something is wrong with parsing " +
1750 "ONOSMastership[0] or mastershipState" )
1751 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1752 main.log.error( "mastershipState" + repr( mastershipState ) )
1753 main.cleanup()
1754 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001755 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001756 for i in range( 1, 29 ):
1757 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001758 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001759 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001760 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001761 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001763 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001764 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001765 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001766 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001767 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001768 utilities.assert_equals(
1769 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001770 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001771 onpass="Mastership of Switches was not changed",
1772 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001773 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001774
Jon Hall6aec96b2015-01-19 14:49:31 -08001775 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001776 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001777 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001778 consistentIntents = True
1779 intentsResults = True
1780 threads = []
1781 for i in range( numControllers ):
1782 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001783 name="intents-" + str( i ),
1784 args=[],
1785 kwargs={ 'jsonFormat': True } )
1786 threads.append( t )
1787 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001788
1789 for t in threads:
1790 t.join()
1791 ONOSIntents.append( t.result )
1792
1793 for i in range( numControllers ):
1794 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001795 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001796 " intents" )
1797 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1798 repr( ONOSIntents[ i ] ) )
1799 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001800 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001801 expect=True,
1802 actual=intentsResults,
1803 onpass="No error in reading intents output",
1804 onfail="Error in reading intents from ONOS" )
1805
1806 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001807 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001808 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001809 "nodes" )
1810 else:
1811 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001812
1813 # Try to make it easy to figure out what is happening
1814 #
1815 # Intent ONOS1 ONOS2 ...
1816 # 0x01 INSTALLED INSTALLING
1817 # ... ... ...
1818 # ... ... ...
1819 title = " ID"
1820 for n in range( numControllers ):
1821 title += " " * 10 + "ONOS" + str( n + 1 )
1822 main.log.warn( title )
1823 # get all intent keys in the cluster
1824 keys = []
1825 for nodeStr in ONOSIntents:
1826 node = json.loads( nodeStr )
1827 for intent in node:
1828 keys.append( intent.get( 'id' ) )
1829 keys = set( keys )
1830 for key in keys:
1831 row = "%-13s" % key
1832 for nodeStr in ONOSIntents:
1833 node = json.loads( nodeStr )
1834 for intent in node:
1835 if intent.get( 'id' ) == key:
1836 row += "%-15s" % intent.get( 'state' )
1837 main.log.warn( row )
1838 # End table view
1839
Jon Hall65844a32015-03-09 19:09:37 -07001840 utilities.assert_equals(
1841 expect=True,
1842 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001843 onpass="Intents are consistent across all ONOS nodes",
1844 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001845 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001846 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001847 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001848 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001849 try:
1850 for intent in json.loads( node ):
1851 nodeStates.append( intent[ 'state' ] )
1852 except ( ValueError, TypeError ):
1853 main.log.exception( "Error in parsing intents" )
1854 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001855 intentStates.append( nodeStates )
1856 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1857 main.log.info( dict( out ) )
1858
Jon Hall65844a32015-03-09 19:09:37 -07001859 if intentsResults and not consistentIntents:
1860 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001861 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1862 main.log.warn( json.dumps(
1863 json.loads( ONOSIntents[ i ] ),
1864 sort_keys=True,
1865 indent=4,
1866 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001867 elif intentsResults and consistentIntents:
1868 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001869
Jon Hall58c76b72015-02-23 11:09:24 -08001870 # NOTE: Store has no durability, so intents are lost across system
1871 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001872 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001873 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001874 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001875 sameIntents = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001876 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001877 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001878 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001879 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001880 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001881 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1882 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001883 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001884 before = json.loads( intentState )
1885 after = json.loads( ONOSIntents[ 0 ] )
1886 for intent in before:
1887 if intent not in after:
1888 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001889 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001890 "(at least in the same form):" )
1891 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001892 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001893 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001894 main.log.debug( repr( ONOSIntents[0] ) )
1895 main.log.debug( repr( intentState ) )
1896 if sameIntents == main.FALSE:
1897 try:
1898 main.log.debug( "ONOS intents before: " )
1899 main.log.debug( json.dumps( json.loads( intentState ),
1900 sort_keys=True, indent=4,
1901 separators=( ',', ': ' ) ) )
1902 main.log.debug( "Current ONOS intents: " )
1903 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1904 sort_keys=True, indent=4,
1905 separators=( ',', ': ' ) ) )
1906 except ( ValueError, TypeError ):
1907 main.log.exception( "Exception printing intents" )
1908 main.log.debug( repr( ONOSIntents[0] ) )
1909 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001910 utilities.assert_equals(
1911 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001912 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001913 onpass="Intents are consistent with before failure",
1914 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001915 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001916
Jon Hall6aec96b2015-01-19 14:49:31 -08001917 main.step( "Get the OF Table entries and compare to before " +
1918 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001919 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001920 flows2 = []
1921 for i in range( 28 ):
1922 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001923 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1924 flows2.append( tmpFlows )
1925 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001926 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001927 flow2=tmpFlows )
1928 FlowTables = FlowTables and tempResult
1929 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001930 main.log.info( "Differences in flow table for switch: s" +
1931 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 utilities.assert_equals(
1933 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001934 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001935 onpass="No changes were found in the flow tables",
1936 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001937
Jon Hall6aec96b2015-01-19 14:49:31 -08001938 main.step( "Check the continuous pings to ensure that no packets " +
1939 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001940 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1941 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001942 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001943 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1944 for i in range( 8, 18 ):
1945 main.log.info(
1946 "Checking for a loss in pings along flow from s" +
1947 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001948 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001949 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001950 str( i ) ) or LossInPings
1951 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001952 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001953 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001954 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001955 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001956 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001957 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 utilities.assert_equals(
1959 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001960 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001961 onpass="No Loss of connectivity",
1962 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001963
Jon Hall390696c2015-05-05 17:13:41 -07001964 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001965 # Test of LeadershipElection
1966 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001967 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001968 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001969 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001970 for cli in CLIs:
1971 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001973 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001974 # all is well
1975 # NOTE: In failure scenario, this could be a new node, maybe
1976 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001977 pass
1978 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001979 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001980 main.log.error( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001981 "electionTestLeader function, check the" +
1982 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001983 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001984 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001985 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001986 main.log.error( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001987 " as the leader of the election app. " +
1988 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001989 utilities.assert_equals(
1990 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001991 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001992 onpass="Leadership election passed",
1993 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001994
Jon Hall6aec96b2015-01-19 14:49:31 -08001995 def CASE8( self, main ):
1996 """
Jon Hallb1290e82014-11-18 16:17:48 -05001997 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001998 """
Jon Hallb1290e82014-11-18 16:17:48 -05001999 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 # FIXME add this path to params
2001 sys.path.append( "/home/admin/sts" )
2002 # assumes that sts is already in you PYTHONPATH
2003 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05002004 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08002005 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002006 assert numControllers, "numControllers not defined"
2007 assert main, "main not defined"
2008 assert utilities.assert_equals, "utilities.assert_equals not defined"
2009 assert CLIs, "CLIs not defined"
2010 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002011
Jon Hallfeff3082015-05-19 10:23:26 -07002012 main.case( "Compare ONOS Topology view to Mininet topology" )
2013 main.caseExplaination = "Compare topology objects between Mininet" +\
2014 " and ONOS"
Jon Hallb1290e82014-11-18 16:17:48 -05002015
Jon Hallfeff3082015-05-19 10:23:26 -07002016 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002017 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002018 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002019 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002020 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002021 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002022 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002023 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002024 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002025 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002026 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002027 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07002028 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002029 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002030 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07002031 threads = []
2032 for i in range( numControllers ):
2033 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07002034 name="devices-" + str( i ),
2035 args=[ ] )
2036 threads.append( t )
2037 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002038
2039 for t in threads:
2040 t.join()
2041 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002042 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002043 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07002044 threads = []
2045 for i in range( numControllers ):
2046 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07002047 name="hosts-" + str( i ),
2048 args=[ ] )
2049 threads.append( t )
2050 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002051
2052 for t in threads:
2053 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002054 try:
2055 hosts.append( json.loads( t.result ) )
2056 except ( ValueError, TypeError ):
2057 main.log.exception( "Error parsing hosts results" )
2058 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002059 for controller in range( 0, len( hosts ) ):
2060 controllerStr = str( controller + 1 )
2061 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002062 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002063 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002064 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002065 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002066 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002067 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07002068 threads = []
2069 for i in range( numControllers ):
2070 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07002071 name="ports-" + str( i ),
2072 args=[ ] )
2073 threads.append( t )
2074 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002075
2076 for t in threads:
2077 t.join()
2078 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002079 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002080 threads = []
2081 for i in range( numControllers ):
2082 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002083 name="links-" + str( i ),
2084 args=[ ] )
2085 threads.append( t )
2086 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002087
2088 for t in threads:
2089 t.join()
2090 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002091 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002092 threads = []
2093 for i in range( numControllers ):
2094 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002095 name="clusters-" + str( i ),
2096 args=[ ] )
2097 threads.append( t )
2098 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002099
2100 for t in threads:
2101 t.join()
2102 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002103
Jon Hall8f89dda2015-01-22 16:03:33 -08002104 elapsed = time.time() - startTime
2105 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002106 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002107 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002108
Jon Hallb6a54872015-06-12 14:02:42 -07002109 mnSwitches = main.Mininet1.getSwitches()
2110 mnLinks = main.Mininet1.getLinks()
2111 mnHosts = main.Mininet1.getHosts()
Jon Hall21270ac2015-02-16 17:59:55 -08002112 for controller in range( numControllers ):
2113 controllerStr = str( controller + 1 )
Jon Hallb6a54872015-06-12 14:02:42 -07002114 if devices[ controller ] and ports[ controller ] and\
2115 "Error" not in devices[ controller ] and\
2116 "Error" not in ports[ controller ]:
2117
Jon Hall21270ac2015-02-16 17:59:55 -08002118 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallb6a54872015-06-12 14:02:42 -07002119 mnSwitches,
2120 json.loads( devices[ controller ] ),
2121 json.loads( ports[ 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 Hallb6a54872015-06-12 14:02:42 -07002131 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall21270ac2015-02-16 17:59:55 -08002132 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallb6a54872015-06-12 14:02:42 -07002133 mnSwitches, mnLinks,
2134 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002135 else:
2136 currentLinksResult = main.FALSE
2137 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002138 actual=currentLinksResult,
2139 onpass="ONOS" + controllerStr +
2140 " links view is correct",
2141 onfail="ONOS" + controllerStr +
2142 " links view is incorrect" )
2143
2144 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2145 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallb6a54872015-06-12 14:02:42 -07002146 mnHosts,
2147 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002148 else:
2149 currentHostsResult = main.FALSE
2150 utilities.assert_equals( expect=main.TRUE,
2151 actual=currentHostsResult,
2152 onpass="ONOS" + controllerStr +
2153 " hosts exist in Mininet",
2154 onfail="ONOS" + controllerStr +
2155 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002156 # CHECKING HOST ATTACHMENT POINTS
2157 hostAttachment = True
Jon Hallb6a54872015-06-12 14:02:42 -07002158 zeroHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002159 # FIXME: topo-HA/obelisk specific mappings:
2160 # key is mac and value is dpid
2161 mappings = {}
2162 for i in range( 1, 29 ): # hosts 1 through 28
2163 # set up correct variables:
2164 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2165 if i == 1:
2166 deviceId = "1000".zfill(16)
2167 elif i == 2:
2168 deviceId = "2000".zfill(16)
2169 elif i == 3:
2170 deviceId = "3000".zfill(16)
2171 elif i == 4:
2172 deviceId = "3004".zfill(16)
2173 elif i == 5:
2174 deviceId = "5000".zfill(16)
2175 elif i == 6:
2176 deviceId = "6000".zfill(16)
2177 elif i == 7:
2178 deviceId = "6007".zfill(16)
2179 elif i >= 8 and i <= 17:
2180 dpid = '3' + str( i ).zfill( 3 )
2181 deviceId = dpid.zfill(16)
2182 elif i >= 18 and i <= 27:
2183 dpid = '6' + str( i ).zfill( 3 )
2184 deviceId = dpid.zfill(16)
2185 elif i == 28:
2186 deviceId = "2800".zfill(16)
2187 mappings[ macId ] = deviceId
2188 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2189 if hosts[ controller ] == []:
2190 main.log.warn( "There are no hosts discovered" )
Jon Hallb6a54872015-06-12 14:02:42 -07002191 zeroHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002192 else:
2193 for host in hosts[ controller ]:
2194 mac = None
2195 location = None
2196 device = None
2197 port = None
2198 try:
2199 mac = host.get( 'mac' )
2200 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002201
Jon Hallc9eabec2015-06-10 14:33:14 -07002202 location = host.get( 'location' )
2203 assert location, "location field could not be found for this host object"
2204
2205 # Trim the protocol identifier off deviceId
2206 device = str( location.get( 'elementId' ) ).split(':')[1]
2207 assert device, "elementId field could not be found for this host location object"
2208
2209 port = location.get( 'port' )
2210 assert port, "port field could not be found for this host location object"
2211
2212 # Now check if this matches where they should be
2213 if mac and device and port:
2214 if str( port ) != "1":
2215 main.log.error( "The attachment port is incorrect for " +
2216 "host " + str( mac ) +
2217 ". Expected: 1 Actual: " + str( port) )
2218 hostAttachment = False
2219 if device != mappings[ str( mac ) ]:
2220 main.log.error( "The attachment device is incorrect for " +
2221 "host " + str( mac ) +
2222 ". Expected: " + mappings[ str( mac ) ] +
2223 " Actual: " + device )
2224 hostAttachment = False
2225 else:
2226 hostAttachment = False
2227 except AssertionError:
2228 main.log.exception( "Json object not as expected" )
2229 main.log.error( repr( host ) )
2230 hostAttachment = False
2231 else:
2232 main.log.error( "No hosts json output or \"Error\"" +
2233 " in output. hosts = " +
2234 repr( hosts[ controller ] ) )
Jon Hallb6a54872015-06-12 14:02:42 -07002235 if zeroHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002236 hostAttachment = True
2237
2238 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002239 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002240 linksResults = linksResults and currentLinksResult
2241 hostsResults = hostsResults and currentHostsResult
Jon Hallb6a54872015-06-12 14:02:42 -07002242 hostAttachmentResults = hostAttachmentResults and\
2243 hostAttachment
2244 topoResult = ( devicesResults and linksResults
2245 and hostsResults and ipResult and
2246 hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002247
Jon Hallc9eabec2015-06-10 14:33:14 -07002248 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002249
Jon Hallc9eabec2015-06-10 14:33:14 -07002250 # hosts
2251 main.step( "Hosts view is consistent across all ONOS nodes" )
2252 consistentHostsResult = main.TRUE
2253 for controller in range( len( hosts ) ):
2254 controllerStr = str( controller + 1 )
2255 if "Error" not in hosts[ controller ]:
2256 if hosts[ controller ] == hosts[ 0 ]:
2257 continue
2258 else: # hosts not consistent
2259 main.log.error( "hosts from ONOS" + controllerStr +
2260 " is inconsistent with ONOS1" )
2261 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002262 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002263
Jon Hallc9eabec2015-06-10 14:33:14 -07002264 else:
2265 main.log.error( "Error in getting ONOS hosts from ONOS" +
2266 controllerStr )
2267 consistentHostsResult = main.FALSE
2268 main.log.warn( "ONOS" + controllerStr +
2269 " hosts response: " +
2270 repr( hosts[ controller ] ) )
2271 utilities.assert_equals(
2272 expect=main.TRUE,
2273 actual=consistentHostsResult,
2274 onpass="Hosts view is consistent across all ONOS nodes",
2275 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002276
Jon Hallc9eabec2015-06-10 14:33:14 -07002277 main.step( "Hosts information is correct" )
2278 hostsResults = hostsResults and ipResult
2279 utilities.assert_equals(
2280 expect=main.TRUE,
2281 actual=hostsResults,
2282 onpass="Host information is correct",
2283 onfail="Host information is incorrect" )
2284
2285 main.step( "Host attachment points to the network" )
2286 utilities.assert_equals(
2287 expect=True,
2288 actual=hostAttachmentResults,
2289 onpass="Hosts are correctly attached to the network",
2290 onfail="ONOS did not correctly attach hosts to the network" )
2291
2292 # Strongly connected clusters of devices
2293 main.step( "Clusters view is consistent across all ONOS nodes" )
2294 consistentClustersResult = main.TRUE
2295 for controller in range( len( clusters ) ):
2296 controllerStr = str( controller + 1 )
2297 if "Error" not in clusters[ controller ]:
2298 if clusters[ controller ] == clusters[ 0 ]:
2299 continue
2300 else: # clusters not consistent
2301 main.log.error( "clusters from ONOS" +
2302 controllerStr +
2303 " is inconsistent with ONOS1" )
Jon Hall21270ac2015-02-16 17:59:55 -08002304 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002305
Jon Hallc9eabec2015-06-10 14:33:14 -07002306 else:
2307 main.log.error( "Error in getting dataplane clusters " +
2308 "from ONOS" + controllerStr )
2309 consistentClustersResult = main.FALSE
2310 main.log.warn( "ONOS" + controllerStr +
2311 " clusters response: " +
2312 repr( clusters[ controller ] ) )
2313 utilities.assert_equals(
2314 expect=main.TRUE,
2315 actual=consistentClustersResult,
2316 onpass="Clusters view is consistent across all ONOS nodes",
2317 onfail="ONOS nodes have different views of clusters" )
2318
2319 main.step( "There is only one SCC" )
2320 # there should always only be one cluster
2321 try:
2322 numClusters = len( json.loads( clusters[ 0 ] ) )
2323 except ( ValueError, TypeError ):
2324 main.log.exception( "Error parsing clusters[0]: " +
2325 repr( clusters[0] ) )
2326 clusterResults = main.FALSE
2327 if numClusters == 1:
2328 clusterResults = main.TRUE
2329 utilities.assert_equals(
2330 expect=1,
2331 actual=numClusters,
2332 onpass="ONOS shows 1 SCC",
2333 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2334
Jon Hallb6a54872015-06-12 14:02:42 -07002335 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002336 and hostsResults and consistentHostsResult
2337 and consistentClustersResult and clusterResults
2338 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002339
Jon Hall21270ac2015-02-16 17:59:55 -08002340 topoResult = topoResult and int( count <= 2 )
2341 note = "note it takes about " + str( int( cliTime ) ) + \
2342 " seconds for the test to make all the cli calls to fetch " +\
2343 "the topology from each ONOS instance"
2344 main.log.info(
2345 "Very crass estimate for topology discovery/convergence( " +
2346 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2347 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002348
2349 main.step( "Device information is correct" )
2350 utilities.assert_equals(
2351 expect=main.TRUE,
2352 actual=devicesResults,
2353 onpass="Device information is correct",
2354 onfail="Device information is incorrect" )
2355
Jon Hallc9eabec2015-06-10 14:33:14 -07002356 main.step( "Links are correct" )
2357 utilities.assert_equals(
2358 expect=main.TRUE,
2359 actual=linksResults,
2360 onpass="Link are correct",
2361 onfail="Links are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002362
Jon Hallb6a54872015-06-12 14:02:42 -07002363 main.step( "Hosts are correct" )
2364 utilities.assert_equals(
2365 expect=main.TRUE,
2366 actual=hostsResults,
2367 onpass="Hosts are correct",
2368 onfail="Hosts are incorrect" )
2369
Jon Halla9d26da2015-03-30 16:45:32 -07002370 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002371 main.step( "Checking ONOS nodes" )
2372 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002373 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002374 threads = []
2375 for i in range( numControllers ):
2376 t = main.Thread( target=CLIs[i].nodes,
2377 name="nodes-" + str( i ),
2378 args=[ ] )
2379 threads.append( t )
2380 t.start()
2381
2382 for t in threads:
2383 t.join()
2384 nodesOutput.append( t.result )
2385 ips = [ node.ip_address for node in nodes ]
2386 for i in nodesOutput:
2387 try:
2388 current = json.loads( i )
2389 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002390 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002391 if node['ip'] in ips: # node in nodes() output is in cell
2392 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002393 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002394 else:
2395 main.log.error( "Error in ONOS node availability" )
2396 main.log.error(
2397 json.dumps( current,
2398 sort_keys=True,
2399 indent=4,
2400 separators=( ',', ': ' ) ) )
2401 break
Jon Hall390696c2015-05-05 17:13:41 -07002402 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002403 except ( ValueError, TypeError ):
2404 main.log.error( "Error parsing nodes output" )
2405 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002406 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2407 onpass="Nodes check successful",
2408 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002409
Jon Hall6aec96b2015-01-19 14:49:31 -08002410 def CASE9( self, main ):
2411 """
Jon Hallb1290e82014-11-18 16:17:48 -05002412 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002413 """
2414 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002415 assert numControllers, "numControllers not defined"
2416 assert main, "main not defined"
2417 assert utilities.assert_equals, "utilities.assert_equals not defined"
2418 assert CLIs, "CLIs not defined"
2419 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002420 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002421
Jon Hall8f89dda2015-01-22 16:03:33 -08002422 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002423
Jon Hall6aec96b2015-01-19 14:49:31 -08002424 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002425 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002426 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002427
Jon Hall6aec96b2015-01-19 14:49:31 -08002428 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002429 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002430 main.log.info( "Waiting " + str( linkSleep ) +
2431 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002432 time.sleep( linkSleep )
2433 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002434 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002435 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002436 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002437
Jon Hall6aec96b2015-01-19 14:49:31 -08002438 def CASE10( self, main ):
2439 """
Jon Hallb1290e82014-11-18 16:17:48 -05002440 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002441 """
2442 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002443 assert numControllers, "numControllers not defined"
2444 assert main, "main not defined"
2445 assert utilities.assert_equals, "utilities.assert_equals not defined"
2446 assert CLIs, "CLIs not defined"
2447 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002448 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002449
Jon Hall8f89dda2015-01-22 16:03:33 -08002450 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002451
Jon Hall6aec96b2015-01-19 14:49:31 -08002452 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002453 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002454 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002455
Jon Hall6aec96b2015-01-19 14:49:31 -08002456 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002457 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002458 main.log.info( "Waiting " + str( linkSleep ) +
2459 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002460 time.sleep( linkSleep )
2461 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002462 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002463 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002464 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002465
Jon Hall6aec96b2015-01-19 14:49:31 -08002466 def CASE11( self, main ):
2467 """
Jon Hallb1290e82014-11-18 16:17:48 -05002468 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002469 """
2470 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002471 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002472 assert numControllers, "numControllers not defined"
2473 assert main, "main not defined"
2474 assert utilities.assert_equals, "utilities.assert_equals not defined"
2475 assert CLIs, "CLIs not defined"
2476 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002477
Jon Hall8f89dda2015-01-22 16:03:33 -08002478 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002479
2480 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002481 main.case( description )
2482 switch = main.params[ 'kill' ][ 'switch' ]
2483 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002484
Jon Hall6aec96b2015-01-19 14:49:31 -08002485 # TODO: Make this switch parameterizable
2486 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002487 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002488 main.Mininet1.delSwitch( switch )
2489 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002490 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002491 time.sleep( switchSleep )
2492 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002493 # Peek at the deleted switch
2494 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002495 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002496 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002497 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002499 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002500 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002501
Jon Hall6aec96b2015-01-19 14:49:31 -08002502 def CASE12( self, main ):
2503 """
Jon Hallb1290e82014-11-18 16:17:48 -05002504 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002505 """
2506 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002507 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002508 assert numControllers, "numControllers not defined"
2509 assert main, "main not defined"
2510 assert utilities.assert_equals, "utilities.assert_equals not defined"
2511 assert CLIs, "CLIs not defined"
2512 assert nodes, "nodes not defined"
2513 assert ONOS1Port, "ONOS1Port not defined"
2514 assert ONOS2Port, "ONOS2Port not defined"
2515 assert ONOS3Port, "ONOS3Port not defined"
2516 assert ONOS4Port, "ONOS4Port not defined"
2517 assert ONOS5Port, "ONOS5Port not defined"
2518 assert ONOS6Port, "ONOS6Port not defined"
2519 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002520
Jon Hall8f89dda2015-01-22 16:03:33 -08002521 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002522 switch = main.params[ 'kill' ][ 'switch' ]
2523 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2524 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002525 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002526 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002527
Jon Hall6aec96b2015-01-19 14:49:31 -08002528 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002529 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002530 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002531 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002532 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2533 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -07002534 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002535 port1=ONOS1Port,
Jon Hall65844a32015-03-09 19:09:37 -07002536 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002537 port2=ONOS2Port,
Jon Hall65844a32015-03-09 19:09:37 -07002538 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002539 port3=ONOS3Port,
Jon Hall65844a32015-03-09 19:09:37 -07002540 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002541 port4=ONOS4Port,
Jon Hall65844a32015-03-09 19:09:37 -07002542 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002543 port5=ONOS5Port,
Jon Hall65844a32015-03-09 19:09:37 -07002544 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002545 port6=ONOS6Port,
Jon Hall65844a32015-03-09 19:09:37 -07002546 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002547 port7=ONOS7Port )
2548 main.log.info( "Waiting " + str( switchSleep ) +
2549 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002550 time.sleep( switchSleep )
2551 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002552 # Peek at the deleted switch
2553 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002554 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002556 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002557 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002558 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002559 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002560
Jon Hall6aec96b2015-01-19 14:49:31 -08002561 def CASE13( self, main ):
2562 """
Jon Hallb1290e82014-11-18 16:17:48 -05002563 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002564 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002565 import os
2566 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002567 assert numControllers, "numControllers not defined"
2568 assert main, "main not defined"
2569 assert utilities.assert_equals, "utilities.assert_equals not defined"
2570 assert CLIs, "CLIs not defined"
2571 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002572
2573 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002574 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2575 'blue': '\033[94m', 'green': '\033[92m',
2576 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002577 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002578 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002579 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002580
Jon Hall6aec96b2015-01-19 14:49:31 -08002581 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002582 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002583 teststationUser = main.params[ 'TESTONUSER' ]
2584 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002585 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002586 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002587 # FIXME: scp
2588 # mn files
2589 # TODO: Load these from params
2590 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002591 logFolder = "/opt/onos/log/"
2592 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002594 dstDir = "~/packet_captures/"
2595 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002596 for node in nodes:
2597 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2598 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002599 teststationUser + "@" +
2600 teststationIP + ":" +
2601 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002602 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002603 main.ONOSbench.handle.expect( "\$" )
2604
Jon Hall6aec96b2015-01-19 14:49:31 -08002605 # std*.log's
2606 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002607 logFolder = "/opt/onos/var/"
2608 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002609 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002610 dstDir = "~/packet_captures/"
2611 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002612 for node in nodes:
2613 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2614 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002615 teststationUser + "@" +
2616 teststationIP + ":" +
2617 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002618 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002619 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002620 # sleep so scp can finish
2621 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002622
2623 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002624 mnResult = main.Mininet1.stopNet()
2625 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2626 onpass="Mininet stopped",
2627 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002628
2629 main.step( "Checking ONOS Logs for errors" )
2630 for node in nodes:
2631 print colors[ 'purple' ] + "Checking logs for errors on " + \
2632 node.name + ":" + colors[ 'end' ]
2633 print main.ONOSbench.checkLogs( node.ip_address )
2634
Jon Hall6aec96b2015-01-19 14:49:31 -08002635 main.step( "Packing and rotating pcap archives" )
2636 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002637
Jon Hall390696c2015-05-05 17:13:41 -07002638 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002639 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002640 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002641 labels = "Gossip Intents"
2642 data = str( gossipTime )
2643 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002644 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002645 except NameError, e:
2646 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002647
Jon Hall6aec96b2015-01-19 14:49:31 -08002648 def CASE14( self, main ):
2649 """
Jon Hall94fd0472014-12-08 11:52:42 -08002650 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002651 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002652 assert numControllers, "numControllers not defined"
2653 assert main, "main not defined"
2654 assert utilities.assert_equals, "utilities.assert_equals not defined"
2655 assert CLIs, "CLIs not defined"
2656 assert nodes, "nodes not defined"
2657
Jon Hall390696c2015-05-05 17:13:41 -07002658 main.case("Start Leadership Election app")
2659 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002660 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2661 utilities.assert_equals(
2662 expect=main.TRUE,
2663 actual=appResult,
2664 onpass="Election app installed",
2665 onfail="Something went wrong with installing Leadership election" )
2666
2667 main.step( "Run for election on each node" )
2668 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002669 leaders = []
2670 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002671 cli.electionTestRun()
2672 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002673 leader = cli.electionTestLeader()
2674 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002675 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002676 "should be an ONOS node, instead got '" +
2677 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002678 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002679 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002680 utilities.assert_equals(
2681 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002682 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002683 onpass="Successfully ran for leadership",
2684 onfail="Failed to run for leadership" )
2685
2686 main.step( "Check that each node shows the same leader" )
2687 sameLeader = main.TRUE
2688 if len( set( leaders ) ) != 1:
2689 sameLeader = main.FALSE
2690 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2691 str( leaders ) )
2692 utilities.assert_equals(
2693 expect=main.TRUE,
2694 actual=sameLeader,
2695 onpass="Leadership is consistent for the election topic",
2696 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002697
Jon Hall6aec96b2015-01-19 14:49:31 -08002698 def CASE15( self, main ):
2699 """
Jon Hall669173b2014-12-17 11:36:30 -08002700 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002701 """
Jon Hall390696c2015-05-05 17:13:41 -07002702 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002703 assert numControllers, "numControllers not defined"
2704 assert main, "main not defined"
2705 assert utilities.assert_equals, "utilities.assert_equals not defined"
2706 assert CLIs, "CLIs not defined"
2707 assert nodes, "nodes not defined"
2708
Jon Hall8f89dda2015-01-22 16:03:33 -08002709 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002710 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002711 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002712
2713 main.step( "Check that each node shows the same leader" )
2714 sameLeader = main.TRUE
2715 leaders = []
2716 for cli in CLIs:
2717 leader = cli.electionTestLeader()
2718 leaders.append( leader )
2719 if len( set( leaders ) ) != 1:
2720 sameLeader = main.FALSE
2721 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2722 str( leaders ) )
2723 utilities.assert_equals(
2724 expect=main.TRUE,
2725 actual=sameLeader,
2726 onpass="Leadership is consistent for the election topic",
2727 onfail="Nodes have different leaders" )
2728
Jon Hall6aec96b2015-01-19 14:49:31 -08002729 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002730 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002731 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002732 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002733 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002734 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002735 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002736 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002737 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002738 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002739 for i in range( len( CLIs ) ):
2740 if leader == nodes[ i ].ip_address:
2741 oldLeader = CLIs[ i ]
2742 break
Jon Halla9d26da2015-03-30 16:45:32 -07002743 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002744 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002745 if oldLeader:
2746 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002747 utilities.assert_equals(
2748 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002749 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002750 onpass="Node was withdrawn from election",
2751 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002752
Jon Hall6aec96b2015-01-19 14:49:31 -08002753 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002754 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002755 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002756 for cli in CLIs:
2757 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002758 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002759 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002760 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002761 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002762 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002763 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002764 # error in response
2765 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002766 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002767 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002768 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002769 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002770 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002771 elif leaderN is None:
2772 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002773 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002774 leaderN = cli.electionTestLeader()
2775 leaderList.pop()
2776 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002777 consistentLeader = main.FALSE
2778 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002779 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002780 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002781 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002782 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002783 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002784 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002785 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002786 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002787 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002788 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002789 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002790 utilities.assert_equals(
2791 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002792 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002793 onpass="Leadership election passed",
2794 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002795
Jon Hall58c76b72015-02-23 11:09:24 -08002796 main.step( "Run for election on old leader( just so everyone " +
2797 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002798 if oldLeader:
2799 runResult = oldLeader.electionTestRun()
2800 else:
2801 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002802 utilities.assert_equals(
2803 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002804 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002805 onpass="App re-ran for election",
2806 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002807
Jon Hallfeff3082015-05-19 10:23:26 -07002808 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002809 afterRun = main.ONOScli1.electionTestLeader()
2810 # verify leader didn't just change
2811 if afterRun == leaderList[ 0 ]:
2812 afterResult = main.TRUE
2813 else:
2814 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002815
Jon Hall6aec96b2015-01-19 14:49:31 -08002816 utilities.assert_equals(
2817 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002818 actual=afterResult,
2819 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002820 onfail="Something went wrong with Leadership election after " +
2821 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002822
Jon Hall390696c2015-05-05 17:13:41 -07002823 def CASE16( self, main ):
2824 """
2825 Install Distributed Primitives app
2826 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002827 import time
Jon Hall390696c2015-05-05 17:13:41 -07002828 assert numControllers, "numControllers not defined"
2829 assert main, "main not defined"
2830 assert utilities.assert_equals, "utilities.assert_equals not defined"
2831 assert CLIs, "CLIs not defined"
2832 assert nodes, "nodes not defined"
2833
2834 # Variables for the distributed primitives tests
2835 global pCounterName
2836 global iCounterName
2837 global pCounterValue
2838 global iCounterValue
2839 global onosSet
2840 global onosSetName
2841 pCounterName = "TestON-Partitions"
2842 iCounterName = "TestON-inMemory"
2843 pCounterValue = 0
2844 iCounterValue = 0
2845 onosSet = set([])
2846 onosSetName = "TestON-set"
2847
2848 description = "Install Primitives app"
2849 main.case( description )
2850 main.step( "Install Primitives app" )
2851 appName = "org.onosproject.distributedprimitives"
2852 appResults = CLIs[0].activateApp( appName )
2853 utilities.assert_equals( expect=main.TRUE,
2854 actual=appResults,
2855 onpass="Primitives app activated",
2856 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002857 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002858
2859 def CASE17( self, main ):
2860 """
2861 Check for basic functionality with distributed primitives
2862 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002863 import json
Jon Hall390696c2015-05-05 17:13:41 -07002864 # Make sure variables are defined/set
2865 assert numControllers, "numControllers not defined"
2866 assert main, "main not defined"
2867 assert utilities.assert_equals, "utilities.assert_equals not defined"
2868 assert CLIs, "CLIs not defined"
2869 assert nodes, "nodes not defined"
2870 assert pCounterName, "pCounterName not defined"
2871 assert iCounterName, "iCounterName not defined"
2872 assert onosSetName, "onosSetName not defined"
2873 # NOTE: assert fails if value is 0/None/Empty/False
2874 try:
2875 pCounterValue
2876 except NameError:
2877 main.log.error( "pCounterValue not defined, setting to 0" )
2878 pCounterValue = 0
2879 try:
2880 iCounterValue
2881 except NameError:
2882 main.log.error( "iCounterValue not defined, setting to 0" )
2883 iCounterValue = 0
2884 try:
2885 onosSet
2886 except NameError:
2887 main.log.error( "onosSet not defined, setting to empty Set" )
2888 onosSet = set([])
2889 # Variables for the distributed primitives tests. These are local only
2890 addValue = "a"
2891 addAllValue = "a b c d e f"
2892 retainValue = "c d e f"
2893
2894 description = "Check for basic functionality with distributed " +\
2895 "primitives"
2896 main.case( description )
2897 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2898 # DISTRIBUTED ATOMIC COUNTERS
2899 main.step( "Increment and get a default counter on each node" )
2900 pCounters = []
2901 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002902 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002903 for i in range( numControllers ):
2904 t = main.Thread( target=CLIs[i].counterTestIncrement,
2905 name="counterIncrement-" + str( i ),
2906 args=[ pCounterName ] )
2907 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002908 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002909 threads.append( t )
2910 t.start()
2911
2912 for t in threads:
2913 t.join()
2914 pCounters.append( t.result )
2915 # Check that counter incremented numController times
2916 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002917 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002918 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002919 pCounterResults = pCounterResults and tmpResult
2920 if not tmpResult:
2921 main.log.error( str( i ) + " is not in partitioned "
2922 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002923 utilities.assert_equals( expect=True,
2924 actual=pCounterResults,
2925 onpass="Default counter incremented",
2926 onfail="Error incrementing default" +
2927 " counter" )
2928
2929 main.step( "Increment and get an in memory counter on each node" )
2930 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002931 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002932 threads = []
2933 for i in range( numControllers ):
2934 t = main.Thread( target=CLIs[i].counterTestIncrement,
2935 name="icounterIncrement-" + str( i ),
2936 args=[ iCounterName ],
2937 kwargs={ "inMemory": True } )
2938 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002939 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002940 threads.append( t )
2941 t.start()
2942
2943 for t in threads:
2944 t.join()
2945 iCounters.append( t.result )
2946 # Check that counter incremented numController times
2947 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002948 for i in addedIValues:
2949 tmpResult = i in iCounters
2950 iCounterResults = iCounterResults and tmpResult
2951 if not tmpResult:
2952 main.log.error( str( i ) + " is not in the in-memory "
2953 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002954 utilities.assert_equals( expect=True,
2955 actual=iCounterResults,
2956 onpass="In memory counter incremented",
2957 onfail="Error incrementing in memory" +
2958 " counter" )
2959
2960 main.step( "Check counters are consistant across nodes" )
2961 onosCounters = []
2962 threads = []
2963 for i in range( numControllers ):
2964 t = main.Thread( target=CLIs[i].counters,
2965 name="counters-" + str( i ) )
2966 threads.append( t )
2967 t.start()
2968 for t in threads:
2969 t.join()
2970 onosCounters.append( t.result )
2971 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2972 if all( tmp ):
2973 main.log.info( "Counters are consistent across all nodes" )
2974 consistentCounterResults = main.TRUE
2975 else:
2976 main.log.error( "Counters are not consistent across all nodes" )
2977 consistentCounterResults = main.FALSE
2978 utilities.assert_equals( expect=main.TRUE,
2979 actual=consistentCounterResults,
2980 onpass="ONOS counters are consistent " +
2981 "across nodes",
2982 onfail="ONOS Counters are inconsistent " +
2983 "across nodes" )
2984
2985 main.step( "Counters we added have the correct values" )
2986 correctResults = main.TRUE
2987 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002988 current = json.loads( onosCounters[i] )
2989 pValue = None
2990 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002991 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002992 for database in current:
2993 partitioned = database.get( 'partitionedDatabaseCounters' )
2994 if partitioned:
2995 for value in partitioned:
2996 if value.get( 'name' ) == pCounterName:
2997 pValue = value.get( 'value' )
2998 break
2999 inMemory = database.get( 'inMemoryDatabaseCounters' )
3000 if inMemory:
3001 for value in inMemory:
3002 if value.get( 'name' ) == iCounterName:
3003 iValue = value.get( 'value' )
3004 break
Jon Hall390696c2015-05-05 17:13:41 -07003005 except AttributeError, e:
3006 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3007 "is not as expected" )
3008 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003009 if pValue == pCounterValue:
3010 main.log.info( "Partitioned counter value is correct" )
3011 else:
3012 main.log.error( "Partitioned counter value is incorrect," +
3013 " expected value: " + str( pCounterValue )
3014 + " current value: " + str( pValue ) )
3015 correctResults = main.FALSE
3016 if iValue == iCounterValue:
3017 main.log.info( "In memory counter value is correct" )
3018 else:
3019 main.log.error( "In memory counter value is incorrect, " +
3020 "expected value: " + str( iCounterValue ) +
3021 " current value: " + str( iValue ) )
3022 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003023 utilities.assert_equals( expect=main.TRUE,
3024 actual=correctResults,
3025 onpass="Added counters are correct",
3026 onfail="Added counters are incorrect" )
3027 # DISTRIBUTED SETS
3028 main.step( "Distributed Set get" )
3029 size = len( onosSet )
3030 getResponses = []
3031 threads = []
3032 for i in range( numControllers ):
3033 t = main.Thread( target=CLIs[i].setTestGet,
3034 name="setTestGet-" + str( i ),
3035 args=[ onosSetName ] )
3036 threads.append( t )
3037 t.start()
3038 for t in threads:
3039 t.join()
3040 getResponses.append( t.result )
3041
3042 getResults = main.TRUE
3043 for i in range( numControllers ):
3044 if isinstance( getResponses[ i ], list):
3045 current = set( getResponses[ i ] )
3046 if len( current ) == len( getResponses[ i ] ):
3047 # no repeats
3048 if onosSet != current:
3049 main.log.error( "ONOS" + str( i + 1 ) +
3050 " has incorrect view" +
3051 " of set " + onosSetName + ":\n" +
3052 str( getResponses[ i ] ) )
3053 main.log.debug( "Expected: " + str( onosSet ) )
3054 main.log.debug( "Actual: " + str( current ) )
3055 getResults = main.FALSE
3056 else:
3057 # error, set is not a set
3058 main.log.error( "ONOS" + str( i + 1 ) +
3059 " has repeat elements in" +
3060 " set " + onosSetName + ":\n" +
3061 str( getResponses[ i ] ) )
3062 getResults = main.FALSE
3063 elif getResponses[ i ] == main.ERROR:
3064 getResults = main.FALSE
3065 utilities.assert_equals( expect=main.TRUE,
3066 actual=getResults,
3067 onpass="Set elements are correct",
3068 onfail="Set elements are incorrect" )
3069
3070 main.step( "Distributed Set size" )
3071 sizeResponses = []
3072 threads = []
3073 for i in range( numControllers ):
3074 t = main.Thread( target=CLIs[i].setTestSize,
3075 name="setTestSize-" + str( i ),
3076 args=[ onosSetName ] )
3077 threads.append( t )
3078 t.start()
3079 for t in threads:
3080 t.join()
3081 sizeResponses.append( t.result )
3082
3083 sizeResults = main.TRUE
3084 for i in range( numControllers ):
3085 if size != sizeResponses[ i ]:
3086 sizeResults = main.FALSE
3087 main.log.error( "ONOS" + str( i + 1 ) +
3088 " expected a size of " + str( size ) +
3089 " for set " + onosSetName +
3090 " but got " + str( sizeResponses[ i ] ) )
3091 utilities.assert_equals( expect=main.TRUE,
3092 actual=sizeResults,
3093 onpass="Set sizes are correct",
3094 onfail="Set sizes are incorrect" )
3095
3096 main.step( "Distributed Set add()" )
3097 onosSet.add( addValue )
3098 addResponses = []
3099 threads = []
3100 for i in range( numControllers ):
3101 t = main.Thread( target=CLIs[i].setTestAdd,
3102 name="setTestAdd-" + str( i ),
3103 args=[ onosSetName, addValue ] )
3104 threads.append( t )
3105 t.start()
3106 for t in threads:
3107 t.join()
3108 addResponses.append( t.result )
3109
3110 # main.TRUE = successfully changed the set
3111 # main.FALSE = action resulted in no change in set
3112 # main.ERROR - Some error in executing the function
3113 addResults = main.TRUE
3114 for i in range( numControllers ):
3115 if addResponses[ i ] == main.TRUE:
3116 # All is well
3117 pass
3118 elif addResponses[ i ] == main.FALSE:
3119 # Already in set, probably fine
3120 pass
3121 elif addResponses[ i ] == main.ERROR:
3122 # Error in execution
3123 addResults = main.FALSE
3124 else:
3125 # unexpected result
3126 addResults = main.FALSE
3127 if addResults != main.TRUE:
3128 main.log.error( "Error executing set add" )
3129
3130 # Check if set is still correct
3131 size = len( onosSet )
3132 getResponses = []
3133 threads = []
3134 for i in range( numControllers ):
3135 t = main.Thread( target=CLIs[i].setTestGet,
3136 name="setTestGet-" + str( i ),
3137 args=[ onosSetName ] )
3138 threads.append( t )
3139 t.start()
3140 for t in threads:
3141 t.join()
3142 getResponses.append( t.result )
3143 getResults = main.TRUE
3144 for i in range( numControllers ):
3145 if isinstance( getResponses[ i ], list):
3146 current = set( getResponses[ i ] )
3147 if len( current ) == len( getResponses[ i ] ):
3148 # no repeats
3149 if onosSet != current:
3150 main.log.error( "ONOS" + str( i + 1 ) +
3151 " has incorrect view" +
3152 " of set " + onosSetName + ":\n" +
3153 str( getResponses[ i ] ) )
3154 main.log.debug( "Expected: " + str( onosSet ) )
3155 main.log.debug( "Actual: " + str( current ) )
3156 getResults = main.FALSE
3157 else:
3158 # error, set is not a set
3159 main.log.error( "ONOS" + str( i + 1 ) +
3160 " has repeat elements in" +
3161 " set " + onosSetName + ":\n" +
3162 str( getResponses[ i ] ) )
3163 getResults = main.FALSE
3164 elif getResponses[ i ] == main.ERROR:
3165 getResults = main.FALSE
3166 sizeResponses = []
3167 threads = []
3168 for i in range( numControllers ):
3169 t = main.Thread( target=CLIs[i].setTestSize,
3170 name="setTestSize-" + str( i ),
3171 args=[ onosSetName ] )
3172 threads.append( t )
3173 t.start()
3174 for t in threads:
3175 t.join()
3176 sizeResponses.append( t.result )
3177 sizeResults = main.TRUE
3178 for i in range( numControllers ):
3179 if size != sizeResponses[ i ]:
3180 sizeResults = main.FALSE
3181 main.log.error( "ONOS" + str( i + 1 ) +
3182 " expected a size of " + str( size ) +
3183 " for set " + onosSetName +
3184 " but got " + str( sizeResponses[ i ] ) )
3185 addResults = addResults and getResults and sizeResults
3186 utilities.assert_equals( expect=main.TRUE,
3187 actual=addResults,
3188 onpass="Set add correct",
3189 onfail="Set add was incorrect" )
3190
3191 main.step( "Distributed Set addAll()" )
3192 onosSet.update( addAllValue.split() )
3193 addResponses = []
3194 threads = []
3195 for i in range( numControllers ):
3196 t = main.Thread( target=CLIs[i].setTestAdd,
3197 name="setTestAddAll-" + str( i ),
3198 args=[ onosSetName, addAllValue ] )
3199 threads.append( t )
3200 t.start()
3201 for t in threads:
3202 t.join()
3203 addResponses.append( t.result )
3204
3205 # main.TRUE = successfully changed the set
3206 # main.FALSE = action resulted in no change in set
3207 # main.ERROR - Some error in executing the function
3208 addAllResults = main.TRUE
3209 for i in range( numControllers ):
3210 if addResponses[ i ] == main.TRUE:
3211 # All is well
3212 pass
3213 elif addResponses[ i ] == main.FALSE:
3214 # Already in set, probably fine
3215 pass
3216 elif addResponses[ i ] == main.ERROR:
3217 # Error in execution
3218 addAllResults = main.FALSE
3219 else:
3220 # unexpected result
3221 addAllResults = main.FALSE
3222 if addAllResults != main.TRUE:
3223 main.log.error( "Error executing set addAll" )
3224
3225 # Check if set is still correct
3226 size = len( onosSet )
3227 getResponses = []
3228 threads = []
3229 for i in range( numControllers ):
3230 t = main.Thread( target=CLIs[i].setTestGet,
3231 name="setTestGet-" + str( i ),
3232 args=[ onosSetName ] )
3233 threads.append( t )
3234 t.start()
3235 for t in threads:
3236 t.join()
3237 getResponses.append( t.result )
3238 getResults = main.TRUE
3239 for i in range( numControllers ):
3240 if isinstance( getResponses[ i ], list):
3241 current = set( getResponses[ i ] )
3242 if len( current ) == len( getResponses[ i ] ):
3243 # no repeats
3244 if onosSet != current:
3245 main.log.error( "ONOS" + str( i + 1 ) +
3246 " has incorrect view" +
3247 " of set " + onosSetName + ":\n" +
3248 str( getResponses[ i ] ) )
3249 main.log.debug( "Expected: " + str( onosSet ) )
3250 main.log.debug( "Actual: " + str( current ) )
3251 getResults = main.FALSE
3252 else:
3253 # error, set is not a set
3254 main.log.error( "ONOS" + str( i + 1 ) +
3255 " has repeat elements in" +
3256 " set " + onosSetName + ":\n" +
3257 str( getResponses[ i ] ) )
3258 getResults = main.FALSE
3259 elif getResponses[ i ] == main.ERROR:
3260 getResults = main.FALSE
3261 sizeResponses = []
3262 threads = []
3263 for i in range( numControllers ):
3264 t = main.Thread( target=CLIs[i].setTestSize,
3265 name="setTestSize-" + str( i ),
3266 args=[ onosSetName ] )
3267 threads.append( t )
3268 t.start()
3269 for t in threads:
3270 t.join()
3271 sizeResponses.append( t.result )
3272 sizeResults = main.TRUE
3273 for i in range( numControllers ):
3274 if size != sizeResponses[ i ]:
3275 sizeResults = main.FALSE
3276 main.log.error( "ONOS" + str( i + 1 ) +
3277 " expected a size of " + str( size ) +
3278 " for set " + onosSetName +
3279 " but got " + str( sizeResponses[ i ] ) )
3280 addAllResults = addAllResults and getResults and sizeResults
3281 utilities.assert_equals( expect=main.TRUE,
3282 actual=addAllResults,
3283 onpass="Set addAll correct",
3284 onfail="Set addAll was incorrect" )
3285
3286 main.step( "Distributed Set contains()" )
3287 containsResponses = []
3288 threads = []
3289 for i in range( numControllers ):
3290 t = main.Thread( target=CLIs[i].setTestGet,
3291 name="setContains-" + str( i ),
3292 args=[ onosSetName ],
3293 kwargs={ "values": addValue } )
3294 threads.append( t )
3295 t.start()
3296 for t in threads:
3297 t.join()
3298 # NOTE: This is the tuple
3299 containsResponses.append( t.result )
3300
3301 containsResults = main.TRUE
3302 for i in range( numControllers ):
3303 if containsResponses[ i ] == main.ERROR:
3304 containsResults = main.FALSE
3305 else:
3306 containsResults = containsResults and\
3307 containsResponses[ i ][ 1 ]
3308 utilities.assert_equals( expect=main.TRUE,
3309 actual=containsResults,
3310 onpass="Set contains is functional",
3311 onfail="Set contains failed" )
3312
3313 main.step( "Distributed Set containsAll()" )
3314 containsAllResponses = []
3315 threads = []
3316 for i in range( numControllers ):
3317 t = main.Thread( target=CLIs[i].setTestGet,
3318 name="setContainsAll-" + str( i ),
3319 args=[ onosSetName ],
3320 kwargs={ "values": addAllValue } )
3321 threads.append( t )
3322 t.start()
3323 for t in threads:
3324 t.join()
3325 # NOTE: This is the tuple
3326 containsAllResponses.append( t.result )
3327
3328 containsAllResults = main.TRUE
3329 for i in range( numControllers ):
3330 if containsResponses[ i ] == main.ERROR:
3331 containsResults = main.FALSE
3332 else:
3333 containsResults = containsResults and\
3334 containsResponses[ i ][ 1 ]
3335 utilities.assert_equals( expect=main.TRUE,
3336 actual=containsAllResults,
3337 onpass="Set containsAll is functional",
3338 onfail="Set containsAll failed" )
3339
3340 main.step( "Distributed Set remove()" )
3341 onosSet.remove( addValue )
3342 removeResponses = []
3343 threads = []
3344 for i in range( numControllers ):
3345 t = main.Thread( target=CLIs[i].setTestRemove,
3346 name="setTestRemove-" + str( i ),
3347 args=[ onosSetName, addValue ] )
3348 threads.append( t )
3349 t.start()
3350 for t in threads:
3351 t.join()
3352 removeResponses.append( t.result )
3353
3354 # main.TRUE = successfully changed the set
3355 # main.FALSE = action resulted in no change in set
3356 # main.ERROR - Some error in executing the function
3357 removeResults = main.TRUE
3358 for i in range( numControllers ):
3359 if removeResponses[ i ] == main.TRUE:
3360 # All is well
3361 pass
3362 elif removeResponses[ i ] == main.FALSE:
3363 # not in set, probably fine
3364 pass
3365 elif removeResponses[ i ] == main.ERROR:
3366 # Error in execution
3367 removeResults = main.FALSE
3368 else:
3369 # unexpected result
3370 removeResults = main.FALSE
3371 if removeResults != main.TRUE:
3372 main.log.error( "Error executing set remove" )
3373
3374 # Check if set is still correct
3375 size = len( onosSet )
3376 getResponses = []
3377 threads = []
3378 for i in range( numControllers ):
3379 t = main.Thread( target=CLIs[i].setTestGet,
3380 name="setTestGet-" + str( i ),
3381 args=[ onosSetName ] )
3382 threads.append( t )
3383 t.start()
3384 for t in threads:
3385 t.join()
3386 getResponses.append( t.result )
3387 getResults = main.TRUE
3388 for i in range( numControllers ):
3389 if isinstance( getResponses[ i ], list):
3390 current = set( getResponses[ i ] )
3391 if len( current ) == len( getResponses[ i ] ):
3392 # no repeats
3393 if onosSet != current:
3394 main.log.error( "ONOS" + str( i + 1 ) +
3395 " has incorrect view" +
3396 " of set " + onosSetName + ":\n" +
3397 str( getResponses[ i ] ) )
3398 main.log.debug( "Expected: " + str( onosSet ) )
3399 main.log.debug( "Actual: " + str( current ) )
3400 getResults = main.FALSE
3401 else:
3402 # error, set is not a set
3403 main.log.error( "ONOS" + str( i + 1 ) +
3404 " has repeat elements in" +
3405 " set " + onosSetName + ":\n" +
3406 str( getResponses[ i ] ) )
3407 getResults = main.FALSE
3408 elif getResponses[ i ] == main.ERROR:
3409 getResults = main.FALSE
3410 sizeResponses = []
3411 threads = []
3412 for i in range( numControllers ):
3413 t = main.Thread( target=CLIs[i].setTestSize,
3414 name="setTestSize-" + str( i ),
3415 args=[ onosSetName ] )
3416 threads.append( t )
3417 t.start()
3418 for t in threads:
3419 t.join()
3420 sizeResponses.append( t.result )
3421 sizeResults = main.TRUE
3422 for i in range( numControllers ):
3423 if size != sizeResponses[ i ]:
3424 sizeResults = main.FALSE
3425 main.log.error( "ONOS" + str( i + 1 ) +
3426 " expected a size of " + str( size ) +
3427 " for set " + onosSetName +
3428 " but got " + str( sizeResponses[ i ] ) )
3429 removeResults = removeResults and getResults and sizeResults
3430 utilities.assert_equals( expect=main.TRUE,
3431 actual=removeResults,
3432 onpass="Set remove correct",
3433 onfail="Set remove was incorrect" )
3434
3435 main.step( "Distributed Set removeAll()" )
3436 onosSet.difference_update( addAllValue.split() )
3437 removeAllResponses = []
3438 threads = []
3439 try:
3440 for i in range( numControllers ):
3441 t = main.Thread( target=CLIs[i].setTestRemove,
3442 name="setTestRemoveAll-" + str( i ),
3443 args=[ onosSetName, addAllValue ] )
3444 threads.append( t )
3445 t.start()
3446 for t in threads:
3447 t.join()
3448 removeAllResponses.append( t.result )
3449 except Exception, e:
3450 main.log.exception(e)
3451
3452 # main.TRUE = successfully changed the set
3453 # main.FALSE = action resulted in no change in set
3454 # main.ERROR - Some error in executing the function
3455 removeAllResults = main.TRUE
3456 for i in range( numControllers ):
3457 if removeAllResponses[ i ] == main.TRUE:
3458 # All is well
3459 pass
3460 elif removeAllResponses[ i ] == main.FALSE:
3461 # not in set, probably fine
3462 pass
3463 elif removeAllResponses[ i ] == main.ERROR:
3464 # Error in execution
3465 removeAllResults = main.FALSE
3466 else:
3467 # unexpected result
3468 removeAllResults = main.FALSE
3469 if removeAllResults != main.TRUE:
3470 main.log.error( "Error executing set removeAll" )
3471
3472 # Check if set is still correct
3473 size = len( onosSet )
3474 getResponses = []
3475 threads = []
3476 for i in range( numControllers ):
3477 t = main.Thread( target=CLIs[i].setTestGet,
3478 name="setTestGet-" + str( i ),
3479 args=[ onosSetName ] )
3480 threads.append( t )
3481 t.start()
3482 for t in threads:
3483 t.join()
3484 getResponses.append( t.result )
3485 getResults = main.TRUE
3486 for i in range( numControllers ):
3487 if isinstance( getResponses[ i ], list):
3488 current = set( getResponses[ i ] )
3489 if len( current ) == len( getResponses[ i ] ):
3490 # no repeats
3491 if onosSet != current:
3492 main.log.error( "ONOS" + str( i + 1 ) +
3493 " has incorrect view" +
3494 " of set " + onosSetName + ":\n" +
3495 str( getResponses[ i ] ) )
3496 main.log.debug( "Expected: " + str( onosSet ) )
3497 main.log.debug( "Actual: " + str( current ) )
3498 getResults = main.FALSE
3499 else:
3500 # error, set is not a set
3501 main.log.error( "ONOS" + str( i + 1 ) +
3502 " has repeat elements in" +
3503 " set " + onosSetName + ":\n" +
3504 str( getResponses[ i ] ) )
3505 getResults = main.FALSE
3506 elif getResponses[ i ] == main.ERROR:
3507 getResults = main.FALSE
3508 sizeResponses = []
3509 threads = []
3510 for i in range( numControllers ):
3511 t = main.Thread( target=CLIs[i].setTestSize,
3512 name="setTestSize-" + str( i ),
3513 args=[ onosSetName ] )
3514 threads.append( t )
3515 t.start()
3516 for t in threads:
3517 t.join()
3518 sizeResponses.append( t.result )
3519 sizeResults = main.TRUE
3520 for i in range( numControllers ):
3521 if size != sizeResponses[ i ]:
3522 sizeResults = main.FALSE
3523 main.log.error( "ONOS" + str( i + 1 ) +
3524 " expected a size of " + str( size ) +
3525 " for set " + onosSetName +
3526 " but got " + str( sizeResponses[ i ] ) )
3527 removeAllResults = removeAllResults and getResults and sizeResults
3528 utilities.assert_equals( expect=main.TRUE,
3529 actual=removeAllResults,
3530 onpass="Set removeAll correct",
3531 onfail="Set removeAll was incorrect" )
3532
3533 main.step( "Distributed Set addAll()" )
3534 onosSet.update( addAllValue.split() )
3535 addResponses = []
3536 threads = []
3537 for i in range( numControllers ):
3538 t = main.Thread( target=CLIs[i].setTestAdd,
3539 name="setTestAddAll-" + str( i ),
3540 args=[ onosSetName, addAllValue ] )
3541 threads.append( t )
3542 t.start()
3543 for t in threads:
3544 t.join()
3545 addResponses.append( t.result )
3546
3547 # main.TRUE = successfully changed the set
3548 # main.FALSE = action resulted in no change in set
3549 # main.ERROR - Some error in executing the function
3550 addAllResults = main.TRUE
3551 for i in range( numControllers ):
3552 if addResponses[ i ] == main.TRUE:
3553 # All is well
3554 pass
3555 elif addResponses[ i ] == main.FALSE:
3556 # Already in set, probably fine
3557 pass
3558 elif addResponses[ i ] == main.ERROR:
3559 # Error in execution
3560 addAllResults = main.FALSE
3561 else:
3562 # unexpected result
3563 addAllResults = main.FALSE
3564 if addAllResults != main.TRUE:
3565 main.log.error( "Error executing set addAll" )
3566
3567 # Check if set is still correct
3568 size = len( onosSet )
3569 getResponses = []
3570 threads = []
3571 for i in range( numControllers ):
3572 t = main.Thread( target=CLIs[i].setTestGet,
3573 name="setTestGet-" + str( i ),
3574 args=[ onosSetName ] )
3575 threads.append( t )
3576 t.start()
3577 for t in threads:
3578 t.join()
3579 getResponses.append( t.result )
3580 getResults = main.TRUE
3581 for i in range( numControllers ):
3582 if isinstance( getResponses[ i ], list):
3583 current = set( getResponses[ i ] )
3584 if len( current ) == len( getResponses[ i ] ):
3585 # no repeats
3586 if onosSet != current:
3587 main.log.error( "ONOS" + str( i + 1 ) +
3588 " has incorrect view" +
3589 " of set " + onosSetName + ":\n" +
3590 str( getResponses[ i ] ) )
3591 main.log.debug( "Expected: " + str( onosSet ) )
3592 main.log.debug( "Actual: " + str( current ) )
3593 getResults = main.FALSE
3594 else:
3595 # error, set is not a set
3596 main.log.error( "ONOS" + str( i + 1 ) +
3597 " has repeat elements in" +
3598 " set " + onosSetName + ":\n" +
3599 str( getResponses[ i ] ) )
3600 getResults = main.FALSE
3601 elif getResponses[ i ] == main.ERROR:
3602 getResults = main.FALSE
3603 sizeResponses = []
3604 threads = []
3605 for i in range( numControllers ):
3606 t = main.Thread( target=CLIs[i].setTestSize,
3607 name="setTestSize-" + str( i ),
3608 args=[ onosSetName ] )
3609 threads.append( t )
3610 t.start()
3611 for t in threads:
3612 t.join()
3613 sizeResponses.append( t.result )
3614 sizeResults = main.TRUE
3615 for i in range( numControllers ):
3616 if size != sizeResponses[ i ]:
3617 sizeResults = main.FALSE
3618 main.log.error( "ONOS" + str( i + 1 ) +
3619 " expected a size of " + str( size ) +
3620 " for set " + onosSetName +
3621 " but got " + str( sizeResponses[ i ] ) )
3622 addAllResults = addAllResults and getResults and sizeResults
3623 utilities.assert_equals( expect=main.TRUE,
3624 actual=addAllResults,
3625 onpass="Set addAll correct",
3626 onfail="Set addAll was incorrect" )
3627
3628 main.step( "Distributed Set clear()" )
3629 onosSet.clear()
3630 clearResponses = []
3631 threads = []
3632 for i in range( numControllers ):
3633 t = main.Thread( target=CLIs[i].setTestRemove,
3634 name="setTestClear-" + str( i ),
3635 args=[ onosSetName, " "], # Values doesn't matter
3636 kwargs={ "clear": True } )
3637 threads.append( t )
3638 t.start()
3639 for t in threads:
3640 t.join()
3641 clearResponses.append( t.result )
3642
3643 # main.TRUE = successfully changed the set
3644 # main.FALSE = action resulted in no change in set
3645 # main.ERROR - Some error in executing the function
3646 clearResults = main.TRUE
3647 for i in range( numControllers ):
3648 if clearResponses[ i ] == main.TRUE:
3649 # All is well
3650 pass
3651 elif clearResponses[ i ] == main.FALSE:
3652 # Nothing set, probably fine
3653 pass
3654 elif clearResponses[ i ] == main.ERROR:
3655 # Error in execution
3656 clearResults = main.FALSE
3657 else:
3658 # unexpected result
3659 clearResults = main.FALSE
3660 if clearResults != main.TRUE:
3661 main.log.error( "Error executing set clear" )
3662
3663 # Check if set is still correct
3664 size = len( onosSet )
3665 getResponses = []
3666 threads = []
3667 for i in range( numControllers ):
3668 t = main.Thread( target=CLIs[i].setTestGet,
3669 name="setTestGet-" + str( i ),
3670 args=[ onosSetName ] )
3671 threads.append( t )
3672 t.start()
3673 for t in threads:
3674 t.join()
3675 getResponses.append( t.result )
3676 getResults = main.TRUE
3677 for i in range( numControllers ):
3678 if isinstance( getResponses[ i ], list):
3679 current = set( getResponses[ i ] )
3680 if len( current ) == len( getResponses[ i ] ):
3681 # no repeats
3682 if onosSet != current:
3683 main.log.error( "ONOS" + str( i + 1 ) +
3684 " has incorrect view" +
3685 " of set " + onosSetName + ":\n" +
3686 str( getResponses[ i ] ) )
3687 main.log.debug( "Expected: " + str( onosSet ) )
3688 main.log.debug( "Actual: " + str( current ) )
3689 getResults = main.FALSE
3690 else:
3691 # error, set is not a set
3692 main.log.error( "ONOS" + str( i + 1 ) +
3693 " has repeat elements in" +
3694 " set " + onosSetName + ":\n" +
3695 str( getResponses[ i ] ) )
3696 getResults = main.FALSE
3697 elif getResponses[ i ] == main.ERROR:
3698 getResults = main.FALSE
3699 sizeResponses = []
3700 threads = []
3701 for i in range( numControllers ):
3702 t = main.Thread( target=CLIs[i].setTestSize,
3703 name="setTestSize-" + str( i ),
3704 args=[ onosSetName ] )
3705 threads.append( t )
3706 t.start()
3707 for t in threads:
3708 t.join()
3709 sizeResponses.append( t.result )
3710 sizeResults = main.TRUE
3711 for i in range( numControllers ):
3712 if size != sizeResponses[ i ]:
3713 sizeResults = main.FALSE
3714 main.log.error( "ONOS" + str( i + 1 ) +
3715 " expected a size of " + str( size ) +
3716 " for set " + onosSetName +
3717 " but got " + str( sizeResponses[ i ] ) )
3718 clearResults = clearResults and getResults and sizeResults
3719 utilities.assert_equals( expect=main.TRUE,
3720 actual=clearResults,
3721 onpass="Set clear correct",
3722 onfail="Set clear was incorrect" )
3723
3724 main.step( "Distributed Set addAll()" )
3725 onosSet.update( addAllValue.split() )
3726 addResponses = []
3727 threads = []
3728 for i in range( numControllers ):
3729 t = main.Thread( target=CLIs[i].setTestAdd,
3730 name="setTestAddAll-" + str( i ),
3731 args=[ onosSetName, addAllValue ] )
3732 threads.append( t )
3733 t.start()
3734 for t in threads:
3735 t.join()
3736 addResponses.append( t.result )
3737
3738 # main.TRUE = successfully changed the set
3739 # main.FALSE = action resulted in no change in set
3740 # main.ERROR - Some error in executing the function
3741 addAllResults = main.TRUE
3742 for i in range( numControllers ):
3743 if addResponses[ i ] == main.TRUE:
3744 # All is well
3745 pass
3746 elif addResponses[ i ] == main.FALSE:
3747 # Already in set, probably fine
3748 pass
3749 elif addResponses[ i ] == main.ERROR:
3750 # Error in execution
3751 addAllResults = main.FALSE
3752 else:
3753 # unexpected result
3754 addAllResults = main.FALSE
3755 if addAllResults != main.TRUE:
3756 main.log.error( "Error executing set addAll" )
3757
3758 # Check if set is still correct
3759 size = len( onosSet )
3760 getResponses = []
3761 threads = []
3762 for i in range( numControllers ):
3763 t = main.Thread( target=CLIs[i].setTestGet,
3764 name="setTestGet-" + str( i ),
3765 args=[ onosSetName ] )
3766 threads.append( t )
3767 t.start()
3768 for t in threads:
3769 t.join()
3770 getResponses.append( t.result )
3771 getResults = main.TRUE
3772 for i in range( numControllers ):
3773 if isinstance( getResponses[ i ], list):
3774 current = set( getResponses[ i ] )
3775 if len( current ) == len( getResponses[ i ] ):
3776 # no repeats
3777 if onosSet != current:
3778 main.log.error( "ONOS" + str( i + 1 ) +
3779 " has incorrect view" +
3780 " of set " + onosSetName + ":\n" +
3781 str( getResponses[ i ] ) )
3782 main.log.debug( "Expected: " + str( onosSet ) )
3783 main.log.debug( "Actual: " + str( current ) )
3784 getResults = main.FALSE
3785 else:
3786 # error, set is not a set
3787 main.log.error( "ONOS" + str( i + 1 ) +
3788 " has repeat elements in" +
3789 " set " + onosSetName + ":\n" +
3790 str( getResponses[ i ] ) )
3791 getResults = main.FALSE
3792 elif getResponses[ i ] == main.ERROR:
3793 getResults = main.FALSE
3794 sizeResponses = []
3795 threads = []
3796 for i in range( numControllers ):
3797 t = main.Thread( target=CLIs[i].setTestSize,
3798 name="setTestSize-" + str( i ),
3799 args=[ onosSetName ] )
3800 threads.append( t )
3801 t.start()
3802 for t in threads:
3803 t.join()
3804 sizeResponses.append( t.result )
3805 sizeResults = main.TRUE
3806 for i in range( numControllers ):
3807 if size != sizeResponses[ i ]:
3808 sizeResults = main.FALSE
3809 main.log.error( "ONOS" + str( i + 1 ) +
3810 " expected a size of " + str( size ) +
3811 " for set " + onosSetName +
3812 " but got " + str( sizeResponses[ i ] ) )
3813 addAllResults = addAllResults and getResults and sizeResults
3814 utilities.assert_equals( expect=main.TRUE,
3815 actual=addAllResults,
3816 onpass="Set addAll correct",
3817 onfail="Set addAll was incorrect" )
3818
3819 main.step( "Distributed Set retain()" )
3820 onosSet.intersection_update( retainValue.split() )
3821 retainResponses = []
3822 threads = []
3823 for i in range( numControllers ):
3824 t = main.Thread( target=CLIs[i].setTestRemove,
3825 name="setTestRetain-" + str( i ),
3826 args=[ onosSetName, retainValue ],
3827 kwargs={ "retain": True } )
3828 threads.append( t )
3829 t.start()
3830 for t in threads:
3831 t.join()
3832 retainResponses.append( t.result )
3833
3834 # main.TRUE = successfully changed the set
3835 # main.FALSE = action resulted in no change in set
3836 # main.ERROR - Some error in executing the function
3837 retainResults = main.TRUE
3838 for i in range( numControllers ):
3839 if retainResponses[ i ] == main.TRUE:
3840 # All is well
3841 pass
3842 elif retainResponses[ i ] == main.FALSE:
3843 # Already in set, probably fine
3844 pass
3845 elif retainResponses[ i ] == main.ERROR:
3846 # Error in execution
3847 retainResults = main.FALSE
3848 else:
3849 # unexpected result
3850 retainResults = main.FALSE
3851 if retainResults != main.TRUE:
3852 main.log.error( "Error executing set retain" )
3853
3854 # Check if set is still correct
3855 size = len( onosSet )
3856 getResponses = []
3857 threads = []
3858 for i in range( numControllers ):
3859 t = main.Thread( target=CLIs[i].setTestGet,
3860 name="setTestGet-" + str( i ),
3861 args=[ onosSetName ] )
3862 threads.append( t )
3863 t.start()
3864 for t in threads:
3865 t.join()
3866 getResponses.append( t.result )
3867 getResults = main.TRUE
3868 for i in range( numControllers ):
3869 if isinstance( getResponses[ i ], list):
3870 current = set( getResponses[ i ] )
3871 if len( current ) == len( getResponses[ i ] ):
3872 # no repeats
3873 if onosSet != current:
3874 main.log.error( "ONOS" + str( i + 1 ) +
3875 " has incorrect view" +
3876 " of set " + onosSetName + ":\n" +
3877 str( getResponses[ i ] ) )
3878 main.log.debug( "Expected: " + str( onosSet ) )
3879 main.log.debug( "Actual: " + str( current ) )
3880 getResults = main.FALSE
3881 else:
3882 # error, set is not a set
3883 main.log.error( "ONOS" + str( i + 1 ) +
3884 " has repeat elements in" +
3885 " set " + onosSetName + ":\n" +
3886 str( getResponses[ i ] ) )
3887 getResults = main.FALSE
3888 elif getResponses[ i ] == main.ERROR:
3889 getResults = main.FALSE
3890 sizeResponses = []
3891 threads = []
3892 for i in range( numControllers ):
3893 t = main.Thread( target=CLIs[i].setTestSize,
3894 name="setTestSize-" + str( i ),
3895 args=[ onosSetName ] )
3896 threads.append( t )
3897 t.start()
3898 for t in threads:
3899 t.join()
3900 sizeResponses.append( t.result )
3901 sizeResults = main.TRUE
3902 for i in range( numControllers ):
3903 if size != sizeResponses[ i ]:
3904 sizeResults = main.FALSE
3905 main.log.error( "ONOS" + str( i + 1 ) +
3906 " expected a size of " +
3907 str( size ) + " for set " + onosSetName +
3908 " but got " + str( sizeResponses[ i ] ) )
3909 retainResults = retainResults and getResults and sizeResults
3910 utilities.assert_equals( expect=main.TRUE,
3911 actual=retainResults,
3912 onpass="Set retain correct",
3913 onfail="Set retain was incorrect" )
3914