blob: 83b4e51e568cdada1a69f2db2746ba0c86df9191 [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 Hall0f523f22015-07-06 09:31:09 -0700268 ipList = []
269 for i in range( numControllers ):
270 ipList.append( nodes[ i ].ip_address )
271 swList = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 for i in range( 1, 29 ):
Jon Hall0f523f22015-07-06 09:31:09 -0700273 swList.append( "s" + str( i ) )
274 main.Mininet1.assignSwController( sw=swList, ip=ipList )
Jon Hallb1290e82014-11-18 16:17:48 -0500275
Jon Hall8f89dda2015-01-22 16:03:33 -0800276 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800277 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800278 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800279 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800280 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800281 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800282 main.log.info( repr( response ) )
Jon Hall65844a32015-03-09 19:09:37 -0700283 for node in nodes:
284 if re.search( "tcp:" + node.ip_address, response ):
285 mastershipCheck = mastershipCheck and main.TRUE
286 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700287 main.log.error( "Error, node " + node.ip_address + " is " +
288 "not in the list of controllers s" +
289 str( i ) + " is connecting to." )
Jon Hall65844a32015-03-09 19:09:37 -0700290 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800291 utilities.assert_equals(
292 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800293 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800294 onpass="Switch mastership assigned correctly",
295 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700296
Jon Hallc9eabec2015-06-10 14:33:14 -0700297 def CASE21( self, main ):
298 """
299 Assign mastership to controllers
300 """
301 import re
302 import time
303 assert numControllers, "numControllers not defined"
304 assert main, "main not defined"
305 assert utilities.assert_equals, "utilities.assert_equals not defined"
306 assert CLIs, "CLIs not defined"
307 assert nodes, "nodes not defined"
308 assert ONOS1Port, "ONOS1Port not defined"
309 assert ONOS2Port, "ONOS2Port not defined"
310 assert ONOS3Port, "ONOS3Port not defined"
311 assert ONOS4Port, "ONOS4Port not defined"
312 assert ONOS5Port, "ONOS5Port not defined"
313 assert ONOS6Port, "ONOS6Port not defined"
314 assert ONOS7Port, "ONOS7Port not defined"
315
316 main.case( "Assigning Controller roles for switches" )
317 main.caseExplaination = "Check that ONOS is connected to each " +\
318 "device. Then manually assign" +\
319 " mastership to specific ONOS nodes using" +\
320 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700321 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800323 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700324
325 ipList = [ ]
326 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800327 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700328 for i in range( 1, 29 ): # switches 1 through 28
329 # set up correct variables:
330 if i == 1:
331 ip = nodes[ 0 ].ip_address # ONOS1
332 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
333 elif i == 2:
334 ip = nodes[ 1 ].ip_address # ONOS2
335 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
336 elif i == 3:
337 ip = nodes[ 1 ].ip_address # ONOS2
338 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
339 elif i == 4:
340 ip = nodes[ 3 ].ip_address # ONOS4
341 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
342 elif i == 5:
343 ip = nodes[ 2 ].ip_address # ONOS3
344 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
345 elif i == 6:
346 ip = nodes[ 2 ].ip_address # ONOS3
347 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
348 elif i == 7:
349 ip = nodes[ 5 ].ip_address # ONOS6
350 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
351 elif i >= 8 and i <= 17:
352 ip = nodes[ 4 ].ip_address # ONOS5
353 dpid = '3' + str( i ).zfill( 3 )
354 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
355 elif i >= 18 and i <= 27:
356 ip = nodes[ 6 ].ip_address # ONOS7
357 dpid = '6' + str( i ).zfill( 3 )
358 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
359 elif i == 28:
360 ip = nodes[ 0 ].ip_address # ONOS1
361 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
362 else:
363 main.log.error( "You didn't write an else statement for " +
364 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700365 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700366 # Assign switch
367 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
368 # TODO: make this controller dynamic
369 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
370 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700371 ipList.append( ip )
372 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800373 except ( AttributeError, AssertionError ):
374 main.log.exception( "Something is wrong with ONOS device view" )
375 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800376 utilities.assert_equals(
377 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800378 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800379 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800380 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800381
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.step( "Check mastership was correctly assigned" )
383 roleCheck = main.TRUE
384 # NOTE: This is due to the fact that device mastership change is not
385 # atomic and is actually a multi step process
386 time.sleep( 5 )
387 for i in range( len( ipList ) ):
388 ip = ipList[i]
389 deviceId = deviceList[i]
390 # Check assignment
391 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
392 if ip in master:
393 roleCheck = roleCheck and main.TRUE
394 else:
395 roleCheck = roleCheck and main.FALSE
396 main.log.error( "Error, controller " + ip + " is not" +
397 " master " + "of device " +
398 str( deviceId ) + ". Master is " +
399 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 utilities.assert_equals(
401 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800402 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800403 onpass="Switches were successfully reassigned to designated " +
404 "controller",
405 onfail="Switches were not successfully reassigned" )
Jon Hallb1290e82014-11-18 16:17:48 -0500406
Jon Hall6aec96b2015-01-19 14:49:31 -0800407 def CASE3( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500408 """
409 Assign intents
Jon Hallb1290e82014-11-18 16:17:48 -0500410 """
411 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800412 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700413 assert numControllers, "numControllers not defined"
414 assert main, "main not defined"
415 assert utilities.assert_equals, "utilities.assert_equals not defined"
416 assert CLIs, "CLIs not defined"
417 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800418 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700419 main.caseExplaination = "Discover hosts by using pingall then " +\
420 "assign predetermined host-to-host intents." +\
421 " After installation, check that the intent" +\
422 " is distributed to all nodes and the state" +\
423 " is INSTALLED"
Jon Hallb1290e82014-11-18 16:17:48 -0500424
Jon Hall6aec96b2015-01-19 14:49:31 -0800425 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700426 main.step( "Install reactive forwarding app" )
427 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
428 utilities.assert_equals( expect=main.TRUE, actual=installResults,
429 onpass="Install fwd successful",
430 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700431
Jon Hallfeff3082015-05-19 10:23:26 -0700432 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700433 appCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700434 threads = []
435 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700436 t = main.Thread( target=CLIs[i].appToIDCheck,
437 name="appToIDCheck-" + str( i ),
438 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700439 threads.append( t )
440 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700441
442 for t in threads:
443 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700444 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700445 if appCheck != main.TRUE:
446 main.log.warn( CLIs[0].apps() )
447 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700448 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
449 onpass="App Ids seem to be correct",
450 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800451
Jon Hallfeff3082015-05-19 10:23:26 -0700452 main.step( "Discovering Hosts( Via pingall for now )" )
453 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800454 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800455 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700456 for i in range(2): # Retry if pingall fails first time
457 time1 = time.time()
458 pingResult = main.Mininet1.pingall()
Jon Hall0f523f22015-07-06 09:31:09 -0700459 if i == 0:
460 utilities.assert_equals(
461 expect=main.TRUE,
462 actual=pingResult,
463 onpass="Reactive Pingall test passed",
464 onfail="Reactive Pingall failed, " +
465 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700466 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700467 main.log.info( "Time for pingall: %2f seconds" %
468 ( time2 - time1 ) )
469 # timeout for fwd flows
470 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800471 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700472 main.step( "Uninstall reactive forwarding app" )
473 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
474 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
475 onpass="Uninstall fwd successful",
476 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700477 '''
478 main.Mininet1.handle.sendline( "py [ h.cmd( \"arping -c 1 10.1.1.1 \" ) for h in net.hosts ] ")
479 import time
480 time.sleep(60)
481 '''
482
483 main.step( "Check app ids" )
Jon Hall65844a32015-03-09 19:09:37 -0700484 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700485 appCheck2 = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700486 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700487 t = main.Thread( target=CLIs[i].appToIDCheck,
488 name="appToIDCheck-" + str( i ),
489 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700490 threads.append( t )
491 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700492
493 for t in threads:
494 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700495 appCheck2 = appCheck2 and t.result
496 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700497 main.log.warn( CLIs[0].apps() )
498 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700499 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700500 onpass="App Ids seem to be correct",
501 onfail="Something is wrong with app Ids" )
Jon Hallb1290e82014-11-18 16:17:48 -0500502
Jon Hallfeff3082015-05-19 10:23:26 -0700503 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800504 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800505 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800506 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800507 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800508 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800509 for i in range( 8, 18 ):
510 main.log.info( "Adding host intent between h" + str( i ) +
511 " and h" + str( i + 10 ) )
512 host1 = "00:00:00:00:00:" + \
513 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
514 host2 = "00:00:00:00:00:" + \
515 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800516 # NOTE: getHost can return None
Jon Hall5cfd23c2015-03-19 11:40:57 -0700517 host1Dict = main.ONOScli1.getHost( host1 )
518 host2Dict = main.ONOScli1.getHost( host2 )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800519 host1Id = None
520 host2Id = None
521 if host1Dict and host2Dict:
522 host1Id = host1Dict.get( 'id', None )
523 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800524 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700525 nodeNum = ( i % 7 )
526 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800527 if tmpId:
528 main.log.info( "Added intent with id: " + tmpId )
529 intentIds.append( tmpId )
530 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700531 main.log.error( "addHostIntent returned: " +
532 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800533 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700534 main.log.error( "Error, getHost() failed for h" + str( i ) +
535 " and/or h" + str( i + 10 ) )
536 hosts = CLIs[ 0 ].hosts()
537 main.log.warn( "Hosts output: " )
538 try:
539 main.log.warn( json.dumps( json.loads( hosts ),
540 sort_keys=True,
541 indent=4,
542 separators=( ',', ': ' ) ) )
543 except ( ValueError, TypeError ):
544 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800545 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700546 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
547 onpass="Found a host id for each host",
548 onfail="Error looking up host ids" )
549
Jon Hall5cfd23c2015-03-19 11:40:57 -0700550 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800551 onosIds = main.ONOScli1.getAllIntentsId()
552 main.log.info( "Submitted intents: " + str( intentIds ) )
553 main.log.info( "Intents in ONOS: " + str( onosIds ) )
554 for intent in intentIds:
555 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700556 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800557 else:
558 intentAddResult = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700559 if intentAddResult:
560 intentStop = time.time()
561 else:
562 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800563 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800564 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800565 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -0700566 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800567 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
568 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700569 try:
570 for intent in json.loads( intents ):
571 state = intent.get( 'state', None )
572 if "INSTALLED" not in state:
573 installedCheck = False
574 intentId = intent.get( 'id', None )
575 intentStates.append( ( intentId, state ) )
576 except ( ValueError, TypeError ):
577 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800578 # add submitted intents not in the store
579 tmplist = [ i for i, s in intentStates ]
580 missingIntents = False
581 for i in intentIds:
582 if i not in tmplist:
583 intentStates.append( ( i, " - " ) )
584 missingIntents = True
585 intentStates.sort()
586 for i, s in intentStates:
587 count += 1
588 main.log.info( "%-6s%-15s%-15s" %
589 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700590 leaders = main.ONOScli1.leaders()
591 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700592 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700593 if leaders:
594 parsedLeaders = json.loads( leaders )
595 main.log.warn( json.dumps( parsedLeaders,
596 sort_keys=True,
597 indent=4,
598 separators=( ',', ': ' ) ) )
599 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700600 topics = []
601 for i in range( 14 ):
602 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700603 main.log.debug( topics )
604 ONOStopics = [ j['topic'] for j in parsedLeaders ]
605 for topic in topics:
606 if topic not in ONOStopics:
607 main.log.error( "Error: " + topic +
608 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700609 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700610 else:
611 main.log.error( "leaders() returned None" )
612 except ( ValueError, TypeError ):
613 main.log.exception( "Error parsing leaders" )
614 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700615 # Check all nodes
616 if missing:
617 for node in CLIs:
618 response = node.leaders( jsonFormat=False)
619 main.log.warn( str( node.name ) + " leaders output: \n" +
620 str( response ) )
621
Jon Hall5cfd23c2015-03-19 11:40:57 -0700622 partitions = main.ONOScli1.partitions()
623 try:
624 if partitions :
625 parsedPartitions = json.loads( partitions )
626 main.log.warn( json.dumps( parsedPartitions,
627 sort_keys=True,
628 indent=4,
629 separators=( ',', ': ' ) ) )
630 # TODO check for a leader in all paritions
631 # TODO check for consistency among nodes
632 else:
633 main.log.error( "partitions() returned None" )
634 except ( ValueError, TypeError ):
635 main.log.exception( "Error parsing partitions" )
636 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800637 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700638 try:
639 if pendingMap :
640 parsedPending = json.loads( pendingMap )
641 main.log.warn( json.dumps( parsedPending,
642 sort_keys=True,
643 indent=4,
644 separators=( ',', ': ' ) ) )
645 # TODO check something here?
646 else:
647 main.log.error( "pendingMap() returned None" )
648 except ( ValueError, TypeError ):
649 main.log.exception( "Error parsing pending map" )
650 main.log.error( repr( pendingMap ) )
651
Jon Hallfeff3082015-05-19 10:23:26 -0700652 intentAddResult = bool( intentAddResult and not missingIntents and
653 installedCheck )
654 if not intentAddResult:
655 main.log.error( "Error in pushing host intents to ONOS" )
656
Jon Hall390696c2015-05-05 17:13:41 -0700657 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700658 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700659 correct = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700660 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700661 for cli in CLIs:
662 onosIds = []
663 ids = cli.getAllIntentsId()
664 onosIds.append( ids )
665 main.log.debug( "Intents in " + cli.name + ": " +
666 str( sorted( onosIds ) ) )
667 if sorted( ids ) != sorted( intentIds ):
Jon Hallb87f3db2015-07-06 03:10:27 -0700668 main.log.debug( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700669 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700670 break
671 else:
672 intents = json.loads( cli.intents() )
673 for intent in intents:
674 if intent[ 'state' ] != "INSTALLED":
675 main.log.warn( "Intent " + intent[ 'id' ] +
676 " is " + intent[ 'state' ] )
677 correct = False
678 break
Jon Hall390696c2015-05-05 17:13:41 -0700679 if correct:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700680 break
Jon Hallc9eabec2015-06-10 14:33:14 -0700681 else:
682 time.sleep(1)
Jon Hall5cfd23c2015-03-19 11:40:57 -0700683 if not intentStop:
684 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700685 global gossipTime
Jon Hall5cfd23c2015-03-19 11:40:57 -0700686 gossipTime = intentStop - intentStart
687 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700688 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700689 # FIXME: make this time configurable/calculate based off of number of
690 # nodes and gossip rounds
Jon Hall5cfd23c2015-03-19 11:40:57 -0700691 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700692 expect=40, actual=gossipTime,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700693 onpass="ECM anti-entropy for intents worked within " +
694 "expected time",
695 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700696 if gossipTime <= 40:
Jon Halla9d26da2015-03-30 16:45:32 -0700697 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800698
Jon Hall63604932015-02-26 17:09:50 -0800699 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800700 import time
Jon Hall63604932015-02-26 17:09:50 -0800701 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800702 main.log.info( "Sleeping 60 seconds to see if intents are found" )
703 time.sleep( 60 )
704 onosIds = main.ONOScli1.getAllIntentsId()
705 main.log.info( "Submitted intents: " + str( intentIds ) )
706 main.log.info( "Intents in ONOS: " + str( onosIds ) )
707 # Print the intent states
708 intents = main.ONOScli1.intents()
709 intentStates = []
710 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
711 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700712 try:
713 for intent in json.loads( intents ):
714 # Iter through intents of a node
715 state = intent.get( 'state', None )
716 if "INSTALLED" not in state:
717 installedCheck = False
718 intentId = intent.get( 'id', None )
719 intentStates.append( ( intentId, state ) )
720 except ( ValueError, TypeError ):
721 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800722 # add submitted intents not in the store
723 tmplist = [ i for i, s in intentStates ]
724 for i in intentIds:
725 if i not in tmplist:
726 intentStates.append( ( i, " - " ) )
727 intentStates.sort()
728 for i, s in intentStates:
729 count += 1
730 main.log.info( "%-6s%-15s%-15s" %
731 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700732 leaders = main.ONOScli1.leaders()
733 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700734 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700735 if leaders:
736 parsedLeaders = json.loads( leaders )
737 main.log.warn( json.dumps( parsedLeaders,
738 sort_keys=True,
739 indent=4,
740 separators=( ',', ': ' ) ) )
741 # check for all intent partitions
742 # check for election
743 topics = []
744 for i in range( 14 ):
745 topics.append( "intent-partition-" + str( i ) )
746 # FIXME: this should only be after we start the app
747 topics.append( "org.onosproject.election" )
748 main.log.debug( topics )
749 ONOStopics = [ j['topic'] for j in parsedLeaders ]
750 for topic in topics:
751 if topic not in ONOStopics:
752 main.log.error( "Error: " + topic +
753 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700754 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700755 else:
756 main.log.error( "leaders() returned None" )
757 except ( ValueError, TypeError ):
758 main.log.exception( "Error parsing leaders" )
759 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700760 # Check all nodes
761 if missing:
762 for node in CLIs:
763 response = node.leaders( jsonFormat=False)
764 main.log.warn( str( node.name ) + " leaders output: \n" +
765 str( response ) )
766
Jon Hall5cfd23c2015-03-19 11:40:57 -0700767 partitions = main.ONOScli1.partitions()
768 try:
769 if partitions :
770 parsedPartitions = json.loads( partitions )
771 main.log.warn( json.dumps( parsedPartitions,
772 sort_keys=True,
773 indent=4,
774 separators=( ',', ': ' ) ) )
775 # TODO check for a leader in all paritions
776 # TODO check for consistency among nodes
777 else:
778 main.log.error( "partitions() returned None" )
779 except ( ValueError, TypeError ):
780 main.log.exception( "Error parsing partitions" )
781 main.log.error( repr( partitions ) )
782 pendingMap = main.ONOScli1.pendingMap()
783 try:
784 if pendingMap :
785 parsedPending = json.loads( pendingMap )
786 main.log.warn( json.dumps( parsedPending,
787 sort_keys=True,
788 indent=4,
789 separators=( ',', ': ' ) ) )
790 # TODO check something here?
791 else:
792 main.log.error( "pendingMap() returned None" )
793 except ( ValueError, TypeError ):
794 main.log.exception( "Error parsing pending map" )
795 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500796
Jon Hall6aec96b2015-01-19 14:49:31 -0800797 def CASE4( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500798 """
799 Ping across added host intents
800 """
Jon Hall58c76b72015-02-23 11:09:24 -0800801 import json
Jon Hall65844a32015-03-09 19:09:37 -0700802 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700803 assert numControllers, "numControllers not defined"
804 assert main, "main not defined"
805 assert utilities.assert_equals, "utilities.assert_equals not defined"
806 assert CLIs, "CLIs not defined"
807 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700808 main.case( "Verify connectivity by sendind traffic across Intents" )
809 main.caseExplaination = "Ping across added host intents to check " +\
810 "functionality and check the state of " +\
811 "the intent"
812 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800813 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800814 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800815 ping = main.Mininet1.pingHost( src="h" + str( i ),
816 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800817 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800818 if ping == main.FALSE:
819 main.log.warn( "Ping failed between h" + str( i ) +
820 " and h" + str( i + 10 ) )
821 elif ping == main.TRUE:
822 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800823 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800824 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700825 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800826 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800827 # TODO: pretty print
Jon Hall65844a32015-03-09 19:09:37 -0700828 main.log.warn( "ONOS1 intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700829 try:
830 tmpIntents = main.ONOScli1.intents()
831 main.log.warn( json.dumps( json.loads( tmpIntents ),
832 sort_keys=True,
833 indent=4,
834 separators=( ',', ': ' ) ) )
835 except ( ValueError, TypeError ):
836 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800837 utilities.assert_equals(
838 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800839 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800840 onpass="Intents have been installed correctly and pings work",
841 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallb1290e82014-11-18 16:17:48 -0500842
Jon Hallfeff3082015-05-19 10:23:26 -0700843 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700844 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700845 loopCount = 0
846 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700847 installedCheck = True
848 # Print the intent states
849 intents = main.ONOScli1.intents()
850 intentStates = []
851 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Hall0f523f22015-07-06 09:31:09 -0700852 count = 0
Jon Hall40d2cbd2015-06-03 16:24:29 -0700853 # Iter through intents of a node
854 try:
855 for intent in json.loads( intents ):
856 state = intent.get( 'state', None )
857 if "INSTALLED" not in state:
858 installedCheck = False
859 intentId = intent.get( 'id', None )
860 intentStates.append( ( intentId, state ) )
861 except ( ValueError, TypeError ):
862 main.log.exception( "Error parsing intents." )
863 # Print states
864 intentStates.sort()
865 for i, s in intentStates:
866 count += 1
867 main.log.info( "%-6s%-15s%-15s" %
868 ( str( count ), str( i ), str( s ) ) )
869 if not installedCheck:
870 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700871 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700872 utilities.assert_equals( expect=True, actual=installedCheck,
873 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700874 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700875 "INSTALLED state" )
876
877 main.step( "Check leadership of topics" )
878 leaders = main.ONOScli1.leaders()
879 topicCheck = main.TRUE
880 try:
881 if leaders:
882 parsedLeaders = json.loads( leaders )
883 main.log.warn( json.dumps( parsedLeaders,
884 sort_keys=True,
885 indent=4,
886 separators=( ',', ': ' ) ) )
887 # check for all intent partitions
888 # check for election
889 # TODO: Look at Devices as topics now that it uses this system
890 topics = []
891 for i in range( 14 ):
892 topics.append( "intent-partition-" + str( i ) )
893 # FIXME: this should only be after we start the app
894 # FIXME: topics.append( "org.onosproject.election" )
895 # Print leaders output
896 main.log.debug( topics )
897 ONOStopics = [ j['topic'] for j in parsedLeaders ]
898 for topic in topics:
899 if topic not in ONOStopics:
900 main.log.error( "Error: " + topic +
901 " not in leaders" )
902 topicCheck = main.FALSE
903 else:
904 main.log.error( "leaders() returned None" )
905 topicCheck = main.FALSE
906 except ( ValueError, TypeError ):
907 topicCheck = main.FALSE
908 main.log.exception( "Error parsing leaders" )
909 main.log.error( repr( leaders ) )
910 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700911 # Check all nodes
912 if topicCheck:
913 for node in CLIs:
914 response = node.leaders( jsonFormat=False)
915 main.log.warn( str( node.name ) + " leaders output: \n" +
916 str( response ) )
917
Jon Hallfeff3082015-05-19 10:23:26 -0700918 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
919 onpass="intent Partitions is in leaders",
920 onfail="Some topics were lost " )
921 # Print partitions
922 partitions = main.ONOScli1.partitions()
923 try:
924 if partitions :
925 parsedPartitions = json.loads( partitions )
926 main.log.warn( json.dumps( parsedPartitions,
927 sort_keys=True,
928 indent=4,
929 separators=( ',', ': ' ) ) )
930 # TODO check for a leader in all paritions
931 # TODO check for consistency among nodes
932 else:
933 main.log.error( "partitions() returned None" )
934 except ( ValueError, TypeError ):
935 main.log.exception( "Error parsing partitions" )
936 main.log.error( repr( partitions ) )
937 # Print Pending Map
938 pendingMap = main.ONOScli1.pendingMap()
939 try:
940 if pendingMap :
941 parsedPending = json.loads( pendingMap )
942 main.log.warn( json.dumps( parsedPending,
943 sort_keys=True,
944 indent=4,
945 separators=( ',', ': ' ) ) )
946 # TODO check something here?
947 else:
948 main.log.error( "pendingMap() returned None" )
949 except ( ValueError, TypeError ):
950 main.log.exception( "Error parsing pending map" )
951 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700952
Jon Hall63604932015-02-26 17:09:50 -0800953 if not installedCheck:
Jon Hall65844a32015-03-09 19:09:37 -0700954 main.log.info( "Waiting 60 seconds to see if the state of " +
955 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800956 time.sleep( 60 )
957 # Print the intent states
958 intents = main.ONOScli1.intents()
959 intentStates = []
960 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
961 count = 0
962 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700963 try:
964 for intent in json.loads( intents ):
965 state = intent.get( 'state', None )
966 if "INSTALLED" not in state:
967 installedCheck = False
968 intentId = intent.get( 'id', None )
969 intentStates.append( ( intentId, state ) )
970 except ( ValueError, TypeError ):
971 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800972 intentStates.sort()
973 for i, s in intentStates:
974 count += 1
975 main.log.info( "%-6s%-15s%-15s" %
976 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700977 leaders = main.ONOScli1.leaders()
978 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700979 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700980 if leaders:
981 parsedLeaders = json.loads( leaders )
982 main.log.warn( json.dumps( parsedLeaders,
983 sort_keys=True,
984 indent=4,
985 separators=( ',', ': ' ) ) )
986 # check for all intent partitions
987 # check for election
988 topics = []
989 for i in range( 14 ):
990 topics.append( "intent-partition-" + str( i ) )
991 # FIXME: this should only be after we start the app
992 topics.append( "org.onosproject.election" )
993 main.log.debug( topics )
994 ONOStopics = [ j['topic'] for j in parsedLeaders ]
995 for topic in topics:
996 if topic not in ONOStopics:
997 main.log.error( "Error: " + topic +
998 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700999 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -07001000 else:
1001 main.log.error( "leaders() returned None" )
1002 except ( ValueError, TypeError ):
1003 main.log.exception( "Error parsing leaders" )
1004 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001005 if missing:
1006 for node in CLIs:
1007 response = node.leaders( jsonFormat=False)
1008 main.log.warn( str( node.name ) + " leaders output: \n" +
1009 str( response ) )
1010
Jon Hall5cfd23c2015-03-19 11:40:57 -07001011 partitions = main.ONOScli1.partitions()
1012 try:
1013 if partitions :
1014 parsedPartitions = json.loads( partitions )
1015 main.log.warn( json.dumps( parsedPartitions,
1016 sort_keys=True,
1017 indent=4,
1018 separators=( ',', ': ' ) ) )
1019 # TODO check for a leader in all paritions
1020 # TODO check for consistency among nodes
1021 else:
1022 main.log.error( "partitions() returned None" )
1023 except ( ValueError, TypeError ):
1024 main.log.exception( "Error parsing partitions" )
1025 main.log.error( repr( partitions ) )
1026 pendingMap = main.ONOScli1.pendingMap()
1027 try:
1028 if pendingMap :
1029 parsedPending = json.loads( pendingMap )
1030 main.log.warn( json.dumps( parsedPending,
1031 sort_keys=True,
1032 indent=4,
1033 separators=( ',', ': ' ) ) )
1034 # TODO check something here?
1035 else:
1036 main.log.error( "pendingMap() returned None" )
1037 except ( ValueError, TypeError ):
1038 main.log.exception( "Error parsing pending map" )
1039 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001040 # Print flowrules
1041 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001042 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001043 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001044 PingResult = main.TRUE
1045 for i in range( 8, 18 ):
1046 ping = main.Mininet1.pingHost( src="h" + str( i ),
1047 target="h" + str( i + 10 ) )
1048 PingResult = PingResult and ping
1049 if ping == main.FALSE:
1050 main.log.warn( "Ping failed between h" + str( i ) +
1051 " and h" + str( i + 10 ) )
1052 elif ping == main.TRUE:
1053 main.log.info( "Ping test passed!" )
1054 # Don't set PingResult or you'd override failures
1055 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001056 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001057 "Intents have not been installed correctly, pings failed." )
1058 # TODO: pretty print
1059 main.log.warn( "ONOS1 intents: " )
1060 try:
1061 tmpIntents = main.ONOScli1.intents()
1062 main.log.warn( json.dumps( json.loads( tmpIntents ),
1063 sort_keys=True,
1064 indent=4,
1065 separators=( ',', ': ' ) ) )
1066 except ( ValueError, TypeError ):
1067 main.log.warn( repr( tmpIntents ) )
1068 utilities.assert_equals(
1069 expect=main.TRUE,
1070 actual=PingResult,
1071 onpass="Intents have been installed correctly and pings work",
1072 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallfeff3082015-05-19 10:23:26 -07001073
Jon Hall6aec96b2015-01-19 14:49:31 -08001074 def CASE5( self, main ):
1075 """
Jon Hallb1290e82014-11-18 16:17:48 -05001076 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001077 """
Jon Hallb1290e82014-11-18 16:17:48 -05001078 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001079 import time
1080 assert numControllers, "numControllers not defined"
1081 assert main, "main not defined"
1082 assert utilities.assert_equals, "utilities.assert_equals not defined"
1083 assert CLIs, "CLIs not defined"
1084 assert nodes, "nodes not defined"
Jon Hallb87f3db2015-07-06 03:10:27 -07001085 # assumes that sts is already in you PYTHONPATH
1086 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001087
Jon Hall6aec96b2015-01-19 14:49:31 -08001088 main.case( "Setting up and gathering data for current state" )
1089 # The general idea for this test case is to pull the state of
1090 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -07001091 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -05001092
Jon Hall65844a32015-03-09 19:09:37 -07001093 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001094 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001095 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001096
Jon Hall6aec96b2015-01-19 14:49:31 -08001097 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001098 rolesNotNull = main.TRUE
1099 threads = []
1100 for i in range( numControllers ):
1101 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001102 name="rolesNotNull-" + str( i ),
1103 args=[] )
1104 threads.append( t )
1105 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001106
1107 for t in threads:
1108 t.join()
1109 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001110 utilities.assert_equals(
1111 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001112 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001113 onpass="Each device has a master",
1114 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001115
Jon Hall65844a32015-03-09 19:09:37 -07001116 main.step( "Get the Mastership of each switch from each controller" )
1117 ONOSMastership = []
1118 mastershipCheck = main.FALSE
1119 consistentMastership = True
1120 rolesResults = True
1121 threads = []
1122 for i in range( numControllers ):
1123 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001124 name="roles-" + str( i ),
1125 args=[] )
1126 threads.append( t )
1127 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001128
1129 for t in threads:
1130 t.join()
1131 ONOSMastership.append( t.result )
1132
1133 for i in range( numControllers ):
1134 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001135 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001136 " roles" )
1137 main.log.warn(
1138 "ONOS" + str( i + 1 ) + " mastership response: " +
1139 repr( ONOSMastership[i] ) )
1140 rolesResults = False
1141 utilities.assert_equals(
1142 expect=True,
1143 actual=rolesResults,
1144 onpass="No error in reading roles output",
1145 onfail="Error in reading roles from ONOS" )
1146
1147 main.step( "Check for consistency in roles from each controller" )
1148 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001149 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001150 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001151 else:
Jon Hall65844a32015-03-09 19:09:37 -07001152 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001153 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001154 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001155 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001156 onpass="Switch roles are consistent across all ONOS nodes",
1157 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001158
Jon Hall65844a32015-03-09 19:09:37 -07001159 if rolesResults and not consistentMastership:
1160 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001161 try:
1162 main.log.warn(
1163 "ONOS" + str( i + 1 ) + " roles: ",
1164 json.dumps(
1165 json.loads( ONOSMastership[ i ] ),
1166 sort_keys=True,
1167 indent=4,
1168 separators=( ',', ': ' ) ) )
1169 except ( ValueError, TypeError ):
1170 main.log.warn( repr( ONOSMastership[ i ] ) )
1171 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001172 mastershipCheck = main.TRUE
1173 mastershipState = ONOSMastership[ 0 ]
1174
Jon Hall6aec96b2015-01-19 14:49:31 -08001175 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001176 global intentState
1177 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001178 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001179 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001180 consistentIntents = True
1181 intentsResults = True
1182 threads = []
1183 for i in range( numControllers ):
1184 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001185 name="intents-" + str( i ),
1186 args=[],
1187 kwargs={ 'jsonFormat': True } )
1188 threads.append( t )
1189 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001190
1191 for t in threads:
1192 t.join()
1193 ONOSIntents.append( t.result )
1194
1195 for i in range( numControllers ):
1196 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001197 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001198 " intents" )
1199 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1200 repr( ONOSIntents[ i ] ) )
1201 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001202 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001203 expect=True,
1204 actual=intentsResults,
1205 onpass="No error in reading intents output",
1206 onfail="Error in reading intents from ONOS" )
1207
1208 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001209 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001210 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001211 "nodes" )
1212 else:
1213 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001214 main.log.error( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001215 utilities.assert_equals(
1216 expect=True,
1217 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 onpass="Intents are consistent across all ONOS nodes",
1219 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001220
Jon Hall390696c2015-05-05 17:13:41 -07001221 if intentsResults:
1222 # Try to make it easy to figure out what is happening
1223 #
1224 # Intent ONOS1 ONOS2 ...
1225 # 0x01 INSTALLED INSTALLING
1226 # ... ... ...
1227 # ... ... ...
1228 title = " Id"
1229 for n in range( numControllers ):
1230 title += " " * 10 + "ONOS" + str( n + 1 )
1231 main.log.warn( title )
Jon Hall390696c2015-05-05 17:13:41 -07001232 keys = []
Jon Hall40d2cbd2015-06-03 16:24:29 -07001233 try:
1234 # Get the set of all intent keys
Jon Hall390696c2015-05-05 17:13:41 -07001235 for nodeStr in ONOSIntents:
1236 node = json.loads( nodeStr )
1237 for intent in node:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001238 keys.append( intent.get( 'id' ) )
1239 keys = set( keys )
1240 # For each intent key, print the state on each node
1241 for key in keys:
1242 row = "%-13s" % key
1243 for nodeStr in ONOSIntents:
1244 node = json.loads( nodeStr )
1245 for intent in node:
1246 if intent.get( 'id', "Error" ) == key:
1247 row += "%-15s" % intent.get( 'state' )
1248 main.log.warn( row )
1249 # End of intent state table
1250 except ValueError as e:
1251 main.log.exception( e )
1252 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall390696c2015-05-05 17:13:41 -07001253
Jon Hall65844a32015-03-09 19:09:37 -07001254 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001255 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001256 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001257 main.log.debug( "ONOS" + str( n ) + " intents: " )
1258 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1259 sort_keys=True,
1260 indent=4,
1261 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001262 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001263 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001264 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1265 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1266 sort_keys=True,
1267 indent=4,
1268 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001269 else:
Jon Hall390696c2015-05-05 17:13:41 -07001270 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1271 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001272 elif intentsResults and consistentIntents:
1273 intentCheck = main.TRUE
1274 intentState = ONOSIntents[ 0 ]
1275
Jon Hall6aec96b2015-01-19 14:49:31 -08001276 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001277 global flowState
1278 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001279 ONOSFlows = []
1280 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001281 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001282 consistentFlows = True
1283 flowsResults = True
1284 threads = []
1285 for i in range( numControllers ):
1286 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001287 name="flows-" + str( i ),
1288 args=[],
1289 kwargs={ 'jsonFormat': True } )
1290 threads.append( t )
1291 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001292
Jon Halla9d26da2015-03-30 16:45:32 -07001293 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001294 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001295 for t in threads:
1296 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001297 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001298 ONOSFlows.append( result )
1299
1300 for i in range( numControllers ):
1301 num = str( i + 1 )
1302 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001303 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall65844a32015-03-09 19:09:37 -07001304 main.log.warn( "ONOS" + num + " flows response: " +
1305 repr( ONOSFlows[ i ] ) )
1306 flowsResults = False
1307 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001308 else:
Jon Hall65844a32015-03-09 19:09:37 -07001309 try:
1310 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1311 except ( ValueError, TypeError ):
1312 # FIXME: change this to log.error?
1313 main.log.exception( "Error in parsing ONOS" + num +
1314 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001315 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001316 ONOSFlowsJson.append( None )
1317 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001318 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001319 expect=True,
1320 actual=flowsResults,
1321 onpass="No error in reading flows output",
1322 onfail="Error in reading flows from ONOS" )
1323
1324 main.step( "Check for consistency in Flows from each controller" )
1325 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1326 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001327 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001328 else:
1329 consistentFlows = False
1330 utilities.assert_equals(
1331 expect=True,
1332 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001333 onpass="The flow count is consistent across all ONOS nodes",
1334 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001335
Jon Hall65844a32015-03-09 19:09:37 -07001336 if flowsResults and not consistentFlows:
1337 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001338 try:
1339 main.log.warn(
1340 "ONOS" + str( i + 1 ) + " flows: " +
1341 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1342 indent=4, separators=( ',', ': ' ) ) )
1343 except ( ValueError, TypeError ):
1344 main.log.warn(
1345 "ONOS" + str( i + 1 ) + " flows: " +
1346 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001347 elif flowsResults and consistentFlows:
1348 flowCheck = main.TRUE
1349 flowState = ONOSFlows[ 0 ]
1350
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001352 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001353 flows = []
1354 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001355 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001356 if flowCheck == main.FALSE:
1357 for table in flows:
1358 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001359 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001360
Jon Hall6aec96b2015-01-19 14:49:31 -08001361 main.step( "Start continuous pings" )
1362 main.Mininet2.pingLong(
1363 src=main.params[ 'PING' ][ 'source1' ],
1364 target=main.params[ 'PING' ][ 'target1' ],
1365 pingTime=500 )
1366 main.Mininet2.pingLong(
1367 src=main.params[ 'PING' ][ 'source2' ],
1368 target=main.params[ 'PING' ][ 'target2' ],
1369 pingTime=500 )
1370 main.Mininet2.pingLong(
1371 src=main.params[ 'PING' ][ 'source3' ],
1372 target=main.params[ 'PING' ][ 'target3' ],
1373 pingTime=500 )
1374 main.Mininet2.pingLong(
1375 src=main.params[ 'PING' ][ 'source4' ],
1376 target=main.params[ 'PING' ][ 'target4' ],
1377 pingTime=500 )
1378 main.Mininet2.pingLong(
1379 src=main.params[ 'PING' ][ 'source5' ],
1380 target=main.params[ 'PING' ][ 'target5' ],
1381 pingTime=500 )
1382 main.Mininet2.pingLong(
1383 src=main.params[ 'PING' ][ 'source6' ],
1384 target=main.params[ 'PING' ][ 'target6' ],
1385 pingTime=500 )
1386 main.Mininet2.pingLong(
1387 src=main.params[ 'PING' ][ 'source7' ],
1388 target=main.params[ 'PING' ][ 'target7' ],
1389 pingTime=500 )
1390 main.Mininet2.pingLong(
1391 src=main.params[ 'PING' ][ 'source8' ],
1392 target=main.params[ 'PING' ][ 'target8' ],
1393 pingTime=500 )
1394 main.Mininet2.pingLong(
1395 src=main.params[ 'PING' ][ 'source9' ],
1396 target=main.params[ 'PING' ][ 'target9' ],
1397 pingTime=500 )
1398 main.Mininet2.pingLong(
1399 src=main.params[ 'PING' ][ 'source10' ],
1400 target=main.params[ 'PING' ][ 'target10' ],
1401 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001402
Jon Hallb87f3db2015-07-06 03:10:27 -07001403 main.step( "Create TestONTopology object" )
1404 ctrls = []
1405 for node in nodes:
1406 temp = ( node, node.name, node.ip_address, 6633 )
1407 ctrls.append( temp )
1408 MNTopo = TestONTopology( main.Mininet1, ctrls )
1409
Jon Hall6aec96b2015-01-19 14:49:31 -08001410 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001411 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001412 threads = []
1413 for i in range( numControllers ):
1414 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001415 name="devices-" + str( i ),
1416 args=[ ] )
1417 threads.append( t )
1418 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001419
1420 for t in threads:
1421 t.join()
1422 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001423 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001424 threads = []
1425 for i in range( numControllers ):
1426 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001427 name="hosts-" + str( i ),
1428 args=[ ] )
1429 threads.append( t )
1430 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001431
1432 for t in threads:
1433 t.join()
1434 try:
1435 hosts.append( json.loads( t.result ) )
1436 except ( ValueError, TypeError ):
1437 # FIXME: better handling of this, print which node
1438 # Maybe use thread name?
1439 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001440 # FIXME: should this be an empty json object instead?
1441 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001442
Jon Hallb1290e82014-11-18 16:17:48 -05001443 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001444 threads = []
1445 for i in range( numControllers ):
1446 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001447 name="ports-" + str( i ),
1448 args=[ ] )
1449 threads.append( t )
1450 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001451
1452 for t in threads:
1453 t.join()
1454 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001455 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001456 threads = []
1457 for i in range( numControllers ):
1458 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001459 name="links-" + str( i ),
1460 args=[ ] )
1461 threads.append( t )
1462 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001463
1464 for t in threads:
1465 t.join()
1466 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001467 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001468 threads = []
1469 for i in range( numControllers ):
1470 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001471 name="clusters-" + str( i ),
1472 args=[ ] )
1473 threads.append( t )
1474 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001475
1476 for t in threads:
1477 t.join()
1478 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001479 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001480
Jon Hall6aec96b2015-01-19 14:49:31 -08001481 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001482 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001483 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001484 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001485 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001486 if "Error" not in hosts[ controller ]:
1487 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001488 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001490 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001491 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001492 " is inconsistent with ONOS1" )
1493 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001494 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001495
1496 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001497 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001498 controllerStr )
1499 consistentHostsResult = main.FALSE
1500 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001501 " hosts response: " +
1502 repr( hosts[ controller ] ) )
1503 utilities.assert_equals(
1504 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001505 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001506 onpass="Hosts view is consistent across all ONOS nodes",
1507 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001508
Jon Hall390696c2015-05-05 17:13:41 -07001509 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001510 ipResult = main.TRUE
1511 for controller in range( 0, len( hosts ) ):
1512 controllerStr = str( controller + 1 )
1513 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001514 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001515 main.log.error( "DEBUG:Error with host ips on controller" +
1516 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001517 ipResult = main.FALSE
1518 utilities.assert_equals(
1519 expect=main.TRUE,
1520 actual=ipResult,
1521 onpass="The ips of the hosts aren't empty",
1522 onfail="The ip of at least one host is missing" )
1523
Jon Hall6aec96b2015-01-19 14:49:31 -08001524 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001525 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001526 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001527 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001528 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001529 if "Error" not in clusters[ controller ]:
1530 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001531 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001532 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001533 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001534 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001535 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001536
1537 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001538 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001539 "from ONOS" + controllerStr )
1540 consistentClustersResult = main.FALSE
1541 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001542 " clusters response: " +
1543 repr( clusters[ controller ] ) )
1544 utilities.assert_equals(
1545 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001546 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001547 onpass="Clusters view is consistent across all ONOS nodes",
1548 onfail="ONOS nodes have different views of clusters" )
1549 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001550 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001551 try:
1552 numClusters = len( json.loads( clusters[ 0 ] ) )
1553 except ( ValueError, TypeError ):
1554 main.log.exception( "Error parsing clusters[0]: " +
1555 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001556 clusterResults = main.FALSE
1557 if numClusters == 1:
1558 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001559 utilities.assert_equals(
1560 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001561 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001562 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001563 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001564
Jon Hall6aec96b2015-01-19 14:49:31 -08001565 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001566 devicesResults = main.TRUE
Jon Hallb87f3db2015-07-06 03:10:27 -07001567 portsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001568 linksResults = main.TRUE
1569 for controller in range( numControllers ):
1570 controllerStr = str( controller + 1 )
Jon Hallb87f3db2015-07-06 03:10:27 -07001571 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001572 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallb87f3db2015-07-06 03:10:27 -07001573 MNTopo,
1574 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001575 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001576 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001577 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001578 actual=currentDevicesResult,
1579 onpass="ONOS" + controllerStr +
1580 " Switches view is correct",
1581 onfail="ONOS" + controllerStr +
1582 " Switches view is incorrect" )
Jon Hallb87f3db2015-07-06 03:10:27 -07001583
1584 if ports[ controller ] or "Error" not in ports[ controller ]:
1585 currentPortsResult = main.Mininet1.comparePorts(
1586 MNTopo,
1587 json.loads( ports[ controller ] ) )
1588 else:
1589 currentPortsResult = main.FALSE
1590 utilities.assert_equals( expect=main.TRUE,
1591 actual=currentPortsResult,
1592 onpass="ONOS" + controllerStr +
1593 " ports view is correct",
1594 onfail="ONOS" + controllerStr +
1595 " ports view is incorrect" )
1596
1597 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001598 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallb87f3db2015-07-06 03:10:27 -07001599 MNTopo,
1600 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001601 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001602 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001603 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001604 actual=currentLinksResult,
1605 onpass="ONOS" + controllerStr +
1606 " links view is correct",
1607 onfail="ONOS" + controllerStr +
1608 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001609
Jon Hallb6a54872015-06-12 14:02:42 -07001610 devicesResults = devicesResults and currentDevicesResult
Jon Hallb87f3db2015-07-06 03:10:27 -07001611 portsResults = portsResults and currentPortsResult
Jon Hallb6a54872015-06-12 14:02:42 -07001612 linksResults = linksResults and currentLinksResult
Jon Hallb6a54872015-06-12 14:02:42 -07001613
Jon Hallb87f3db2015-07-06 03:10:27 -07001614 topoResult = ( devicesResults and portsResults and linksResults
1615 and consistentHostsResult and consistentClustersResult
1616 and clusterResults and ipResult )
1617 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1618 onpass="Topology Check Test successful",
1619 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001620
Jon Hall6aec96b2015-01-19 14:49:31 -08001621 def CASE6( self, main ):
1622 """
Jon Hallb1290e82014-11-18 16:17:48 -05001623 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001624 """
Jon Hall368769f2014-11-19 15:43:35 -08001625 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001626 assert numControllers, "numControllers not defined"
1627 assert main, "main not defined"
1628 assert utilities.assert_equals, "utilities.assert_equals not defined"
1629 assert CLIs, "CLIs not defined"
1630 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001631 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 time.sleep( 60 )
1633 utilities.assert_equals(
1634 expect=main.TRUE,
1635 actual=main.TRUE,
1636 onpass="Sleeping 60 seconds",
1637 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001638
Jon Hall6aec96b2015-01-19 14:49:31 -08001639 def CASE7( self, main ):
1640 """
Jon Hall368769f2014-11-19 15:43:35 -08001641 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001642 """
Jon Hallb1290e82014-11-18 16:17:48 -05001643 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001644 assert numControllers, "numControllers not defined"
1645 assert main, "main not defined"
1646 assert utilities.assert_equals, "utilities.assert_equals not defined"
1647 assert CLIs, "CLIs not defined"
1648 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001649 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001650
Jon Hall65844a32015-03-09 19:09:37 -07001651 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001652 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001653 rolesNotNull = main.TRUE
1654 threads = []
1655 for i in range( numControllers ):
1656 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001657 name="rolesNotNull-" + str( i ),
1658 args=[ ] )
1659 threads.append( t )
1660 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001661
1662 for t in threads:
1663 t.join()
1664 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001665 utilities.assert_equals(
1666 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001667 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001668 onpass="Each device has a master",
1669 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001670
Jon Hall390696c2015-05-05 17:13:41 -07001671 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001672 ONOSMastership = []
1673 mastershipCheck = main.FALSE
1674 consistentMastership = True
1675 rolesResults = True
1676 threads = []
1677 for i in range( numControllers ):
1678 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001679 name="roles-" + str( i ),
1680 args=[] )
1681 threads.append( t )
1682 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001683
1684 for t in threads:
1685 t.join()
1686 ONOSMastership.append( t.result )
1687
1688 for i in range( numControllers ):
1689 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001690 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001691 " roles" )
1692 main.log.warn(
1693 "ONOS" + str( i + 1 ) + " mastership response: " +
1694 repr( ONOSMastership[i] ) )
1695 rolesResults = False
1696 utilities.assert_equals(
1697 expect=True,
1698 actual=rolesResults,
1699 onpass="No error in reading roles output",
1700 onfail="Error in reading roles from ONOS" )
1701
1702 main.step( "Check for consistency in roles from each controller" )
1703 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001704 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001705 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001706 else:
Jon Hall65844a32015-03-09 19:09:37 -07001707 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001708 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001709 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001710 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001711 onpass="Switch roles are consistent across all ONOS nodes",
1712 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001713
Jon Hall65844a32015-03-09 19:09:37 -07001714 if rolesResults and not consistentMastership:
1715 for i in range( numControllers ):
1716 main.log.warn(
1717 "ONOS" + str( i + 1 ) + " roles: ",
1718 json.dumps(
1719 json.loads( ONOSMastership[ i ] ),
1720 sort_keys=True,
1721 indent=4,
1722 separators=( ',', ': ' ) ) )
1723 elif rolesResults and not consistentMastership:
1724 mastershipCheck = main.TRUE
1725
Jon Hallb1290e82014-11-18 16:17:48 -05001726 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001727 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001728 try:
1729 currentJson = json.loads( ONOSMastership[0] )
1730 oldJson = json.loads( mastershipState )
1731 except ( ValueError, TypeError ):
1732 main.log.exception( "Something is wrong with parsing " +
1733 "ONOSMastership[0] or mastershipState" )
1734 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1735 main.log.error( "mastershipState" + repr( mastershipState ) )
1736 main.cleanup()
1737 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001738 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001739 for i in range( 1, 29 ):
1740 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001741 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001742 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001743 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001744 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001745 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001746 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001747 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001748 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001749 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001750 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001751 utilities.assert_equals(
1752 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001753 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 onpass="Mastership of Switches was not changed",
1755 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001756 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001757
Jon Hall6aec96b2015-01-19 14:49:31 -08001758 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001759 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001760 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001761 consistentIntents = True
1762 intentsResults = True
1763 threads = []
1764 for i in range( numControllers ):
1765 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001766 name="intents-" + str( i ),
1767 args=[],
1768 kwargs={ 'jsonFormat': True } )
1769 threads.append( t )
1770 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001771
1772 for t in threads:
1773 t.join()
1774 ONOSIntents.append( t.result )
1775
1776 for i in range( numControllers ):
1777 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001778 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001779 " intents" )
1780 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1781 repr( ONOSIntents[ i ] ) )
1782 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001783 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001784 expect=True,
1785 actual=intentsResults,
1786 onpass="No error in reading intents output",
1787 onfail="Error in reading intents from ONOS" )
1788
1789 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001790 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001791 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001792 "nodes" )
1793 else:
1794 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001795
1796 # Try to make it easy to figure out what is happening
1797 #
1798 # Intent ONOS1 ONOS2 ...
1799 # 0x01 INSTALLED INSTALLING
1800 # ... ... ...
1801 # ... ... ...
1802 title = " ID"
1803 for n in range( numControllers ):
1804 title += " " * 10 + "ONOS" + str( n + 1 )
1805 main.log.warn( title )
1806 # get all intent keys in the cluster
1807 keys = []
1808 for nodeStr in ONOSIntents:
1809 node = json.loads( nodeStr )
1810 for intent in node:
1811 keys.append( intent.get( 'id' ) )
1812 keys = set( keys )
1813 for key in keys:
1814 row = "%-13s" % key
1815 for nodeStr in ONOSIntents:
1816 node = json.loads( nodeStr )
1817 for intent in node:
1818 if intent.get( 'id' ) == key:
1819 row += "%-15s" % intent.get( 'state' )
1820 main.log.warn( row )
1821 # End table view
1822
Jon Hall65844a32015-03-09 19:09:37 -07001823 utilities.assert_equals(
1824 expect=True,
1825 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001826 onpass="Intents are consistent across all ONOS nodes",
1827 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001828 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001829 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001830 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001831 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001832 try:
1833 for intent in json.loads( node ):
1834 nodeStates.append( intent[ 'state' ] )
1835 except ( ValueError, TypeError ):
1836 main.log.exception( "Error in parsing intents" )
1837 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001838 intentStates.append( nodeStates )
1839 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1840 main.log.info( dict( out ) )
1841
Jon Hall65844a32015-03-09 19:09:37 -07001842 if intentsResults and not consistentIntents:
1843 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001844 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1845 main.log.warn( json.dumps(
1846 json.loads( ONOSIntents[ i ] ),
1847 sort_keys=True,
1848 indent=4,
1849 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001850 elif intentsResults and consistentIntents:
1851 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001852
Jon Hall58c76b72015-02-23 11:09:24 -08001853 # NOTE: Store has no durability, so intents are lost across system
1854 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001855 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001856 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001857 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001858 sameIntents = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001859 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001860 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001861 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001862 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001863 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001864 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1865 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001866 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001867 before = json.loads( intentState )
1868 after = json.loads( ONOSIntents[ 0 ] )
1869 for intent in before:
1870 if intent not in after:
1871 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001872 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001873 "(at least in the same form):" )
1874 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001875 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001876 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001877 main.log.debug( repr( ONOSIntents[0] ) )
1878 main.log.debug( repr( intentState ) )
1879 if sameIntents == main.FALSE:
1880 try:
1881 main.log.debug( "ONOS intents before: " )
1882 main.log.debug( json.dumps( json.loads( intentState ),
1883 sort_keys=True, indent=4,
1884 separators=( ',', ': ' ) ) )
1885 main.log.debug( "Current ONOS intents: " )
1886 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1887 sort_keys=True, indent=4,
1888 separators=( ',', ': ' ) ) )
1889 except ( ValueError, TypeError ):
1890 main.log.exception( "Exception printing intents" )
1891 main.log.debug( repr( ONOSIntents[0] ) )
1892 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001893 utilities.assert_equals(
1894 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001895 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001896 onpass="Intents are consistent with before failure",
1897 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001898 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001899
Jon Hall6aec96b2015-01-19 14:49:31 -08001900 main.step( "Get the OF Table entries and compare to before " +
1901 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001902 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001903 flows2 = []
1904 for i in range( 28 ):
1905 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001906 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1907 flows2.append( tmpFlows )
1908 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001909 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001910 flow2=tmpFlows )
1911 FlowTables = FlowTables and tempResult
1912 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001913 main.log.info( "Differences in flow table for switch: s" +
1914 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001915 utilities.assert_equals(
1916 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001917 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001918 onpass="No changes were found in the flow tables",
1919 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001920
Jon Hall6aec96b2015-01-19 14:49:31 -08001921 main.step( "Check the continuous pings to ensure that no packets " +
1922 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001923 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1924 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001925 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001926 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1927 for i in range( 8, 18 ):
1928 main.log.info(
1929 "Checking for a loss in pings along flow from s" +
1930 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001931 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001933 str( i ) ) or LossInPings
1934 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001935 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001936 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001937 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001938 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001940 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001941 utilities.assert_equals(
1942 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001943 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001944 onpass="No Loss of connectivity",
1945 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001946
Jon Hall390696c2015-05-05 17:13:41 -07001947 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 # Test of LeadershipElection
1949 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001950 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001951 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001952 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001953 for cli in CLIs:
1954 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001955 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001956 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001957 # all is well
1958 # NOTE: In failure scenario, this could be a new node, maybe
1959 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001960 pass
1961 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001962 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001963 main.log.error( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001964 "electionTestLeader function, check the" +
1965 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001966 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001967 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001968 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001969 main.log.error( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001970 " as the leader of the election app. " +
1971 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 utilities.assert_equals(
1973 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001974 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001975 onpass="Leadership election passed",
1976 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001977
Jon Hall6aec96b2015-01-19 14:49:31 -08001978 def CASE8( self, main ):
1979 """
Jon Hallb1290e82014-11-18 16:17:48 -05001980 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001981 """
Jon Hallb87f3db2015-07-06 03:10:27 -07001982 import sys
1983 # FIXME add this path to params
1984 sys.path.append( "/home/admin/sts" )
1985 # assumes that sts is already in you PYTHONPATH
1986 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001987 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001988 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001989 assert numControllers, "numControllers not defined"
1990 assert main, "main not defined"
1991 assert utilities.assert_equals, "utilities.assert_equals not defined"
1992 assert CLIs, "CLIs not defined"
1993 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05001994
Jon Hallfeff3082015-05-19 10:23:26 -07001995 main.case( "Compare ONOS Topology view to Mininet topology" )
1996 main.caseExplaination = "Compare topology objects between Mininet" +\
1997 " and ONOS"
Jon Hallb87f3db2015-07-06 03:10:27 -07001998 main.step( "Create TestONTopology object" )
1999 try:
2000 ctrls = []
2001 for node in nodes:
2002 temp = ( node, node.name, node.ip_address, 6633 )
2003 ctrls.append( temp )
2004 MNTopo = TestONTopology( main.Mininet1, ctrls )
2005 except Exception:
2006 objResult = main.FALSE
2007 else:
2008 objResult = main.TRUE
2009 utilities.assert_equals( expect=main.TRUE, actual=objResult,
2010 onpass="Created TestONTopology object",
2011 onfail="Exception while creating " +
2012 "TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05002013
Jon Hallfeff3082015-05-19 10:23:26 -07002014 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002015 devicesResults = main.TRUE
Jon Hallb87f3db2015-07-06 03:10:27 -07002016 portsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002017 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002018 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002019 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002020 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002021 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002022 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002023 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002024 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002025 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002026 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07002027 count += 1
Jon Hallb87f3db2015-07-06 03:10:27 -07002028 if count > 1:
2029 # TODO: Deprecate STS usage
2030 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002031 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002032 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07002033 threads = []
2034 for i in range( numControllers ):
2035 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07002036 name="devices-" + str( i ),
2037 args=[ ] )
2038 threads.append( t )
2039 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002040
2041 for t in threads:
2042 t.join()
2043 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002044 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002045 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07002046 threads = []
2047 for i in range( numControllers ):
2048 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07002049 name="hosts-" + str( i ),
2050 args=[ ] )
2051 threads.append( t )
2052 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002053
2054 for t in threads:
2055 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002056 try:
2057 hosts.append( json.loads( t.result ) )
2058 except ( ValueError, TypeError ):
2059 main.log.exception( "Error parsing hosts results" )
2060 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002061 for controller in range( 0, len( hosts ) ):
2062 controllerStr = str( controller + 1 )
2063 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002064 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002065 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002066 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002067 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002068 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002069 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07002070 threads = []
2071 for i in range( numControllers ):
2072 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07002073 name="ports-" + str( i ),
2074 args=[ ] )
2075 threads.append( t )
2076 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002077
2078 for t in threads:
2079 t.join()
2080 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002081 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002082 threads = []
2083 for i in range( numControllers ):
2084 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002085 name="links-" + str( i ),
2086 args=[ ] )
2087 threads.append( t )
2088 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002089
2090 for t in threads:
2091 t.join()
2092 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002093 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002094 threads = []
2095 for i in range( numControllers ):
2096 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002097 name="clusters-" + str( i ),
2098 args=[ ] )
2099 threads.append( t )
2100 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002101
2102 for t in threads:
2103 t.join()
2104 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002105
Jon Hall8f89dda2015-01-22 16:03:33 -08002106 elapsed = time.time() - startTime
2107 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002108 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002109 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002110
Jon Hall21270ac2015-02-16 17:59:55 -08002111 for controller in range( numControllers ):
2112 controllerStr = str( controller + 1 )
Jon Hallb87f3db2015-07-06 03:10:27 -07002113 if devices[ controller ] or "Error" not in devices[
2114 controller ]:
Jon Hall21270ac2015-02-16 17:59:55 -08002115 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallb87f3db2015-07-06 03:10:27 -07002116 MNTopo,
2117 json.loads( devices[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002118 else:
2119 currentDevicesResult = main.FALSE
2120 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002121 actual=currentDevicesResult,
2122 onpass="ONOS" + controllerStr +
2123 " Switches view is correct",
2124 onfail="ONOS" + controllerStr +
2125 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002126
Jon Hallb87f3db2015-07-06 03:10:27 -07002127 if ports[ controller ] or "Error" not in ports[ controller ]:
2128 currentPortsResult = main.Mininet1.comparePorts(
2129 MNTopo,
2130 json.loads( ports[ controller ] ) )
2131 else:
2132 currentPortsResult = main.FALSE
2133 utilities.assert_equals( expect=main.TRUE,
2134 actual=currentPortsResult,
2135 onpass="ONOS" + controllerStr +
2136 " ports view is correct",
2137 onfail="ONOS" + controllerStr +
2138 " ports view is incorrect" )
2139
2140 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall21270ac2015-02-16 17:59:55 -08002141 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallb87f3db2015-07-06 03:10:27 -07002142 MNTopo,
2143 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002144 else:
2145 currentLinksResult = main.FALSE
2146 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002147 actual=currentLinksResult,
2148 onpass="ONOS" + controllerStr +
2149 " links view is correct",
2150 onfail="ONOS" + controllerStr +
2151 " links view is incorrect" )
2152
2153 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2154 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallb87f3db2015-07-06 03:10:27 -07002155 MNTopo, hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002156 else:
2157 currentHostsResult = main.FALSE
2158 utilities.assert_equals( expect=main.TRUE,
2159 actual=currentHostsResult,
2160 onpass="ONOS" + controllerStr +
2161 " hosts exist in Mininet",
2162 onfail="ONOS" + controllerStr +
2163 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002164 # CHECKING HOST ATTACHMENT POINTS
2165 hostAttachment = True
Jon Hallb87f3db2015-07-06 03:10:27 -07002166 noHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002167 # FIXME: topo-HA/obelisk specific mappings:
2168 # key is mac and value is dpid
2169 mappings = {}
2170 for i in range( 1, 29 ): # hosts 1 through 28
2171 # set up correct variables:
2172 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2173 if i == 1:
2174 deviceId = "1000".zfill(16)
2175 elif i == 2:
2176 deviceId = "2000".zfill(16)
2177 elif i == 3:
2178 deviceId = "3000".zfill(16)
2179 elif i == 4:
2180 deviceId = "3004".zfill(16)
2181 elif i == 5:
2182 deviceId = "5000".zfill(16)
2183 elif i == 6:
2184 deviceId = "6000".zfill(16)
2185 elif i == 7:
2186 deviceId = "6007".zfill(16)
2187 elif i >= 8 and i <= 17:
2188 dpid = '3' + str( i ).zfill( 3 )
2189 deviceId = dpid.zfill(16)
2190 elif i >= 18 and i <= 27:
2191 dpid = '6' + str( i ).zfill( 3 )
2192 deviceId = dpid.zfill(16)
2193 elif i == 28:
2194 deviceId = "2800".zfill(16)
2195 mappings[ macId ] = deviceId
2196 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2197 if hosts[ controller ] == []:
2198 main.log.warn( "There are no hosts discovered" )
Jon Hallb87f3db2015-07-06 03:10:27 -07002199 noHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002200 else:
2201 for host in hosts[ controller ]:
2202 mac = None
2203 location = None
2204 device = None
2205 port = None
2206 try:
2207 mac = host.get( 'mac' )
2208 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002209
Jon Hallc9eabec2015-06-10 14:33:14 -07002210 location = host.get( 'location' )
2211 assert location, "location field could not be found for this host object"
2212
2213 # Trim the protocol identifier off deviceId
2214 device = str( location.get( 'elementId' ) ).split(':')[1]
2215 assert device, "elementId field could not be found for this host location object"
2216
2217 port = location.get( 'port' )
2218 assert port, "port field could not be found for this host location object"
2219
2220 # Now check if this matches where they should be
2221 if mac and device and port:
2222 if str( port ) != "1":
2223 main.log.error( "The attachment port is incorrect for " +
2224 "host " + str( mac ) +
2225 ". Expected: 1 Actual: " + str( port) )
2226 hostAttachment = False
2227 if device != mappings[ str( mac ) ]:
2228 main.log.error( "The attachment device is incorrect for " +
2229 "host " + str( mac ) +
2230 ". Expected: " + mappings[ str( mac ) ] +
2231 " Actual: " + device )
2232 hostAttachment = False
2233 else:
2234 hostAttachment = False
2235 except AssertionError:
2236 main.log.exception( "Json object not as expected" )
2237 main.log.error( repr( host ) )
2238 hostAttachment = False
2239 else:
2240 main.log.error( "No hosts json output or \"Error\"" +
2241 " in output. hosts = " +
2242 repr( hosts[ controller ] ) )
Jon Hallb87f3db2015-07-06 03:10:27 -07002243 if noHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002244 hostAttachment = True
2245
2246 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002247 devicesResults = devicesResults and currentDevicesResult
Jon Hallb87f3db2015-07-06 03:10:27 -07002248 portsResults = portsResults and currentPortsResult
Jon Hall58c76b72015-02-23 11:09:24 -08002249 linksResults = linksResults and currentLinksResult
2250 hostsResults = hostsResults and currentHostsResult
Jon Hallb87f3db2015-07-06 03:10:27 -07002251 hostAttachmentResults = hostAttachmentResults and hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002252
Jon Hallc9eabec2015-06-10 14:33:14 -07002253 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002254
Jon Hallc9eabec2015-06-10 14:33:14 -07002255 # hosts
2256 main.step( "Hosts view is consistent across all ONOS nodes" )
2257 consistentHostsResult = main.TRUE
2258 for controller in range( len( hosts ) ):
2259 controllerStr = str( controller + 1 )
2260 if "Error" not in hosts[ controller ]:
2261 if hosts[ controller ] == hosts[ 0 ]:
2262 continue
2263 else: # hosts not consistent
2264 main.log.error( "hosts from ONOS" + controllerStr +
2265 " is inconsistent with ONOS1" )
2266 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002267 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002268
Jon Hallc9eabec2015-06-10 14:33:14 -07002269 else:
2270 main.log.error( "Error in getting ONOS hosts from ONOS" +
2271 controllerStr )
2272 consistentHostsResult = main.FALSE
2273 main.log.warn( "ONOS" + controllerStr +
2274 " hosts response: " +
2275 repr( hosts[ controller ] ) )
2276 utilities.assert_equals(
2277 expect=main.TRUE,
2278 actual=consistentHostsResult,
2279 onpass="Hosts view is consistent across all ONOS nodes",
2280 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002281
Jon Hallc9eabec2015-06-10 14:33:14 -07002282 main.step( "Hosts information is correct" )
2283 hostsResults = hostsResults and ipResult
2284 utilities.assert_equals(
2285 expect=main.TRUE,
2286 actual=hostsResults,
2287 onpass="Host information is correct",
2288 onfail="Host information is incorrect" )
2289
2290 main.step( "Host attachment points to the network" )
2291 utilities.assert_equals(
2292 expect=True,
2293 actual=hostAttachmentResults,
2294 onpass="Hosts are correctly attached to the network",
2295 onfail="ONOS did not correctly attach hosts to the network" )
2296
2297 # Strongly connected clusters of devices
2298 main.step( "Clusters view is consistent across all ONOS nodes" )
2299 consistentClustersResult = main.TRUE
2300 for controller in range( len( clusters ) ):
2301 controllerStr = str( controller + 1 )
2302 if "Error" not in clusters[ controller ]:
2303 if clusters[ controller ] == clusters[ 0 ]:
2304 continue
2305 else: # clusters not consistent
2306 main.log.error( "clusters from ONOS" +
2307 controllerStr +
2308 " is inconsistent with ONOS1" )
Jon Hall21270ac2015-02-16 17:59:55 -08002309 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002310
Jon Hallc9eabec2015-06-10 14:33:14 -07002311 else:
2312 main.log.error( "Error in getting dataplane clusters " +
2313 "from ONOS" + controllerStr )
2314 consistentClustersResult = main.FALSE
2315 main.log.warn( "ONOS" + controllerStr +
2316 " clusters response: " +
2317 repr( clusters[ controller ] ) )
2318 utilities.assert_equals(
2319 expect=main.TRUE,
2320 actual=consistentClustersResult,
2321 onpass="Clusters view is consistent across all ONOS nodes",
2322 onfail="ONOS nodes have different views of clusters" )
2323
2324 main.step( "There is only one SCC" )
2325 # there should always only be one cluster
2326 try:
2327 numClusters = len( json.loads( clusters[ 0 ] ) )
2328 except ( ValueError, TypeError ):
2329 main.log.exception( "Error parsing clusters[0]: " +
2330 repr( clusters[0] ) )
2331 clusterResults = main.FALSE
2332 if numClusters == 1:
2333 clusterResults = main.TRUE
2334 utilities.assert_equals(
2335 expect=1,
2336 actual=numClusters,
2337 onpass="ONOS shows 1 SCC",
2338 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2339
Jon Hallb87f3db2015-07-06 03:10:27 -07002340 topoResult = ( devicesResults and portsResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002341 and hostsResults and consistentHostsResult
2342 and consistentClustersResult and clusterResults
2343 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002344
Jon Hall21270ac2015-02-16 17:59:55 -08002345 topoResult = topoResult and int( count <= 2 )
2346 note = "note it takes about " + str( int( cliTime ) ) + \
2347 " seconds for the test to make all the cli calls to fetch " +\
2348 "the topology from each ONOS instance"
2349 main.log.info(
2350 "Very crass estimate for topology discovery/convergence( " +
2351 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2352 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002353
2354 main.step( "Device information is correct" )
2355 utilities.assert_equals(
2356 expect=main.TRUE,
2357 actual=devicesResults,
2358 onpass="Device information is correct",
2359 onfail="Device information is incorrect" )
2360
Jon Hallb87f3db2015-07-06 03:10:27 -07002361 main.step( "Port information is correct" )
2362 utilities.assert_equals(
2363 expect=main.TRUE,
2364 actual=portsResults,
2365 onpass="Port information is correct",
2366 onfail="Port information is incorrect" )
2367
Jon Hallc9eabec2015-06-10 14:33:14 -07002368 main.step( "Links are correct" )
2369 utilities.assert_equals(
2370 expect=main.TRUE,
2371 actual=linksResults,
2372 onpass="Link are correct",
2373 onfail="Links are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002374
Jon Halla9d26da2015-03-30 16:45:32 -07002375 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002376 main.step( "Checking ONOS nodes" )
2377 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002378 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002379 threads = []
2380 for i in range( numControllers ):
2381 t = main.Thread( target=CLIs[i].nodes,
2382 name="nodes-" + str( i ),
2383 args=[ ] )
2384 threads.append( t )
2385 t.start()
2386
2387 for t in threads:
2388 t.join()
2389 nodesOutput.append( t.result )
2390 ips = [ node.ip_address for node in nodes ]
2391 for i in nodesOutput:
2392 try:
2393 current = json.loads( i )
2394 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002395 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002396 if node['ip'] in ips: # node in nodes() output is in cell
2397 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002398 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002399 else:
2400 main.log.error( "Error in ONOS node availability" )
2401 main.log.error(
2402 json.dumps( current,
2403 sort_keys=True,
2404 indent=4,
2405 separators=( ',', ': ' ) ) )
2406 break
Jon Hall390696c2015-05-05 17:13:41 -07002407 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002408 except ( ValueError, TypeError ):
2409 main.log.error( "Error parsing nodes output" )
2410 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002411 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2412 onpass="Nodes check successful",
2413 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002414
Jon Hall6aec96b2015-01-19 14:49:31 -08002415 def CASE9( self, main ):
2416 """
Jon Hallb1290e82014-11-18 16:17:48 -05002417 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002418 """
2419 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002420 assert numControllers, "numControllers not defined"
2421 assert main, "main not defined"
2422 assert utilities.assert_equals, "utilities.assert_equals not defined"
2423 assert CLIs, "CLIs not defined"
2424 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002425 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002426
Jon Hall8f89dda2015-01-22 16:03:33 -08002427 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002428
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002430 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002431 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002432
Jon Hall6aec96b2015-01-19 14:49:31 -08002433 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002434 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002435 main.log.info( "Waiting " + str( linkSleep ) +
2436 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002437 time.sleep( linkSleep )
2438 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002439 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002440 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002441 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002442
Jon Hall6aec96b2015-01-19 14:49:31 -08002443 def CASE10( self, main ):
2444 """
Jon Hallb1290e82014-11-18 16:17:48 -05002445 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002446 """
2447 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002448 assert numControllers, "numControllers not defined"
2449 assert main, "main not defined"
2450 assert utilities.assert_equals, "utilities.assert_equals not defined"
2451 assert CLIs, "CLIs not defined"
2452 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002453 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002454
Jon Hall8f89dda2015-01-22 16:03:33 -08002455 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002456
Jon Hall6aec96b2015-01-19 14:49:31 -08002457 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002458 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002459 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002460
Jon Hall6aec96b2015-01-19 14:49:31 -08002461 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002462 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002463 main.log.info( "Waiting " + str( linkSleep ) +
2464 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002465 time.sleep( linkSleep )
2466 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002467 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002468 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002469 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002470
Jon Hall6aec96b2015-01-19 14:49:31 -08002471 def CASE11( self, main ):
2472 """
Jon Hallb1290e82014-11-18 16:17:48 -05002473 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002474 """
2475 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002476 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002477 assert numControllers, "numControllers not defined"
2478 assert main, "main not defined"
2479 assert utilities.assert_equals, "utilities.assert_equals not defined"
2480 assert CLIs, "CLIs not defined"
2481 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002482
Jon Hall8f89dda2015-01-22 16:03:33 -08002483 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002484
2485 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002486 main.case( description )
2487 switch = main.params[ 'kill' ][ 'switch' ]
2488 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002489
Jon Hall6aec96b2015-01-19 14:49:31 -08002490 # TODO: Make this switch parameterizable
2491 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002492 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002493 main.Mininet1.delSwitch( switch )
2494 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002496 time.sleep( switchSleep )
2497 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 # Peek at the deleted switch
2499 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002500 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002501 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002502 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002503 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002504 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002505 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002506
Jon Hall6aec96b2015-01-19 14:49:31 -08002507 def CASE12( self, main ):
2508 """
Jon Hallb1290e82014-11-18 16:17:48 -05002509 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002510 """
2511 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002512 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002513 assert numControllers, "numControllers not defined"
2514 assert main, "main not defined"
2515 assert utilities.assert_equals, "utilities.assert_equals not defined"
2516 assert CLIs, "CLIs not defined"
2517 assert nodes, "nodes not defined"
2518 assert ONOS1Port, "ONOS1Port not defined"
2519 assert ONOS2Port, "ONOS2Port not defined"
2520 assert ONOS3Port, "ONOS3Port not defined"
2521 assert ONOS4Port, "ONOS4Port not defined"
2522 assert ONOS5Port, "ONOS5Port not defined"
2523 assert ONOS6Port, "ONOS6Port not defined"
2524 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002525
Jon Hall8f89dda2015-01-22 16:03:33 -08002526 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002527 switch = main.params[ 'kill' ][ 'switch' ]
2528 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2529 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002530 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002531 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002532
Jon Hall6aec96b2015-01-19 14:49:31 -08002533 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002534 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002535 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002536 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002537 ipList = []
2538 for i in range( numControllers ):
2539 ipList.append( nodes[ i ].ip_address )
2540 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002541 main.log.info( "Waiting " + str( switchSleep ) +
2542 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002543 time.sleep( switchSleep )
2544 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002545 # Peek at the deleted switch
2546 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002547 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002548 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002549 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002550 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002551 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002552 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002553
Jon Hall6aec96b2015-01-19 14:49:31 -08002554 def CASE13( self, main ):
2555 """
Jon Hallb1290e82014-11-18 16:17:48 -05002556 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002557 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002558 import os
2559 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002560 assert numControllers, "numControllers not defined"
2561 assert main, "main not defined"
2562 assert utilities.assert_equals, "utilities.assert_equals not defined"
2563 assert CLIs, "CLIs not defined"
2564 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002565
2566 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002567 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2568 'blue': '\033[94m', 'green': '\033[92m',
2569 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002570 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002571 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002572 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002573
Jon Hall6aec96b2015-01-19 14:49:31 -08002574 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002575 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002576 teststationUser = main.params[ 'TESTONUSER' ]
2577 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002578 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002579 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002580 # FIXME: scp
2581 # mn files
2582 # TODO: Load these from params
2583 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002584 logFolder = "/opt/onos/log/"
2585 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002586 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002587 dstDir = "~/packet_captures/"
2588 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002589 for node in nodes:
2590 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2591 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002592 teststationUser + "@" +
2593 teststationIP + ":" +
2594 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002595 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002596 main.ONOSbench.handle.expect( "\$" )
2597
Jon Hall6aec96b2015-01-19 14:49:31 -08002598 # std*.log's
2599 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002600 logFolder = "/opt/onos/var/"
2601 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002602 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002603 dstDir = "~/packet_captures/"
2604 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002605 for node in nodes:
2606 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2607 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002608 teststationUser + "@" +
2609 teststationIP + ":" +
2610 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002611 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002612 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002613 # sleep so scp can finish
2614 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002615
2616 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002617 mnResult = main.Mininet1.stopNet()
2618 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2619 onpass="Mininet stopped",
2620 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002621
2622 main.step( "Checking ONOS Logs for errors" )
2623 for node in nodes:
2624 print colors[ 'purple' ] + "Checking logs for errors on " + \
2625 node.name + ":" + colors[ 'end' ]
2626 print main.ONOSbench.checkLogs( node.ip_address )
2627
Jon Hall6aec96b2015-01-19 14:49:31 -08002628 main.step( "Packing and rotating pcap archives" )
2629 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002630
Jon Hall390696c2015-05-05 17:13:41 -07002631 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002632 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002633 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002634 labels = "Gossip Intents"
2635 data = str( gossipTime )
2636 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002637 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002638 except NameError, e:
2639 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002640
Jon Hall6aec96b2015-01-19 14:49:31 -08002641 def CASE14( self, main ):
2642 """
Jon Hall94fd0472014-12-08 11:52:42 -08002643 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002644 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002645 assert numControllers, "numControllers not defined"
2646 assert main, "main not defined"
2647 assert utilities.assert_equals, "utilities.assert_equals not defined"
2648 assert CLIs, "CLIs not defined"
2649 assert nodes, "nodes not defined"
2650
Jon Hall390696c2015-05-05 17:13:41 -07002651 main.case("Start Leadership Election app")
2652 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002653 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2654 utilities.assert_equals(
2655 expect=main.TRUE,
2656 actual=appResult,
2657 onpass="Election app installed",
2658 onfail="Something went wrong with installing Leadership election" )
2659
2660 main.step( "Run for election on each node" )
2661 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002662 leaders = []
2663 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002664 cli.electionTestRun()
2665 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002666 leader = cli.electionTestLeader()
2667 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002668 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002669 "should be an ONOS node, instead got '" +
2670 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002671 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002672 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002673 utilities.assert_equals(
2674 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002675 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002676 onpass="Successfully ran for leadership",
2677 onfail="Failed to run for leadership" )
2678
2679 main.step( "Check that each node shows the same leader" )
2680 sameLeader = main.TRUE
2681 if len( set( leaders ) ) != 1:
2682 sameLeader = main.FALSE
2683 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2684 str( leaders ) )
2685 utilities.assert_equals(
2686 expect=main.TRUE,
2687 actual=sameLeader,
2688 onpass="Leadership is consistent for the election topic",
2689 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002690
Jon Hall6aec96b2015-01-19 14:49:31 -08002691 def CASE15( self, main ):
2692 """
Jon Hall669173b2014-12-17 11:36:30 -08002693 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002694 """
Jon Hall390696c2015-05-05 17:13:41 -07002695 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002696 assert numControllers, "numControllers not defined"
2697 assert main, "main not defined"
2698 assert utilities.assert_equals, "utilities.assert_equals not defined"
2699 assert CLIs, "CLIs not defined"
2700 assert nodes, "nodes not defined"
2701
Jon Hall8f89dda2015-01-22 16:03:33 -08002702 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002703 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002704 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002705
2706 main.step( "Check that each node shows the same leader" )
2707 sameLeader = main.TRUE
2708 leaders = []
2709 for cli in CLIs:
2710 leader = cli.electionTestLeader()
2711 leaders.append( leader )
2712 if len( set( leaders ) ) != 1:
2713 sameLeader = main.FALSE
2714 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2715 str( leaders ) )
2716 utilities.assert_equals(
2717 expect=main.TRUE,
2718 actual=sameLeader,
2719 onpass="Leadership is consistent for the election topic",
2720 onfail="Nodes have different leaders" )
2721
Jon Hall6aec96b2015-01-19 14:49:31 -08002722 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002723 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002724 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002725 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002726 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002727 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002728 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002729 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002730 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002731 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002732 for i in range( len( CLIs ) ):
2733 if leader == nodes[ i ].ip_address:
2734 oldLeader = CLIs[ i ]
2735 break
Jon Halla9d26da2015-03-30 16:45:32 -07002736 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002737 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002738 if oldLeader:
2739 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002740 utilities.assert_equals(
2741 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002742 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002743 onpass="Node was withdrawn from election",
2744 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002745
Jon Hall6aec96b2015-01-19 14:49:31 -08002746 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002747 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002748 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002749 for cli in CLIs:
2750 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002751 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002752 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002753 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002754 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002755 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002756 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002757 # error in response
2758 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002759 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002760 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002761 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002762 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002763 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002764 elif leaderN is None:
2765 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002766 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002767 leaderN = cli.electionTestLeader()
2768 leaderList.pop()
2769 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002770 consistentLeader = main.FALSE
2771 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002772 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002773 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002774 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002775 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002776 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002777 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002778 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002779 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002780 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002781 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002782 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002783 utilities.assert_equals(
2784 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002785 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002786 onpass="Leadership election passed",
2787 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002788
Jon Hall58c76b72015-02-23 11:09:24 -08002789 main.step( "Run for election on old leader( just so everyone " +
2790 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002791 if oldLeader:
2792 runResult = oldLeader.electionTestRun()
2793 else:
2794 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002795 utilities.assert_equals(
2796 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002797 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002798 onpass="App re-ran for election",
2799 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002800
Jon Hallfeff3082015-05-19 10:23:26 -07002801 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002802 afterRun = main.ONOScli1.electionTestLeader()
2803 # verify leader didn't just change
2804 if afterRun == leaderList[ 0 ]:
2805 afterResult = main.TRUE
2806 else:
2807 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002808
Jon Hall6aec96b2015-01-19 14:49:31 -08002809 utilities.assert_equals(
2810 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002811 actual=afterResult,
2812 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002813 onfail="Something went wrong with Leadership election after " +
2814 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002815
Jon Hall390696c2015-05-05 17:13:41 -07002816 def CASE16( self, main ):
2817 """
2818 Install Distributed Primitives app
2819 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002820 import time
Jon Hall390696c2015-05-05 17:13:41 -07002821 assert numControllers, "numControllers not defined"
2822 assert main, "main not defined"
2823 assert utilities.assert_equals, "utilities.assert_equals not defined"
2824 assert CLIs, "CLIs not defined"
2825 assert nodes, "nodes not defined"
2826
2827 # Variables for the distributed primitives tests
2828 global pCounterName
2829 global iCounterName
2830 global pCounterValue
2831 global iCounterValue
2832 global onosSet
2833 global onosSetName
2834 pCounterName = "TestON-Partitions"
2835 iCounterName = "TestON-inMemory"
2836 pCounterValue = 0
2837 iCounterValue = 0
2838 onosSet = set([])
2839 onosSetName = "TestON-set"
2840
2841 description = "Install Primitives app"
2842 main.case( description )
2843 main.step( "Install Primitives app" )
2844 appName = "org.onosproject.distributedprimitives"
2845 appResults = CLIs[0].activateApp( appName )
2846 utilities.assert_equals( expect=main.TRUE,
2847 actual=appResults,
2848 onpass="Primitives app activated",
2849 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002850 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002851
2852 def CASE17( self, main ):
2853 """
2854 Check for basic functionality with distributed primitives
2855 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002856 import json
Jon Hall390696c2015-05-05 17:13:41 -07002857 # Make sure variables are defined/set
2858 assert numControllers, "numControllers not defined"
2859 assert main, "main not defined"
2860 assert utilities.assert_equals, "utilities.assert_equals not defined"
2861 assert CLIs, "CLIs not defined"
2862 assert nodes, "nodes not defined"
2863 assert pCounterName, "pCounterName not defined"
2864 assert iCounterName, "iCounterName not defined"
2865 assert onosSetName, "onosSetName not defined"
2866 # NOTE: assert fails if value is 0/None/Empty/False
2867 try:
2868 pCounterValue
2869 except NameError:
2870 main.log.error( "pCounterValue not defined, setting to 0" )
2871 pCounterValue = 0
2872 try:
2873 iCounterValue
2874 except NameError:
2875 main.log.error( "iCounterValue not defined, setting to 0" )
2876 iCounterValue = 0
2877 try:
2878 onosSet
2879 except NameError:
2880 main.log.error( "onosSet not defined, setting to empty Set" )
2881 onosSet = set([])
2882 # Variables for the distributed primitives tests. These are local only
2883 addValue = "a"
2884 addAllValue = "a b c d e f"
2885 retainValue = "c d e f"
2886
2887 description = "Check for basic functionality with distributed " +\
2888 "primitives"
2889 main.case( description )
2890 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2891 # DISTRIBUTED ATOMIC COUNTERS
2892 main.step( "Increment and get a default counter on each node" )
2893 pCounters = []
2894 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002895 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002896 for i in range( numControllers ):
2897 t = main.Thread( target=CLIs[i].counterTestIncrement,
2898 name="counterIncrement-" + str( i ),
2899 args=[ pCounterName ] )
2900 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002901 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002902 threads.append( t )
2903 t.start()
2904
2905 for t in threads:
2906 t.join()
2907 pCounters.append( t.result )
2908 # Check that counter incremented numController times
2909 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002910 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002911 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002912 pCounterResults = pCounterResults and tmpResult
2913 if not tmpResult:
2914 main.log.error( str( i ) + " is not in partitioned "
2915 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002916 utilities.assert_equals( expect=True,
2917 actual=pCounterResults,
2918 onpass="Default counter incremented",
2919 onfail="Error incrementing default" +
2920 " counter" )
2921
2922 main.step( "Increment and get an in memory counter on each node" )
2923 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002924 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002925 threads = []
2926 for i in range( numControllers ):
2927 t = main.Thread( target=CLIs[i].counterTestIncrement,
2928 name="icounterIncrement-" + str( i ),
2929 args=[ iCounterName ],
2930 kwargs={ "inMemory": True } )
2931 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002932 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002933 threads.append( t )
2934 t.start()
2935
2936 for t in threads:
2937 t.join()
2938 iCounters.append( t.result )
2939 # Check that counter incremented numController times
2940 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002941 for i in addedIValues:
2942 tmpResult = i in iCounters
2943 iCounterResults = iCounterResults and tmpResult
2944 if not tmpResult:
2945 main.log.error( str( i ) + " is not in the in-memory "
2946 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002947 utilities.assert_equals( expect=True,
2948 actual=iCounterResults,
2949 onpass="In memory counter incremented",
2950 onfail="Error incrementing in memory" +
2951 " counter" )
2952
2953 main.step( "Check counters are consistant across nodes" )
2954 onosCounters = []
2955 threads = []
2956 for i in range( numControllers ):
2957 t = main.Thread( target=CLIs[i].counters,
2958 name="counters-" + str( i ) )
2959 threads.append( t )
2960 t.start()
2961 for t in threads:
2962 t.join()
2963 onosCounters.append( t.result )
2964 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2965 if all( tmp ):
2966 main.log.info( "Counters are consistent across all nodes" )
2967 consistentCounterResults = main.TRUE
2968 else:
2969 main.log.error( "Counters are not consistent across all nodes" )
2970 consistentCounterResults = main.FALSE
2971 utilities.assert_equals( expect=main.TRUE,
2972 actual=consistentCounterResults,
2973 onpass="ONOS counters are consistent " +
2974 "across nodes",
2975 onfail="ONOS Counters are inconsistent " +
2976 "across nodes" )
2977
2978 main.step( "Counters we added have the correct values" )
2979 correctResults = main.TRUE
2980 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002981 current = json.loads( onosCounters[i] )
2982 pValue = None
2983 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002984 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002985 for database in current:
2986 partitioned = database.get( 'partitionedDatabaseCounters' )
2987 if partitioned:
2988 for value in partitioned:
2989 if value.get( 'name' ) == pCounterName:
2990 pValue = value.get( 'value' )
2991 break
2992 inMemory = database.get( 'inMemoryDatabaseCounters' )
2993 if inMemory:
2994 for value in inMemory:
2995 if value.get( 'name' ) == iCounterName:
2996 iValue = value.get( 'value' )
2997 break
Jon Hall390696c2015-05-05 17:13:41 -07002998 except AttributeError, e:
2999 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3000 "is not as expected" )
3001 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003002 if pValue == pCounterValue:
3003 main.log.info( "Partitioned counter value is correct" )
3004 else:
3005 main.log.error( "Partitioned counter value is incorrect," +
3006 " expected value: " + str( pCounterValue )
3007 + " current value: " + str( pValue ) )
3008 correctResults = main.FALSE
3009 if iValue == iCounterValue:
3010 main.log.info( "In memory counter value is correct" )
3011 else:
3012 main.log.error( "In memory counter value is incorrect, " +
3013 "expected value: " + str( iCounterValue ) +
3014 " current value: " + str( iValue ) )
3015 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003016 utilities.assert_equals( expect=main.TRUE,
3017 actual=correctResults,
3018 onpass="Added counters are correct",
3019 onfail="Added counters are incorrect" )
3020 # DISTRIBUTED SETS
3021 main.step( "Distributed Set get" )
3022 size = len( onosSet )
3023 getResponses = []
3024 threads = []
3025 for i in range( numControllers ):
3026 t = main.Thread( target=CLIs[i].setTestGet,
3027 name="setTestGet-" + str( i ),
3028 args=[ onosSetName ] )
3029 threads.append( t )
3030 t.start()
3031 for t in threads:
3032 t.join()
3033 getResponses.append( t.result )
3034
3035 getResults = main.TRUE
3036 for i in range( numControllers ):
3037 if isinstance( getResponses[ i ], list):
3038 current = set( getResponses[ i ] )
3039 if len( current ) == len( getResponses[ i ] ):
3040 # no repeats
3041 if onosSet != current:
3042 main.log.error( "ONOS" + str( i + 1 ) +
3043 " has incorrect view" +
3044 " of set " + onosSetName + ":\n" +
3045 str( getResponses[ i ] ) )
3046 main.log.debug( "Expected: " + str( onosSet ) )
3047 main.log.debug( "Actual: " + str( current ) )
3048 getResults = main.FALSE
3049 else:
3050 # error, set is not a set
3051 main.log.error( "ONOS" + str( i + 1 ) +
3052 " has repeat elements in" +
3053 " set " + onosSetName + ":\n" +
3054 str( getResponses[ i ] ) )
3055 getResults = main.FALSE
3056 elif getResponses[ i ] == main.ERROR:
3057 getResults = main.FALSE
3058 utilities.assert_equals( expect=main.TRUE,
3059 actual=getResults,
3060 onpass="Set elements are correct",
3061 onfail="Set elements are incorrect" )
3062
3063 main.step( "Distributed Set size" )
3064 sizeResponses = []
3065 threads = []
3066 for i in range( numControllers ):
3067 t = main.Thread( target=CLIs[i].setTestSize,
3068 name="setTestSize-" + str( i ),
3069 args=[ onosSetName ] )
3070 threads.append( t )
3071 t.start()
3072 for t in threads:
3073 t.join()
3074 sizeResponses.append( t.result )
3075
3076 sizeResults = main.TRUE
3077 for i in range( numControllers ):
3078 if size != sizeResponses[ i ]:
3079 sizeResults = main.FALSE
3080 main.log.error( "ONOS" + str( i + 1 ) +
3081 " expected a size of " + str( size ) +
3082 " for set " + onosSetName +
3083 " but got " + str( sizeResponses[ i ] ) )
3084 utilities.assert_equals( expect=main.TRUE,
3085 actual=sizeResults,
3086 onpass="Set sizes are correct",
3087 onfail="Set sizes are incorrect" )
3088
3089 main.step( "Distributed Set add()" )
3090 onosSet.add( addValue )
3091 addResponses = []
3092 threads = []
3093 for i in range( numControllers ):
3094 t = main.Thread( target=CLIs[i].setTestAdd,
3095 name="setTestAdd-" + str( i ),
3096 args=[ onosSetName, addValue ] )
3097 threads.append( t )
3098 t.start()
3099 for t in threads:
3100 t.join()
3101 addResponses.append( t.result )
3102
3103 # main.TRUE = successfully changed the set
3104 # main.FALSE = action resulted in no change in set
3105 # main.ERROR - Some error in executing the function
3106 addResults = main.TRUE
3107 for i in range( numControllers ):
3108 if addResponses[ i ] == main.TRUE:
3109 # All is well
3110 pass
3111 elif addResponses[ i ] == main.FALSE:
3112 # Already in set, probably fine
3113 pass
3114 elif addResponses[ i ] == main.ERROR:
3115 # Error in execution
3116 addResults = main.FALSE
3117 else:
3118 # unexpected result
3119 addResults = main.FALSE
3120 if addResults != main.TRUE:
3121 main.log.error( "Error executing set add" )
3122
3123 # Check if set is still correct
3124 size = len( onosSet )
3125 getResponses = []
3126 threads = []
3127 for i in range( numControllers ):
3128 t = main.Thread( target=CLIs[i].setTestGet,
3129 name="setTestGet-" + str( i ),
3130 args=[ onosSetName ] )
3131 threads.append( t )
3132 t.start()
3133 for t in threads:
3134 t.join()
3135 getResponses.append( t.result )
3136 getResults = main.TRUE
3137 for i in range( numControllers ):
3138 if isinstance( getResponses[ i ], list):
3139 current = set( getResponses[ i ] )
3140 if len( current ) == len( getResponses[ i ] ):
3141 # no repeats
3142 if onosSet != current:
3143 main.log.error( "ONOS" + str( i + 1 ) +
3144 " has incorrect view" +
3145 " of set " + onosSetName + ":\n" +
3146 str( getResponses[ i ] ) )
3147 main.log.debug( "Expected: " + str( onosSet ) )
3148 main.log.debug( "Actual: " + str( current ) )
3149 getResults = main.FALSE
3150 else:
3151 # error, set is not a set
3152 main.log.error( "ONOS" + str( i + 1 ) +
3153 " has repeat elements in" +
3154 " set " + onosSetName + ":\n" +
3155 str( getResponses[ i ] ) )
3156 getResults = main.FALSE
3157 elif getResponses[ i ] == main.ERROR:
3158 getResults = main.FALSE
3159 sizeResponses = []
3160 threads = []
3161 for i in range( numControllers ):
3162 t = main.Thread( target=CLIs[i].setTestSize,
3163 name="setTestSize-" + str( i ),
3164 args=[ onosSetName ] )
3165 threads.append( t )
3166 t.start()
3167 for t in threads:
3168 t.join()
3169 sizeResponses.append( t.result )
3170 sizeResults = main.TRUE
3171 for i in range( numControllers ):
3172 if size != sizeResponses[ i ]:
3173 sizeResults = main.FALSE
3174 main.log.error( "ONOS" + str( i + 1 ) +
3175 " expected a size of " + str( size ) +
3176 " for set " + onosSetName +
3177 " but got " + str( sizeResponses[ i ] ) )
3178 addResults = addResults and getResults and sizeResults
3179 utilities.assert_equals( expect=main.TRUE,
3180 actual=addResults,
3181 onpass="Set add correct",
3182 onfail="Set add was incorrect" )
3183
3184 main.step( "Distributed Set addAll()" )
3185 onosSet.update( addAllValue.split() )
3186 addResponses = []
3187 threads = []
3188 for i in range( numControllers ):
3189 t = main.Thread( target=CLIs[i].setTestAdd,
3190 name="setTestAddAll-" + str( i ),
3191 args=[ onosSetName, addAllValue ] )
3192 threads.append( t )
3193 t.start()
3194 for t in threads:
3195 t.join()
3196 addResponses.append( t.result )
3197
3198 # main.TRUE = successfully changed the set
3199 # main.FALSE = action resulted in no change in set
3200 # main.ERROR - Some error in executing the function
3201 addAllResults = main.TRUE
3202 for i in range( numControllers ):
3203 if addResponses[ i ] == main.TRUE:
3204 # All is well
3205 pass
3206 elif addResponses[ i ] == main.FALSE:
3207 # Already in set, probably fine
3208 pass
3209 elif addResponses[ i ] == main.ERROR:
3210 # Error in execution
3211 addAllResults = main.FALSE
3212 else:
3213 # unexpected result
3214 addAllResults = main.FALSE
3215 if addAllResults != main.TRUE:
3216 main.log.error( "Error executing set addAll" )
3217
3218 # Check if set is still correct
3219 size = len( onosSet )
3220 getResponses = []
3221 threads = []
3222 for i in range( numControllers ):
3223 t = main.Thread( target=CLIs[i].setTestGet,
3224 name="setTestGet-" + str( i ),
3225 args=[ onosSetName ] )
3226 threads.append( t )
3227 t.start()
3228 for t in threads:
3229 t.join()
3230 getResponses.append( t.result )
3231 getResults = main.TRUE
3232 for i in range( numControllers ):
3233 if isinstance( getResponses[ i ], list):
3234 current = set( getResponses[ i ] )
3235 if len( current ) == len( getResponses[ i ] ):
3236 # no repeats
3237 if onosSet != current:
3238 main.log.error( "ONOS" + str( i + 1 ) +
3239 " has incorrect view" +
3240 " of set " + onosSetName + ":\n" +
3241 str( getResponses[ i ] ) )
3242 main.log.debug( "Expected: " + str( onosSet ) )
3243 main.log.debug( "Actual: " + str( current ) )
3244 getResults = main.FALSE
3245 else:
3246 # error, set is not a set
3247 main.log.error( "ONOS" + str( i + 1 ) +
3248 " has repeat elements in" +
3249 " set " + onosSetName + ":\n" +
3250 str( getResponses[ i ] ) )
3251 getResults = main.FALSE
3252 elif getResponses[ i ] == main.ERROR:
3253 getResults = main.FALSE
3254 sizeResponses = []
3255 threads = []
3256 for i in range( numControllers ):
3257 t = main.Thread( target=CLIs[i].setTestSize,
3258 name="setTestSize-" + str( i ),
3259 args=[ onosSetName ] )
3260 threads.append( t )
3261 t.start()
3262 for t in threads:
3263 t.join()
3264 sizeResponses.append( t.result )
3265 sizeResults = main.TRUE
3266 for i in range( numControllers ):
3267 if size != sizeResponses[ i ]:
3268 sizeResults = main.FALSE
3269 main.log.error( "ONOS" + str( i + 1 ) +
3270 " expected a size of " + str( size ) +
3271 " for set " + onosSetName +
3272 " but got " + str( sizeResponses[ i ] ) )
3273 addAllResults = addAllResults and getResults and sizeResults
3274 utilities.assert_equals( expect=main.TRUE,
3275 actual=addAllResults,
3276 onpass="Set addAll correct",
3277 onfail="Set addAll was incorrect" )
3278
3279 main.step( "Distributed Set contains()" )
3280 containsResponses = []
3281 threads = []
3282 for i in range( numControllers ):
3283 t = main.Thread( target=CLIs[i].setTestGet,
3284 name="setContains-" + str( i ),
3285 args=[ onosSetName ],
3286 kwargs={ "values": addValue } )
3287 threads.append( t )
3288 t.start()
3289 for t in threads:
3290 t.join()
3291 # NOTE: This is the tuple
3292 containsResponses.append( t.result )
3293
3294 containsResults = main.TRUE
3295 for i in range( numControllers ):
3296 if containsResponses[ i ] == main.ERROR:
3297 containsResults = main.FALSE
3298 else:
3299 containsResults = containsResults and\
3300 containsResponses[ i ][ 1 ]
3301 utilities.assert_equals( expect=main.TRUE,
3302 actual=containsResults,
3303 onpass="Set contains is functional",
3304 onfail="Set contains failed" )
3305
3306 main.step( "Distributed Set containsAll()" )
3307 containsAllResponses = []
3308 threads = []
3309 for i in range( numControllers ):
3310 t = main.Thread( target=CLIs[i].setTestGet,
3311 name="setContainsAll-" + str( i ),
3312 args=[ onosSetName ],
3313 kwargs={ "values": addAllValue } )
3314 threads.append( t )
3315 t.start()
3316 for t in threads:
3317 t.join()
3318 # NOTE: This is the tuple
3319 containsAllResponses.append( t.result )
3320
3321 containsAllResults = main.TRUE
3322 for i in range( numControllers ):
3323 if containsResponses[ i ] == main.ERROR:
3324 containsResults = main.FALSE
3325 else:
3326 containsResults = containsResults and\
3327 containsResponses[ i ][ 1 ]
3328 utilities.assert_equals( expect=main.TRUE,
3329 actual=containsAllResults,
3330 onpass="Set containsAll is functional",
3331 onfail="Set containsAll failed" )
3332
3333 main.step( "Distributed Set remove()" )
3334 onosSet.remove( addValue )
3335 removeResponses = []
3336 threads = []
3337 for i in range( numControllers ):
3338 t = main.Thread( target=CLIs[i].setTestRemove,
3339 name="setTestRemove-" + str( i ),
3340 args=[ onosSetName, addValue ] )
3341 threads.append( t )
3342 t.start()
3343 for t in threads:
3344 t.join()
3345 removeResponses.append( t.result )
3346
3347 # main.TRUE = successfully changed the set
3348 # main.FALSE = action resulted in no change in set
3349 # main.ERROR - Some error in executing the function
3350 removeResults = main.TRUE
3351 for i in range( numControllers ):
3352 if removeResponses[ i ] == main.TRUE:
3353 # All is well
3354 pass
3355 elif removeResponses[ i ] == main.FALSE:
3356 # not in set, probably fine
3357 pass
3358 elif removeResponses[ i ] == main.ERROR:
3359 # Error in execution
3360 removeResults = main.FALSE
3361 else:
3362 # unexpected result
3363 removeResults = main.FALSE
3364 if removeResults != main.TRUE:
3365 main.log.error( "Error executing set remove" )
3366
3367 # Check if set is still correct
3368 size = len( onosSet )
3369 getResponses = []
3370 threads = []
3371 for i in range( numControllers ):
3372 t = main.Thread( target=CLIs[i].setTestGet,
3373 name="setTestGet-" + str( i ),
3374 args=[ onosSetName ] )
3375 threads.append( t )
3376 t.start()
3377 for t in threads:
3378 t.join()
3379 getResponses.append( t.result )
3380 getResults = main.TRUE
3381 for i in range( numControllers ):
3382 if isinstance( getResponses[ i ], list):
3383 current = set( getResponses[ i ] )
3384 if len( current ) == len( getResponses[ i ] ):
3385 # no repeats
3386 if onosSet != current:
3387 main.log.error( "ONOS" + str( i + 1 ) +
3388 " has incorrect view" +
3389 " of set " + onosSetName + ":\n" +
3390 str( getResponses[ i ] ) )
3391 main.log.debug( "Expected: " + str( onosSet ) )
3392 main.log.debug( "Actual: " + str( current ) )
3393 getResults = main.FALSE
3394 else:
3395 # error, set is not a set
3396 main.log.error( "ONOS" + str( i + 1 ) +
3397 " has repeat elements in" +
3398 " set " + onosSetName + ":\n" +
3399 str( getResponses[ i ] ) )
3400 getResults = main.FALSE
3401 elif getResponses[ i ] == main.ERROR:
3402 getResults = main.FALSE
3403 sizeResponses = []
3404 threads = []
3405 for i in range( numControllers ):
3406 t = main.Thread( target=CLIs[i].setTestSize,
3407 name="setTestSize-" + str( i ),
3408 args=[ onosSetName ] )
3409 threads.append( t )
3410 t.start()
3411 for t in threads:
3412 t.join()
3413 sizeResponses.append( t.result )
3414 sizeResults = main.TRUE
3415 for i in range( numControllers ):
3416 if size != sizeResponses[ i ]:
3417 sizeResults = main.FALSE
3418 main.log.error( "ONOS" + str( i + 1 ) +
3419 " expected a size of " + str( size ) +
3420 " for set " + onosSetName +
3421 " but got " + str( sizeResponses[ i ] ) )
3422 removeResults = removeResults and getResults and sizeResults
3423 utilities.assert_equals( expect=main.TRUE,
3424 actual=removeResults,
3425 onpass="Set remove correct",
3426 onfail="Set remove was incorrect" )
3427
3428 main.step( "Distributed Set removeAll()" )
3429 onosSet.difference_update( addAllValue.split() )
3430 removeAllResponses = []
3431 threads = []
3432 try:
3433 for i in range( numControllers ):
3434 t = main.Thread( target=CLIs[i].setTestRemove,
3435 name="setTestRemoveAll-" + str( i ),
3436 args=[ onosSetName, addAllValue ] )
3437 threads.append( t )
3438 t.start()
3439 for t in threads:
3440 t.join()
3441 removeAllResponses.append( t.result )
3442 except Exception, e:
3443 main.log.exception(e)
3444
3445 # main.TRUE = successfully changed the set
3446 # main.FALSE = action resulted in no change in set
3447 # main.ERROR - Some error in executing the function
3448 removeAllResults = main.TRUE
3449 for i in range( numControllers ):
3450 if removeAllResponses[ i ] == main.TRUE:
3451 # All is well
3452 pass
3453 elif removeAllResponses[ i ] == main.FALSE:
3454 # not in set, probably fine
3455 pass
3456 elif removeAllResponses[ i ] == main.ERROR:
3457 # Error in execution
3458 removeAllResults = main.FALSE
3459 else:
3460 # unexpected result
3461 removeAllResults = main.FALSE
3462 if removeAllResults != main.TRUE:
3463 main.log.error( "Error executing set removeAll" )
3464
3465 # Check if set is still correct
3466 size = len( onosSet )
3467 getResponses = []
3468 threads = []
3469 for i in range( numControllers ):
3470 t = main.Thread( target=CLIs[i].setTestGet,
3471 name="setTestGet-" + str( i ),
3472 args=[ onosSetName ] )
3473 threads.append( t )
3474 t.start()
3475 for t in threads:
3476 t.join()
3477 getResponses.append( t.result )
3478 getResults = main.TRUE
3479 for i in range( numControllers ):
3480 if isinstance( getResponses[ i ], list):
3481 current = set( getResponses[ i ] )
3482 if len( current ) == len( getResponses[ i ] ):
3483 # no repeats
3484 if onosSet != current:
3485 main.log.error( "ONOS" + str( i + 1 ) +
3486 " has incorrect view" +
3487 " of set " + onosSetName + ":\n" +
3488 str( getResponses[ i ] ) )
3489 main.log.debug( "Expected: " + str( onosSet ) )
3490 main.log.debug( "Actual: " + str( current ) )
3491 getResults = main.FALSE
3492 else:
3493 # error, set is not a set
3494 main.log.error( "ONOS" + str( i + 1 ) +
3495 " has repeat elements in" +
3496 " set " + onosSetName + ":\n" +
3497 str( getResponses[ i ] ) )
3498 getResults = main.FALSE
3499 elif getResponses[ i ] == main.ERROR:
3500 getResults = main.FALSE
3501 sizeResponses = []
3502 threads = []
3503 for i in range( numControllers ):
3504 t = main.Thread( target=CLIs[i].setTestSize,
3505 name="setTestSize-" + str( i ),
3506 args=[ onosSetName ] )
3507 threads.append( t )
3508 t.start()
3509 for t in threads:
3510 t.join()
3511 sizeResponses.append( t.result )
3512 sizeResults = main.TRUE
3513 for i in range( numControllers ):
3514 if size != sizeResponses[ i ]:
3515 sizeResults = main.FALSE
3516 main.log.error( "ONOS" + str( i + 1 ) +
3517 " expected a size of " + str( size ) +
3518 " for set " + onosSetName +
3519 " but got " + str( sizeResponses[ i ] ) )
3520 removeAllResults = removeAllResults and getResults and sizeResults
3521 utilities.assert_equals( expect=main.TRUE,
3522 actual=removeAllResults,
3523 onpass="Set removeAll correct",
3524 onfail="Set removeAll was incorrect" )
3525
3526 main.step( "Distributed Set addAll()" )
3527 onosSet.update( addAllValue.split() )
3528 addResponses = []
3529 threads = []
3530 for i in range( numControllers ):
3531 t = main.Thread( target=CLIs[i].setTestAdd,
3532 name="setTestAddAll-" + str( i ),
3533 args=[ onosSetName, addAllValue ] )
3534 threads.append( t )
3535 t.start()
3536 for t in threads:
3537 t.join()
3538 addResponses.append( t.result )
3539
3540 # main.TRUE = successfully changed the set
3541 # main.FALSE = action resulted in no change in set
3542 # main.ERROR - Some error in executing the function
3543 addAllResults = main.TRUE
3544 for i in range( numControllers ):
3545 if addResponses[ i ] == main.TRUE:
3546 # All is well
3547 pass
3548 elif addResponses[ i ] == main.FALSE:
3549 # Already in set, probably fine
3550 pass
3551 elif addResponses[ i ] == main.ERROR:
3552 # Error in execution
3553 addAllResults = main.FALSE
3554 else:
3555 # unexpected result
3556 addAllResults = main.FALSE
3557 if addAllResults != main.TRUE:
3558 main.log.error( "Error executing set addAll" )
3559
3560 # Check if set is still correct
3561 size = len( onosSet )
3562 getResponses = []
3563 threads = []
3564 for i in range( numControllers ):
3565 t = main.Thread( target=CLIs[i].setTestGet,
3566 name="setTestGet-" + str( i ),
3567 args=[ onosSetName ] )
3568 threads.append( t )
3569 t.start()
3570 for t in threads:
3571 t.join()
3572 getResponses.append( t.result )
3573 getResults = main.TRUE
3574 for i in range( numControllers ):
3575 if isinstance( getResponses[ i ], list):
3576 current = set( getResponses[ i ] )
3577 if len( current ) == len( getResponses[ i ] ):
3578 # no repeats
3579 if onosSet != current:
3580 main.log.error( "ONOS" + str( i + 1 ) +
3581 " has incorrect view" +
3582 " of set " + onosSetName + ":\n" +
3583 str( getResponses[ i ] ) )
3584 main.log.debug( "Expected: " + str( onosSet ) )
3585 main.log.debug( "Actual: " + str( current ) )
3586 getResults = main.FALSE
3587 else:
3588 # error, set is not a set
3589 main.log.error( "ONOS" + str( i + 1 ) +
3590 " has repeat elements in" +
3591 " set " + onosSetName + ":\n" +
3592 str( getResponses[ i ] ) )
3593 getResults = main.FALSE
3594 elif getResponses[ i ] == main.ERROR:
3595 getResults = main.FALSE
3596 sizeResponses = []
3597 threads = []
3598 for i in range( numControllers ):
3599 t = main.Thread( target=CLIs[i].setTestSize,
3600 name="setTestSize-" + str( i ),
3601 args=[ onosSetName ] )
3602 threads.append( t )
3603 t.start()
3604 for t in threads:
3605 t.join()
3606 sizeResponses.append( t.result )
3607 sizeResults = main.TRUE
3608 for i in range( numControllers ):
3609 if size != sizeResponses[ i ]:
3610 sizeResults = main.FALSE
3611 main.log.error( "ONOS" + str( i + 1 ) +
3612 " expected a size of " + str( size ) +
3613 " for set " + onosSetName +
3614 " but got " + str( sizeResponses[ i ] ) )
3615 addAllResults = addAllResults and getResults and sizeResults
3616 utilities.assert_equals( expect=main.TRUE,
3617 actual=addAllResults,
3618 onpass="Set addAll correct",
3619 onfail="Set addAll was incorrect" )
3620
3621 main.step( "Distributed Set clear()" )
3622 onosSet.clear()
3623 clearResponses = []
3624 threads = []
3625 for i in range( numControllers ):
3626 t = main.Thread( target=CLIs[i].setTestRemove,
3627 name="setTestClear-" + str( i ),
3628 args=[ onosSetName, " "], # Values doesn't matter
3629 kwargs={ "clear": True } )
3630 threads.append( t )
3631 t.start()
3632 for t in threads:
3633 t.join()
3634 clearResponses.append( t.result )
3635
3636 # main.TRUE = successfully changed the set
3637 # main.FALSE = action resulted in no change in set
3638 # main.ERROR - Some error in executing the function
3639 clearResults = main.TRUE
3640 for i in range( numControllers ):
3641 if clearResponses[ i ] == main.TRUE:
3642 # All is well
3643 pass
3644 elif clearResponses[ i ] == main.FALSE:
3645 # Nothing set, probably fine
3646 pass
3647 elif clearResponses[ i ] == main.ERROR:
3648 # Error in execution
3649 clearResults = main.FALSE
3650 else:
3651 # unexpected result
3652 clearResults = main.FALSE
3653 if clearResults != main.TRUE:
3654 main.log.error( "Error executing set clear" )
3655
3656 # Check if set is still correct
3657 size = len( onosSet )
3658 getResponses = []
3659 threads = []
3660 for i in range( numControllers ):
3661 t = main.Thread( target=CLIs[i].setTestGet,
3662 name="setTestGet-" + str( i ),
3663 args=[ onosSetName ] )
3664 threads.append( t )
3665 t.start()
3666 for t in threads:
3667 t.join()
3668 getResponses.append( t.result )
3669 getResults = main.TRUE
3670 for i in range( numControllers ):
3671 if isinstance( getResponses[ i ], list):
3672 current = set( getResponses[ i ] )
3673 if len( current ) == len( getResponses[ i ] ):
3674 # no repeats
3675 if onosSet != current:
3676 main.log.error( "ONOS" + str( i + 1 ) +
3677 " has incorrect view" +
3678 " of set " + onosSetName + ":\n" +
3679 str( getResponses[ i ] ) )
3680 main.log.debug( "Expected: " + str( onosSet ) )
3681 main.log.debug( "Actual: " + str( current ) )
3682 getResults = main.FALSE
3683 else:
3684 # error, set is not a set
3685 main.log.error( "ONOS" + str( i + 1 ) +
3686 " has repeat elements in" +
3687 " set " + onosSetName + ":\n" +
3688 str( getResponses[ i ] ) )
3689 getResults = main.FALSE
3690 elif getResponses[ i ] == main.ERROR:
3691 getResults = main.FALSE
3692 sizeResponses = []
3693 threads = []
3694 for i in range( numControllers ):
3695 t = main.Thread( target=CLIs[i].setTestSize,
3696 name="setTestSize-" + str( i ),
3697 args=[ onosSetName ] )
3698 threads.append( t )
3699 t.start()
3700 for t in threads:
3701 t.join()
3702 sizeResponses.append( t.result )
3703 sizeResults = main.TRUE
3704 for i in range( numControllers ):
3705 if size != sizeResponses[ i ]:
3706 sizeResults = main.FALSE
3707 main.log.error( "ONOS" + str( i + 1 ) +
3708 " expected a size of " + str( size ) +
3709 " for set " + onosSetName +
3710 " but got " + str( sizeResponses[ i ] ) )
3711 clearResults = clearResults and getResults and sizeResults
3712 utilities.assert_equals( expect=main.TRUE,
3713 actual=clearResults,
3714 onpass="Set clear correct",
3715 onfail="Set clear was incorrect" )
3716
3717 main.step( "Distributed Set addAll()" )
3718 onosSet.update( addAllValue.split() )
3719 addResponses = []
3720 threads = []
3721 for i in range( numControllers ):
3722 t = main.Thread( target=CLIs[i].setTestAdd,
3723 name="setTestAddAll-" + str( i ),
3724 args=[ onosSetName, addAllValue ] )
3725 threads.append( t )
3726 t.start()
3727 for t in threads:
3728 t.join()
3729 addResponses.append( t.result )
3730
3731 # main.TRUE = successfully changed the set
3732 # main.FALSE = action resulted in no change in set
3733 # main.ERROR - Some error in executing the function
3734 addAllResults = main.TRUE
3735 for i in range( numControllers ):
3736 if addResponses[ i ] == main.TRUE:
3737 # All is well
3738 pass
3739 elif addResponses[ i ] == main.FALSE:
3740 # Already in set, probably fine
3741 pass
3742 elif addResponses[ i ] == main.ERROR:
3743 # Error in execution
3744 addAllResults = main.FALSE
3745 else:
3746 # unexpected result
3747 addAllResults = main.FALSE
3748 if addAllResults != main.TRUE:
3749 main.log.error( "Error executing set addAll" )
3750
3751 # Check if set is still correct
3752 size = len( onosSet )
3753 getResponses = []
3754 threads = []
3755 for i in range( numControllers ):
3756 t = main.Thread( target=CLIs[i].setTestGet,
3757 name="setTestGet-" + str( i ),
3758 args=[ onosSetName ] )
3759 threads.append( t )
3760 t.start()
3761 for t in threads:
3762 t.join()
3763 getResponses.append( t.result )
3764 getResults = main.TRUE
3765 for i in range( numControllers ):
3766 if isinstance( getResponses[ i ], list):
3767 current = set( getResponses[ i ] )
3768 if len( current ) == len( getResponses[ i ] ):
3769 # no repeats
3770 if onosSet != current:
3771 main.log.error( "ONOS" + str( i + 1 ) +
3772 " has incorrect view" +
3773 " of set " + onosSetName + ":\n" +
3774 str( getResponses[ i ] ) )
3775 main.log.debug( "Expected: " + str( onosSet ) )
3776 main.log.debug( "Actual: " + str( current ) )
3777 getResults = main.FALSE
3778 else:
3779 # error, set is not a set
3780 main.log.error( "ONOS" + str( i + 1 ) +
3781 " has repeat elements in" +
3782 " set " + onosSetName + ":\n" +
3783 str( getResponses[ i ] ) )
3784 getResults = main.FALSE
3785 elif getResponses[ i ] == main.ERROR:
3786 getResults = main.FALSE
3787 sizeResponses = []
3788 threads = []
3789 for i in range( numControllers ):
3790 t = main.Thread( target=CLIs[i].setTestSize,
3791 name="setTestSize-" + str( i ),
3792 args=[ onosSetName ] )
3793 threads.append( t )
3794 t.start()
3795 for t in threads:
3796 t.join()
3797 sizeResponses.append( t.result )
3798 sizeResults = main.TRUE
3799 for i in range( numControllers ):
3800 if size != sizeResponses[ i ]:
3801 sizeResults = main.FALSE
3802 main.log.error( "ONOS" + str( i + 1 ) +
3803 " expected a size of " + str( size ) +
3804 " for set " + onosSetName +
3805 " but got " + str( sizeResponses[ i ] ) )
3806 addAllResults = addAllResults and getResults and sizeResults
3807 utilities.assert_equals( expect=main.TRUE,
3808 actual=addAllResults,
3809 onpass="Set addAll correct",
3810 onfail="Set addAll was incorrect" )
3811
3812 main.step( "Distributed Set retain()" )
3813 onosSet.intersection_update( retainValue.split() )
3814 retainResponses = []
3815 threads = []
3816 for i in range( numControllers ):
3817 t = main.Thread( target=CLIs[i].setTestRemove,
3818 name="setTestRetain-" + str( i ),
3819 args=[ onosSetName, retainValue ],
3820 kwargs={ "retain": True } )
3821 threads.append( t )
3822 t.start()
3823 for t in threads:
3824 t.join()
3825 retainResponses.append( t.result )
3826
3827 # main.TRUE = successfully changed the set
3828 # main.FALSE = action resulted in no change in set
3829 # main.ERROR - Some error in executing the function
3830 retainResults = main.TRUE
3831 for i in range( numControllers ):
3832 if retainResponses[ i ] == main.TRUE:
3833 # All is well
3834 pass
3835 elif retainResponses[ i ] == main.FALSE:
3836 # Already in set, probably fine
3837 pass
3838 elif retainResponses[ i ] == main.ERROR:
3839 # Error in execution
3840 retainResults = main.FALSE
3841 else:
3842 # unexpected result
3843 retainResults = main.FALSE
3844 if retainResults != main.TRUE:
3845 main.log.error( "Error executing set retain" )
3846
3847 # Check if set is still correct
3848 size = len( onosSet )
3849 getResponses = []
3850 threads = []
3851 for i in range( numControllers ):
3852 t = main.Thread( target=CLIs[i].setTestGet,
3853 name="setTestGet-" + str( i ),
3854 args=[ onosSetName ] )
3855 threads.append( t )
3856 t.start()
3857 for t in threads:
3858 t.join()
3859 getResponses.append( t.result )
3860 getResults = main.TRUE
3861 for i in range( numControllers ):
3862 if isinstance( getResponses[ i ], list):
3863 current = set( getResponses[ i ] )
3864 if len( current ) == len( getResponses[ i ] ):
3865 # no repeats
3866 if onosSet != current:
3867 main.log.error( "ONOS" + str( i + 1 ) +
3868 " has incorrect view" +
3869 " of set " + onosSetName + ":\n" +
3870 str( getResponses[ i ] ) )
3871 main.log.debug( "Expected: " + str( onosSet ) )
3872 main.log.debug( "Actual: " + str( current ) )
3873 getResults = main.FALSE
3874 else:
3875 # error, set is not a set
3876 main.log.error( "ONOS" + str( i + 1 ) +
3877 " has repeat elements in" +
3878 " set " + onosSetName + ":\n" +
3879 str( getResponses[ i ] ) )
3880 getResults = main.FALSE
3881 elif getResponses[ i ] == main.ERROR:
3882 getResults = main.FALSE
3883 sizeResponses = []
3884 threads = []
3885 for i in range( numControllers ):
3886 t = main.Thread( target=CLIs[i].setTestSize,
3887 name="setTestSize-" + str( i ),
3888 args=[ onosSetName ] )
3889 threads.append( t )
3890 t.start()
3891 for t in threads:
3892 t.join()
3893 sizeResponses.append( t.result )
3894 sizeResults = main.TRUE
3895 for i in range( numControllers ):
3896 if size != sizeResponses[ i ]:
3897 sizeResults = main.FALSE
3898 main.log.error( "ONOS" + str( i + 1 ) +
3899 " expected a size of " +
3900 str( size ) + " for set " + onosSetName +
3901 " but got " + str( sizeResponses[ i ] ) )
3902 retainResults = retainResults and getResults and sizeResults
3903 utilities.assert_equals( expect=main.TRUE,
3904 actual=retainResults,
3905 onpass="Set retain correct",
3906 onfail="Set retain was incorrect" )
3907