blob: a502918dce1dd9afa75a55ad940ec495c8c34f36 [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 Hallafa8a472015-06-12 14:02:42 -0700668 main.log.warn( "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 Hall6aec96b2015-01-19 14:49:31 -08001403 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001404 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001405 threads = []
1406 for i in range( numControllers ):
1407 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001408 name="devices-" + str( i ),
1409 args=[ ] )
1410 threads.append( t )
1411 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001412
1413 for t in threads:
1414 t.join()
1415 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001416 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001417 threads = []
1418 for i in range( numControllers ):
1419 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001420 name="hosts-" + str( i ),
1421 args=[ ] )
1422 threads.append( t )
1423 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001424
1425 for t in threads:
1426 t.join()
1427 try:
1428 hosts.append( json.loads( t.result ) )
1429 except ( ValueError, TypeError ):
1430 # FIXME: better handling of this, print which node
1431 # Maybe use thread name?
1432 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001433 # FIXME: should this be an empty json object instead?
1434 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001435
Jon Hallb1290e82014-11-18 16:17:48 -05001436 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001437 threads = []
1438 for i in range( numControllers ):
1439 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001440 name="ports-" + str( i ),
1441 args=[ ] )
1442 threads.append( t )
1443 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001444
1445 for t in threads:
1446 t.join()
1447 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001448 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001449 threads = []
1450 for i in range( numControllers ):
1451 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001452 name="links-" + str( i ),
1453 args=[ ] )
1454 threads.append( t )
1455 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001456
1457 for t in threads:
1458 t.join()
1459 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001460 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001461 threads = []
1462 for i in range( numControllers ):
1463 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001464 name="clusters-" + str( i ),
1465 args=[ ] )
1466 threads.append( t )
1467 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001468
1469 for t in threads:
1470 t.join()
1471 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001472 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001473
Jon Hall6aec96b2015-01-19 14:49:31 -08001474 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001475 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001476 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001477 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001478 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001479 if "Error" not in hosts[ controller ]:
1480 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001481 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001482 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001483 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001484 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001485 " is inconsistent with ONOS1" )
1486 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001487 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001488
1489 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001490 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001491 controllerStr )
1492 consistentHostsResult = main.FALSE
1493 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001494 " hosts response: " +
1495 repr( hosts[ controller ] ) )
1496 utilities.assert_equals(
1497 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001498 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001499 onpass="Hosts view is consistent across all ONOS nodes",
1500 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001501
Jon Hall390696c2015-05-05 17:13:41 -07001502 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001503 ipResult = main.TRUE
1504 for controller in range( 0, len( hosts ) ):
1505 controllerStr = str( controller + 1 )
1506 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001507 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001508 main.log.error( "DEBUG:Error with host ips on controller" +
1509 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001510 ipResult = main.FALSE
1511 utilities.assert_equals(
1512 expect=main.TRUE,
1513 actual=ipResult,
1514 onpass="The ips of the hosts aren't empty",
1515 onfail="The ip of at least one host is missing" )
1516
Jon Hall6aec96b2015-01-19 14:49:31 -08001517 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001518 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001519 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001520 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001521 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001522 if "Error" not in clusters[ controller ]:
1523 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001524 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001525 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001526 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001527 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001528 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001529
1530 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001531 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001532 "from ONOS" + controllerStr )
1533 consistentClustersResult = main.FALSE
1534 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001535 " clusters response: " +
1536 repr( clusters[ controller ] ) )
1537 utilities.assert_equals(
1538 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001539 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001540 onpass="Clusters view is consistent across all ONOS nodes",
1541 onfail="ONOS nodes have different views of clusters" )
1542 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001543 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001544 try:
1545 numClusters = len( json.loads( clusters[ 0 ] ) )
1546 except ( ValueError, TypeError ):
1547 main.log.exception( "Error parsing clusters[0]: " +
1548 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001549 clusterResults = main.FALSE
1550 if numClusters == 1:
1551 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001552 utilities.assert_equals(
1553 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001554 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001555 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001556 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001557
Jon Hall6aec96b2015-01-19 14:49:31 -08001558 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001559 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001560 linksResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001561 hostsResults = main.TRUE
1562 mnSwitches = main.Mininet1.getSwitches()
1563 mnLinks = main.Mininet1.getLinks()
1564 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001565 for controller in range( numControllers ):
1566 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001567 if devices[ controller ] and ports[ controller ] and\
1568 "Error" not in devices[ controller ] and\
1569 "Error" not in ports[ controller ]:
1570
Jon Hall8f89dda2015-01-22 16:03:33 -08001571 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001572 mnSwitches,
1573 json.loads( devices[ controller ] ),
1574 json.loads( ports[ 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 Hallafa8a472015-06-12 14:02:42 -07001583 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001584 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001585 mnSwitches, mnLinks,
1586 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001587 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001588 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001589 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001590 actual=currentLinksResult,
1591 onpass="ONOS" + controllerStr +
1592 " links view is correct",
1593 onfail="ONOS" + controllerStr +
1594 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001595
Jon Hallafa8a472015-06-12 14:02:42 -07001596 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1597 currentHostsResult = main.Mininet1.compareHosts(
1598 mnHosts,
1599 hosts[ controller ] )
1600 else:
1601 currentHostsResult = main.FALSE
1602 utilities.assert_equals( expect=main.TRUE,
1603 actual=currentHostsResult,
1604 onpass="ONOS" + controllerStr +
1605 " hosts exist in Mininet",
1606 onfail="ONOS" + controllerStr +
1607 " hosts don't match Mininet" )
Jon Hallb6a54872015-06-12 14:02:42 -07001608
Jon Hallafa8a472015-06-12 14:02:42 -07001609 devicesResults = devicesResults and currentDevicesResult
1610 linksResults = linksResults and currentLinksResult
1611 hostsResults = hostsResults and currentHostsResult
1612
1613 main.step( "Device information is correct" )
1614 utilities.assert_equals(
1615 expect=main.TRUE,
1616 actual=devicesResults,
1617 onpass="Device information is correct",
1618 onfail="Device information is incorrect" )
1619
1620 main.step( "Links are correct" )
1621 utilities.assert_equals(
1622 expect=main.TRUE,
1623 actual=linksResults,
1624 onpass="Link are correct",
1625 onfail="Links are incorrect" )
1626
1627 main.step( "Hosts are correct" )
1628 utilities.assert_equals(
1629 expect=main.TRUE,
1630 actual=hostsResults,
1631 onpass="Hosts are correct",
1632 onfail="Hosts are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001633
Jon Hall6aec96b2015-01-19 14:49:31 -08001634 def CASE6( self, main ):
1635 """
Jon Hallb1290e82014-11-18 16:17:48 -05001636 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001637 """
Jon Hall368769f2014-11-19 15:43:35 -08001638 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001639 assert numControllers, "numControllers not defined"
1640 assert main, "main not defined"
1641 assert utilities.assert_equals, "utilities.assert_equals not defined"
1642 assert CLIs, "CLIs not defined"
1643 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001644 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001645 time.sleep( 60 )
1646 utilities.assert_equals(
1647 expect=main.TRUE,
1648 actual=main.TRUE,
1649 onpass="Sleeping 60 seconds",
1650 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001651
Jon Hall6aec96b2015-01-19 14:49:31 -08001652 def CASE7( self, main ):
1653 """
Jon Hall368769f2014-11-19 15:43:35 -08001654 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001655 """
Jon Hallb1290e82014-11-18 16:17:48 -05001656 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001657 assert numControllers, "numControllers not defined"
1658 assert main, "main not defined"
1659 assert utilities.assert_equals, "utilities.assert_equals not defined"
1660 assert CLIs, "CLIs not defined"
1661 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001662 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001663
Jon Hall65844a32015-03-09 19:09:37 -07001664 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001665 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001666 rolesNotNull = main.TRUE
1667 threads = []
1668 for i in range( numControllers ):
1669 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001670 name="rolesNotNull-" + str( i ),
1671 args=[ ] )
1672 threads.append( t )
1673 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001674
1675 for t in threads:
1676 t.join()
1677 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001678 utilities.assert_equals(
1679 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001680 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001681 onpass="Each device has a master",
1682 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001683
Jon Hall390696c2015-05-05 17:13:41 -07001684 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001685 ONOSMastership = []
1686 mastershipCheck = main.FALSE
1687 consistentMastership = True
1688 rolesResults = True
1689 threads = []
1690 for i in range( numControllers ):
1691 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001692 name="roles-" + str( i ),
1693 args=[] )
1694 threads.append( t )
1695 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001696
1697 for t in threads:
1698 t.join()
1699 ONOSMastership.append( t.result )
1700
1701 for i in range( numControllers ):
1702 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001703 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001704 " roles" )
1705 main.log.warn(
1706 "ONOS" + str( i + 1 ) + " mastership response: " +
1707 repr( ONOSMastership[i] ) )
1708 rolesResults = False
1709 utilities.assert_equals(
1710 expect=True,
1711 actual=rolesResults,
1712 onpass="No error in reading roles output",
1713 onfail="Error in reading roles from ONOS" )
1714
1715 main.step( "Check for consistency in roles from each controller" )
1716 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001717 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001718 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001719 else:
Jon Hall65844a32015-03-09 19:09:37 -07001720 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001721 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001722 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001723 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001724 onpass="Switch roles are consistent across all ONOS nodes",
1725 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001726
Jon Hall65844a32015-03-09 19:09:37 -07001727 if rolesResults and not consistentMastership:
1728 for i in range( numControllers ):
1729 main.log.warn(
1730 "ONOS" + str( i + 1 ) + " roles: ",
1731 json.dumps(
1732 json.loads( ONOSMastership[ i ] ),
1733 sort_keys=True,
1734 indent=4,
1735 separators=( ',', ': ' ) ) )
1736 elif rolesResults and not consistentMastership:
1737 mastershipCheck = main.TRUE
1738
Jon Hallb1290e82014-11-18 16:17:48 -05001739 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001740 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001741 try:
1742 currentJson = json.loads( ONOSMastership[0] )
1743 oldJson = json.loads( mastershipState )
1744 except ( ValueError, TypeError ):
1745 main.log.exception( "Something is wrong with parsing " +
1746 "ONOSMastership[0] or mastershipState" )
1747 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1748 main.log.error( "mastershipState" + repr( mastershipState ) )
1749 main.cleanup()
1750 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001751 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001752 for i in range( 1, 29 ):
1753 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001754 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001755 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001756 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001757 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001758 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001759 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001760 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001761 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001763 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001764 utilities.assert_equals(
1765 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001766 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001767 onpass="Mastership of Switches was not changed",
1768 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001769 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001770
Jon Hall6aec96b2015-01-19 14:49:31 -08001771 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001772 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001773 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001774 consistentIntents = True
1775 intentsResults = True
1776 threads = []
1777 for i in range( numControllers ):
1778 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001779 name="intents-" + str( i ),
1780 args=[],
1781 kwargs={ 'jsonFormat': True } )
1782 threads.append( t )
1783 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001784
1785 for t in threads:
1786 t.join()
1787 ONOSIntents.append( t.result )
1788
1789 for i in range( numControllers ):
1790 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001791 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001792 " intents" )
1793 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1794 repr( ONOSIntents[ i ] ) )
1795 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001796 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001797 expect=True,
1798 actual=intentsResults,
1799 onpass="No error in reading intents output",
1800 onfail="Error in reading intents from ONOS" )
1801
1802 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001803 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001804 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001805 "nodes" )
1806 else:
1807 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001808
1809 # Try to make it easy to figure out what is happening
1810 #
1811 # Intent ONOS1 ONOS2 ...
1812 # 0x01 INSTALLED INSTALLING
1813 # ... ... ...
1814 # ... ... ...
1815 title = " ID"
1816 for n in range( numControllers ):
1817 title += " " * 10 + "ONOS" + str( n + 1 )
1818 main.log.warn( title )
1819 # get all intent keys in the cluster
1820 keys = []
1821 for nodeStr in ONOSIntents:
1822 node = json.loads( nodeStr )
1823 for intent in node:
1824 keys.append( intent.get( 'id' ) )
1825 keys = set( keys )
1826 for key in keys:
1827 row = "%-13s" % key
1828 for nodeStr in ONOSIntents:
1829 node = json.loads( nodeStr )
1830 for intent in node:
1831 if intent.get( 'id' ) == key:
1832 row += "%-15s" % intent.get( 'state' )
1833 main.log.warn( row )
1834 # End table view
1835
Jon Hall65844a32015-03-09 19:09:37 -07001836 utilities.assert_equals(
1837 expect=True,
1838 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001839 onpass="Intents are consistent across all ONOS nodes",
1840 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001841 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001842 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001843 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001844 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001845 try:
1846 for intent in json.loads( node ):
1847 nodeStates.append( intent[ 'state' ] )
1848 except ( ValueError, TypeError ):
1849 main.log.exception( "Error in parsing intents" )
1850 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001851 intentStates.append( nodeStates )
1852 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1853 main.log.info( dict( out ) )
1854
Jon Hall65844a32015-03-09 19:09:37 -07001855 if intentsResults and not consistentIntents:
1856 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001857 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1858 main.log.warn( json.dumps(
1859 json.loads( ONOSIntents[ i ] ),
1860 sort_keys=True,
1861 indent=4,
1862 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001863 elif intentsResults and consistentIntents:
1864 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001865
Jon Hall58c76b72015-02-23 11:09:24 -08001866 # NOTE: Store has no durability, so intents are lost across system
1867 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001868 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001869 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001870 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001871 sameIntents = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001872 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001873 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001874 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001875 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001876 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001877 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1878 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001879 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001880 before = json.loads( intentState )
1881 after = json.loads( ONOSIntents[ 0 ] )
1882 for intent in before:
1883 if intent not in after:
1884 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001885 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001886 "(at least in the same form):" )
1887 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001888 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001889 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001890 main.log.debug( repr( ONOSIntents[0] ) )
1891 main.log.debug( repr( intentState ) )
1892 if sameIntents == main.FALSE:
1893 try:
1894 main.log.debug( "ONOS intents before: " )
1895 main.log.debug( json.dumps( json.loads( intentState ),
1896 sort_keys=True, indent=4,
1897 separators=( ',', ': ' ) ) )
1898 main.log.debug( "Current ONOS intents: " )
1899 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1900 sort_keys=True, indent=4,
1901 separators=( ',', ': ' ) ) )
1902 except ( ValueError, TypeError ):
1903 main.log.exception( "Exception printing intents" )
1904 main.log.debug( repr( ONOSIntents[0] ) )
1905 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001906 utilities.assert_equals(
1907 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001908 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001909 onpass="Intents are consistent with before failure",
1910 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001911 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001912
Jon Hall6aec96b2015-01-19 14:49:31 -08001913 main.step( "Get the OF Table entries and compare to before " +
1914 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001915 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001916 flows2 = []
1917 for i in range( 28 ):
1918 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001919 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1920 flows2.append( tmpFlows )
1921 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001922 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001923 flow2=tmpFlows )
1924 FlowTables = FlowTables and tempResult
1925 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001926 main.log.info( "Differences in flow table for switch: s" +
1927 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001928 utilities.assert_equals(
1929 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001930 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001931 onpass="No changes were found in the flow tables",
1932 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001933
Jon Hall6aec96b2015-01-19 14:49:31 -08001934 main.step( "Check the continuous pings to ensure that no packets " +
1935 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001936 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1937 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001938 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1940 for i in range( 8, 18 ):
1941 main.log.info(
1942 "Checking for a loss in pings along flow from s" +
1943 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001944 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001945 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001946 str( i ) ) or LossInPings
1947 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001949 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001950 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001951 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001952 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001953 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001954 utilities.assert_equals(
1955 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001956 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001957 onpass="No Loss of connectivity",
1958 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001959
Jon Hall390696c2015-05-05 17:13:41 -07001960 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001961 # Test of LeadershipElection
1962 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001963 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001964 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001965 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001966 for cli in CLIs:
1967 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001969 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001970 # all is well
1971 # NOTE: In failure scenario, this could be a new node, maybe
1972 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001973 pass
1974 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001975 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001976 main.log.error( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001977 "electionTestLeader function, check the" +
1978 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001979 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001980 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001981 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001982 main.log.error( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001983 " as the leader of the election app. " +
1984 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001985 utilities.assert_equals(
1986 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001987 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001988 onpass="Leadership election passed",
1989 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001990
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 def CASE8( self, main ):
1992 """
Jon Hallb1290e82014-11-18 16:17:48 -05001993 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001994 """
Jon Hallb87f3db2015-07-06 03:10:27 -07001995 import sys
1996 # FIXME add this path to params
1997 sys.path.append( "/home/admin/sts" )
1998 # assumes that sts is already in you PYTHONPATH
1999 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05002000 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08002001 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002002 assert numControllers, "numControllers not defined"
2003 assert main, "main not defined"
2004 assert utilities.assert_equals, "utilities.assert_equals not defined"
2005 assert CLIs, "CLIs not defined"
2006 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002007
Jon Hallfeff3082015-05-19 10:23:26 -07002008 main.case( "Compare ONOS Topology view to Mininet topology" )
2009 main.caseExplaination = "Compare topology objects between Mininet" +\
2010 " and ONOS"
Jon Hallb1290e82014-11-18 16:17:48 -05002011
Jon Hallfeff3082015-05-19 10:23:26 -07002012 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002013 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002015 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002016 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002017 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002018 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002019 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002020 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002021 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002022 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002023 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07002024 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002025 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002026 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07002027 threads = []
2028 for i in range( numControllers ):
2029 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07002030 name="devices-" + str( i ),
2031 args=[ ] )
2032 threads.append( t )
2033 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002034
2035 for t in threads:
2036 t.join()
2037 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002038 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002039 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07002040 threads = []
2041 for i in range( numControllers ):
2042 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07002043 name="hosts-" + str( i ),
2044 args=[ ] )
2045 threads.append( t )
2046 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002047
2048 for t in threads:
2049 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002050 try:
2051 hosts.append( json.loads( t.result ) )
2052 except ( ValueError, TypeError ):
2053 main.log.exception( "Error parsing hosts results" )
2054 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002055 for controller in range( 0, len( hosts ) ):
2056 controllerStr = str( controller + 1 )
2057 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002058 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002059 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002060 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002061 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002062 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002063 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07002064 threads = []
2065 for i in range( numControllers ):
2066 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07002067 name="ports-" + str( i ),
2068 args=[ ] )
2069 threads.append( t )
2070 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002071
2072 for t in threads:
2073 t.join()
2074 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002075 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002076 threads = []
2077 for i in range( numControllers ):
2078 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002079 name="links-" + str( i ),
2080 args=[ ] )
2081 threads.append( t )
2082 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002083
2084 for t in threads:
2085 t.join()
2086 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002087 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002088 threads = []
2089 for i in range( numControllers ):
2090 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002091 name="clusters-" + str( i ),
2092 args=[ ] )
2093 threads.append( t )
2094 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002095
2096 for t in threads:
2097 t.join()
2098 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002099
Jon Hall8f89dda2015-01-22 16:03:33 -08002100 elapsed = time.time() - startTime
2101 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002102 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002103 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002104
Jon Hallafa8a472015-06-12 14:02:42 -07002105 mnSwitches = main.Mininet1.getSwitches()
2106 mnLinks = main.Mininet1.getLinks()
2107 mnHosts = main.Mininet1.getHosts()
Jon Hall21270ac2015-02-16 17:59:55 -08002108 for controller in range( numControllers ):
2109 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07002110 if devices[ controller ] and ports[ controller ] and\
2111 "Error" not in devices[ controller ] and\
2112 "Error" not in ports[ controller ]:
2113
Jon Hall21270ac2015-02-16 17:59:55 -08002114 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07002115 mnSwitches,
2116 json.loads( devices[ controller ] ),
2117 json.loads( ports[ 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 Hallafa8a472015-06-12 14:02:42 -07002127 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall21270ac2015-02-16 17:59:55 -08002128 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07002129 mnSwitches, mnLinks,
2130 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002131 else:
2132 currentLinksResult = main.FALSE
2133 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002134 actual=currentLinksResult,
2135 onpass="ONOS" + controllerStr +
2136 " links view is correct",
2137 onfail="ONOS" + controllerStr +
2138 " links view is incorrect" )
2139
2140 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2141 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07002142 mnHosts,
2143 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002144 else:
2145 currentHostsResult = main.FALSE
2146 utilities.assert_equals( expect=main.TRUE,
2147 actual=currentHostsResult,
2148 onpass="ONOS" + controllerStr +
2149 " hosts exist in Mininet",
2150 onfail="ONOS" + controllerStr +
2151 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002152 # CHECKING HOST ATTACHMENT POINTS
2153 hostAttachment = True
Jon Hallafa8a472015-06-12 14:02:42 -07002154 zeroHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002155 # FIXME: topo-HA/obelisk specific mappings:
2156 # key is mac and value is dpid
2157 mappings = {}
2158 for i in range( 1, 29 ): # hosts 1 through 28
2159 # set up correct variables:
2160 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2161 if i == 1:
2162 deviceId = "1000".zfill(16)
2163 elif i == 2:
2164 deviceId = "2000".zfill(16)
2165 elif i == 3:
2166 deviceId = "3000".zfill(16)
2167 elif i == 4:
2168 deviceId = "3004".zfill(16)
2169 elif i == 5:
2170 deviceId = "5000".zfill(16)
2171 elif i == 6:
2172 deviceId = "6000".zfill(16)
2173 elif i == 7:
2174 deviceId = "6007".zfill(16)
2175 elif i >= 8 and i <= 17:
2176 dpid = '3' + str( i ).zfill( 3 )
2177 deviceId = dpid.zfill(16)
2178 elif i >= 18 and i <= 27:
2179 dpid = '6' + str( i ).zfill( 3 )
2180 deviceId = dpid.zfill(16)
2181 elif i == 28:
2182 deviceId = "2800".zfill(16)
2183 mappings[ macId ] = deviceId
2184 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2185 if hosts[ controller ] == []:
2186 main.log.warn( "There are no hosts discovered" )
Jon Hallafa8a472015-06-12 14:02:42 -07002187 zeroHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002188 else:
2189 for host in hosts[ controller ]:
2190 mac = None
2191 location = None
2192 device = None
2193 port = None
2194 try:
2195 mac = host.get( 'mac' )
2196 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002197
Jon Hallc9eabec2015-06-10 14:33:14 -07002198 location = host.get( 'location' )
2199 assert location, "location field could not be found for this host object"
2200
2201 # Trim the protocol identifier off deviceId
2202 device = str( location.get( 'elementId' ) ).split(':')[1]
2203 assert device, "elementId field could not be found for this host location object"
2204
2205 port = location.get( 'port' )
2206 assert port, "port field could not be found for this host location object"
2207
2208 # Now check if this matches where they should be
2209 if mac and device and port:
2210 if str( port ) != "1":
2211 main.log.error( "The attachment port is incorrect for " +
2212 "host " + str( mac ) +
2213 ". Expected: 1 Actual: " + str( port) )
2214 hostAttachment = False
2215 if device != mappings[ str( mac ) ]:
2216 main.log.error( "The attachment device is incorrect for " +
2217 "host " + str( mac ) +
2218 ". Expected: " + mappings[ str( mac ) ] +
2219 " Actual: " + device )
2220 hostAttachment = False
2221 else:
2222 hostAttachment = False
2223 except AssertionError:
2224 main.log.exception( "Json object not as expected" )
2225 main.log.error( repr( host ) )
2226 hostAttachment = False
2227 else:
2228 main.log.error( "No hosts json output or \"Error\"" +
2229 " in output. hosts = " +
2230 repr( hosts[ controller ] ) )
Jon Hallafa8a472015-06-12 14:02:42 -07002231 if zeroHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002232 hostAttachment = True
2233
2234 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002235 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002236 linksResults = linksResults and currentLinksResult
2237 hostsResults = hostsResults and currentHostsResult
Jon Hallafa8a472015-06-12 14:02:42 -07002238 hostAttachmentResults = hostAttachmentResults and\
2239 hostAttachment
2240 topoResult = ( devicesResults and linksResults
2241 and hostsResults and ipResult and
2242 hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002243
Jon Hallc9eabec2015-06-10 14:33:14 -07002244 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002245
Jon Hallc9eabec2015-06-10 14:33:14 -07002246 # hosts
2247 main.step( "Hosts view is consistent across all ONOS nodes" )
2248 consistentHostsResult = main.TRUE
2249 for controller in range( len( hosts ) ):
2250 controllerStr = str( controller + 1 )
2251 if "Error" not in hosts[ controller ]:
2252 if hosts[ controller ] == hosts[ 0 ]:
2253 continue
2254 else: # hosts not consistent
2255 main.log.error( "hosts from ONOS" + controllerStr +
2256 " is inconsistent with ONOS1" )
2257 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002258 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002259
Jon Hallc9eabec2015-06-10 14:33:14 -07002260 else:
2261 main.log.error( "Error in getting ONOS hosts from ONOS" +
2262 controllerStr )
2263 consistentHostsResult = main.FALSE
2264 main.log.warn( "ONOS" + controllerStr +
2265 " hosts response: " +
2266 repr( hosts[ controller ] ) )
2267 utilities.assert_equals(
2268 expect=main.TRUE,
2269 actual=consistentHostsResult,
2270 onpass="Hosts view is consistent across all ONOS nodes",
2271 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002272
Jon Hallc9eabec2015-06-10 14:33:14 -07002273 main.step( "Hosts information is correct" )
2274 hostsResults = hostsResults and ipResult
2275 utilities.assert_equals(
2276 expect=main.TRUE,
2277 actual=hostsResults,
2278 onpass="Host information is correct",
2279 onfail="Host information is incorrect" )
2280
2281 main.step( "Host attachment points to the network" )
2282 utilities.assert_equals(
2283 expect=True,
2284 actual=hostAttachmentResults,
2285 onpass="Hosts are correctly attached to the network",
2286 onfail="ONOS did not correctly attach hosts to the network" )
2287
2288 # Strongly connected clusters of devices
2289 main.step( "Clusters view is consistent across all ONOS nodes" )
2290 consistentClustersResult = main.TRUE
2291 for controller in range( len( clusters ) ):
2292 controllerStr = str( controller + 1 )
2293 if "Error" not in clusters[ controller ]:
2294 if clusters[ controller ] == clusters[ 0 ]:
2295 continue
2296 else: # clusters not consistent
2297 main.log.error( "clusters from ONOS" +
2298 controllerStr +
2299 " is inconsistent with ONOS1" )
Jon Hall21270ac2015-02-16 17:59:55 -08002300 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002301
Jon Hallc9eabec2015-06-10 14:33:14 -07002302 else:
2303 main.log.error( "Error in getting dataplane clusters " +
2304 "from ONOS" + controllerStr )
2305 consistentClustersResult = main.FALSE
2306 main.log.warn( "ONOS" + controllerStr +
2307 " clusters response: " +
2308 repr( clusters[ controller ] ) )
2309 utilities.assert_equals(
2310 expect=main.TRUE,
2311 actual=consistentClustersResult,
2312 onpass="Clusters view is consistent across all ONOS nodes",
2313 onfail="ONOS nodes have different views of clusters" )
2314
2315 main.step( "There is only one SCC" )
2316 # there should always only be one cluster
2317 try:
2318 numClusters = len( json.loads( clusters[ 0 ] ) )
2319 except ( ValueError, TypeError ):
2320 main.log.exception( "Error parsing clusters[0]: " +
2321 repr( clusters[0] ) )
2322 clusterResults = main.FALSE
2323 if numClusters == 1:
2324 clusterResults = main.TRUE
2325 utilities.assert_equals(
2326 expect=1,
2327 actual=numClusters,
2328 onpass="ONOS shows 1 SCC",
2329 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2330
Jon Hallafa8a472015-06-12 14:02:42 -07002331 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002332 and hostsResults and consistentHostsResult
2333 and consistentClustersResult and clusterResults
2334 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002335
Jon Hall21270ac2015-02-16 17:59:55 -08002336 topoResult = topoResult and int( count <= 2 )
2337 note = "note it takes about " + str( int( cliTime ) ) + \
2338 " seconds for the test to make all the cli calls to fetch " +\
2339 "the topology from each ONOS instance"
2340 main.log.info(
2341 "Very crass estimate for topology discovery/convergence( " +
2342 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2343 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002344
2345 main.step( "Device information is correct" )
2346 utilities.assert_equals(
2347 expect=main.TRUE,
2348 actual=devicesResults,
2349 onpass="Device information is correct",
2350 onfail="Device information is incorrect" )
2351
Jon Hallc9eabec2015-06-10 14:33:14 -07002352 main.step( "Links are correct" )
2353 utilities.assert_equals(
2354 expect=main.TRUE,
2355 actual=linksResults,
2356 onpass="Link are correct",
2357 onfail="Links are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002358
Jon Hallafa8a472015-06-12 14:02:42 -07002359 main.step( "Hosts are correct" )
2360 utilities.assert_equals(
2361 expect=main.TRUE,
2362 actual=hostsResults,
2363 onpass="Hosts are correct",
2364 onfail="Hosts are incorrect" )
2365
Jon Halla9d26da2015-03-30 16:45:32 -07002366 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002367 main.step( "Checking ONOS nodes" )
2368 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002369 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002370 threads = []
2371 for i in range( numControllers ):
2372 t = main.Thread( target=CLIs[i].nodes,
2373 name="nodes-" + str( i ),
2374 args=[ ] )
2375 threads.append( t )
2376 t.start()
2377
2378 for t in threads:
2379 t.join()
2380 nodesOutput.append( t.result )
2381 ips = [ node.ip_address for node in nodes ]
2382 for i in nodesOutput:
2383 try:
2384 current = json.loads( i )
2385 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002386 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002387 if node['ip'] in ips: # node in nodes() output is in cell
2388 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002389 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002390 else:
2391 main.log.error( "Error in ONOS node availability" )
2392 main.log.error(
2393 json.dumps( current,
2394 sort_keys=True,
2395 indent=4,
2396 separators=( ',', ': ' ) ) )
2397 break
Jon Hall390696c2015-05-05 17:13:41 -07002398 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002399 except ( ValueError, TypeError ):
2400 main.log.error( "Error parsing nodes output" )
2401 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002402 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2403 onpass="Nodes check successful",
2404 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002405
Jon Hall6aec96b2015-01-19 14:49:31 -08002406 def CASE9( self, main ):
2407 """
Jon Hallb1290e82014-11-18 16:17:48 -05002408 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002409 """
2410 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002411 assert numControllers, "numControllers not defined"
2412 assert main, "main not defined"
2413 assert utilities.assert_equals, "utilities.assert_equals not defined"
2414 assert CLIs, "CLIs not defined"
2415 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002416 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002417
Jon Hall8f89dda2015-01-22 16:03:33 -08002418 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002419
Jon Hall6aec96b2015-01-19 14:49:31 -08002420 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002421 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002422 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002423
Jon Hall6aec96b2015-01-19 14:49:31 -08002424 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002425 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002426 main.log.info( "Waiting " + str( linkSleep ) +
2427 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002428 time.sleep( linkSleep )
2429 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002430 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002431 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002432 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002433
Jon Hall6aec96b2015-01-19 14:49:31 -08002434 def CASE10( self, main ):
2435 """
Jon Hallb1290e82014-11-18 16:17:48 -05002436 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002437 """
2438 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002439 assert numControllers, "numControllers not defined"
2440 assert main, "main not defined"
2441 assert utilities.assert_equals, "utilities.assert_equals not defined"
2442 assert CLIs, "CLIs not defined"
2443 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002444 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002445
Jon Hall8f89dda2015-01-22 16:03:33 -08002446 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002447
Jon Hall6aec96b2015-01-19 14:49:31 -08002448 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002449 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002450 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002451
Jon Hall6aec96b2015-01-19 14:49:31 -08002452 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002453 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002454 main.log.info( "Waiting " + str( linkSleep ) +
2455 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002456 time.sleep( linkSleep )
2457 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002458 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002459 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002460 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002461
Jon Hall6aec96b2015-01-19 14:49:31 -08002462 def CASE11( self, main ):
2463 """
Jon Hallb1290e82014-11-18 16:17:48 -05002464 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002465 """
2466 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002467 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002468 assert numControllers, "numControllers not defined"
2469 assert main, "main not defined"
2470 assert utilities.assert_equals, "utilities.assert_equals not defined"
2471 assert CLIs, "CLIs not defined"
2472 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002473
Jon Hall8f89dda2015-01-22 16:03:33 -08002474 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002475
2476 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002477 main.case( description )
2478 switch = main.params[ 'kill' ][ 'switch' ]
2479 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002480
Jon Hall6aec96b2015-01-19 14:49:31 -08002481 # TODO: Make this switch parameterizable
2482 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002483 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002484 main.Mininet1.delSwitch( switch )
2485 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002486 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002487 time.sleep( switchSleep )
2488 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002489 # Peek at the deleted switch
2490 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002491 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002492 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002493 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002494 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002495 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002496 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002497
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 def CASE12( self, main ):
2499 """
Jon Hallb1290e82014-11-18 16:17:48 -05002500 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002501 """
2502 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002503 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002504 assert numControllers, "numControllers not defined"
2505 assert main, "main not defined"
2506 assert utilities.assert_equals, "utilities.assert_equals not defined"
2507 assert CLIs, "CLIs not defined"
2508 assert nodes, "nodes not defined"
2509 assert ONOS1Port, "ONOS1Port not defined"
2510 assert ONOS2Port, "ONOS2Port not defined"
2511 assert ONOS3Port, "ONOS3Port not defined"
2512 assert ONOS4Port, "ONOS4Port not defined"
2513 assert ONOS5Port, "ONOS5Port not defined"
2514 assert ONOS6Port, "ONOS6Port not defined"
2515 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002516
Jon Hall8f89dda2015-01-22 16:03:33 -08002517 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002518 switch = main.params[ 'kill' ][ 'switch' ]
2519 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2520 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002521 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002522 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002523
Jon Hall6aec96b2015-01-19 14:49:31 -08002524 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002525 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002526 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002527 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002528 ipList = []
2529 for i in range( numControllers ):
2530 ipList.append( nodes[ i ].ip_address )
2531 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002532 main.log.info( "Waiting " + str( switchSleep ) +
2533 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002534 time.sleep( switchSleep )
2535 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002536 # Peek at the deleted switch
2537 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002538 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002539 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002540 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002541 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002542 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002543 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002544
Jon Hall6aec96b2015-01-19 14:49:31 -08002545 def CASE13( self, main ):
2546 """
Jon Hallb1290e82014-11-18 16:17:48 -05002547 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002548 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002549 import os
2550 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002551 assert numControllers, "numControllers not defined"
2552 assert main, "main not defined"
2553 assert utilities.assert_equals, "utilities.assert_equals not defined"
2554 assert CLIs, "CLIs not defined"
2555 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002556
2557 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002558 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2559 'blue': '\033[94m', 'green': '\033[92m',
2560 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002561 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002562 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002563 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002564
Jon Hall6aec96b2015-01-19 14:49:31 -08002565 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002566 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002567 teststationUser = main.params[ 'TESTONUSER' ]
2568 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002569 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002570 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002571 # FIXME: scp
2572 # mn files
2573 # TODO: Load these from params
2574 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002575 logFolder = "/opt/onos/log/"
2576 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002577 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002578 dstDir = "~/packet_captures/"
2579 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002580 for node in nodes:
2581 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2582 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002583 teststationUser + "@" +
2584 teststationIP + ":" +
2585 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002586 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002587 main.ONOSbench.handle.expect( "\$" )
2588
Jon Hall6aec96b2015-01-19 14:49:31 -08002589 # std*.log's
2590 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002591 logFolder = "/opt/onos/var/"
2592 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002594 dstDir = "~/packet_captures/"
2595 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002596 for node in nodes:
2597 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2598 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002599 teststationUser + "@" +
2600 teststationIP + ":" +
2601 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002602 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002603 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002604 # sleep so scp can finish
2605 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002606
2607 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002608 mnResult = main.Mininet1.stopNet()
2609 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2610 onpass="Mininet stopped",
2611 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002612
2613 main.step( "Checking ONOS Logs for errors" )
2614 for node in nodes:
2615 print colors[ 'purple' ] + "Checking logs for errors on " + \
2616 node.name + ":" + colors[ 'end' ]
2617 print main.ONOSbench.checkLogs( node.ip_address )
2618
Jon Hall6aec96b2015-01-19 14:49:31 -08002619 main.step( "Packing and rotating pcap archives" )
2620 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002621
Jon Hall390696c2015-05-05 17:13:41 -07002622 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002623 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002624 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002625 labels = "Gossip Intents"
2626 data = str( gossipTime )
2627 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002628 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002629 except NameError, e:
2630 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002631
Jon Hall6aec96b2015-01-19 14:49:31 -08002632 def CASE14( self, main ):
2633 """
Jon Hall94fd0472014-12-08 11:52:42 -08002634 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002635 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002636 assert numControllers, "numControllers not defined"
2637 assert main, "main not defined"
2638 assert utilities.assert_equals, "utilities.assert_equals not defined"
2639 assert CLIs, "CLIs not defined"
2640 assert nodes, "nodes not defined"
2641
Jon Hall390696c2015-05-05 17:13:41 -07002642 main.case("Start Leadership Election app")
2643 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002644 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2645 utilities.assert_equals(
2646 expect=main.TRUE,
2647 actual=appResult,
2648 onpass="Election app installed",
2649 onfail="Something went wrong with installing Leadership election" )
2650
2651 main.step( "Run for election on each node" )
2652 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002653 leaders = []
2654 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002655 cli.electionTestRun()
2656 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002657 leader = cli.electionTestLeader()
2658 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002659 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002660 "should be an ONOS node, instead got '" +
2661 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002662 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002663 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002664 utilities.assert_equals(
2665 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002666 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002667 onpass="Successfully ran for leadership",
2668 onfail="Failed to run for leadership" )
2669
2670 main.step( "Check that each node shows the same leader" )
2671 sameLeader = main.TRUE
2672 if len( set( leaders ) ) != 1:
2673 sameLeader = main.FALSE
2674 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2675 str( leaders ) )
2676 utilities.assert_equals(
2677 expect=main.TRUE,
2678 actual=sameLeader,
2679 onpass="Leadership is consistent for the election topic",
2680 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002681
Jon Hall6aec96b2015-01-19 14:49:31 -08002682 def CASE15( self, main ):
2683 """
Jon Hall669173b2014-12-17 11:36:30 -08002684 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002685 """
Jon Hall390696c2015-05-05 17:13:41 -07002686 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002687 assert numControllers, "numControllers not defined"
2688 assert main, "main not defined"
2689 assert utilities.assert_equals, "utilities.assert_equals not defined"
2690 assert CLIs, "CLIs not defined"
2691 assert nodes, "nodes not defined"
2692
Jon Hall8f89dda2015-01-22 16:03:33 -08002693 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002694 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002695 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002696
2697 main.step( "Check that each node shows the same leader" )
2698 sameLeader = main.TRUE
2699 leaders = []
2700 for cli in CLIs:
2701 leader = cli.electionTestLeader()
2702 leaders.append( leader )
2703 if len( set( leaders ) ) != 1:
2704 sameLeader = main.FALSE
2705 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2706 str( leaders ) )
2707 utilities.assert_equals(
2708 expect=main.TRUE,
2709 actual=sameLeader,
2710 onpass="Leadership is consistent for the election topic",
2711 onfail="Nodes have different leaders" )
2712
Jon Hall6aec96b2015-01-19 14:49:31 -08002713 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002714 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002715 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002716 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002717 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002718 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002719 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002720 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002721 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002722 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002723 for i in range( len( CLIs ) ):
2724 if leader == nodes[ i ].ip_address:
2725 oldLeader = CLIs[ i ]
2726 break
Jon Halla9d26da2015-03-30 16:45:32 -07002727 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002728 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002729 if oldLeader:
2730 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002731 utilities.assert_equals(
2732 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002733 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002734 onpass="Node was withdrawn from election",
2735 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002736
Jon Hall6aec96b2015-01-19 14:49:31 -08002737 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002738 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002739 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002740 for cli in CLIs:
2741 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002742 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002743 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002744 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002745 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002746 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002747 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002748 # error in response
2749 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002750 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002751 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002752 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002753 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002754 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002755 elif leaderN is None:
2756 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002757 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002758 leaderN = cli.electionTestLeader()
2759 leaderList.pop()
2760 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002761 consistentLeader = main.FALSE
2762 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002763 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002764 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002765 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002766 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002767 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002768 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002769 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002770 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002771 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002772 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002773 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002774 utilities.assert_equals(
2775 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002776 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002777 onpass="Leadership election passed",
2778 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002779
Jon Hall58c76b72015-02-23 11:09:24 -08002780 main.step( "Run for election on old leader( just so everyone " +
2781 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002782 if oldLeader:
2783 runResult = oldLeader.electionTestRun()
2784 else:
2785 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002786 utilities.assert_equals(
2787 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002788 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002789 onpass="App re-ran for election",
2790 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002791
Jon Hallfeff3082015-05-19 10:23:26 -07002792 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002793 afterRun = main.ONOScli1.electionTestLeader()
2794 # verify leader didn't just change
2795 if afterRun == leaderList[ 0 ]:
2796 afterResult = main.TRUE
2797 else:
2798 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002799
Jon Hall6aec96b2015-01-19 14:49:31 -08002800 utilities.assert_equals(
2801 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002802 actual=afterResult,
2803 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002804 onfail="Something went wrong with Leadership election after " +
2805 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002806
Jon Hall390696c2015-05-05 17:13:41 -07002807 def CASE16( self, main ):
2808 """
2809 Install Distributed Primitives app
2810 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002811 import time
Jon Hall390696c2015-05-05 17:13:41 -07002812 assert numControllers, "numControllers not defined"
2813 assert main, "main not defined"
2814 assert utilities.assert_equals, "utilities.assert_equals not defined"
2815 assert CLIs, "CLIs not defined"
2816 assert nodes, "nodes not defined"
2817
2818 # Variables for the distributed primitives tests
2819 global pCounterName
2820 global iCounterName
2821 global pCounterValue
2822 global iCounterValue
2823 global onosSet
2824 global onosSetName
2825 pCounterName = "TestON-Partitions"
2826 iCounterName = "TestON-inMemory"
2827 pCounterValue = 0
2828 iCounterValue = 0
2829 onosSet = set([])
2830 onosSetName = "TestON-set"
2831
2832 description = "Install Primitives app"
2833 main.case( description )
2834 main.step( "Install Primitives app" )
2835 appName = "org.onosproject.distributedprimitives"
2836 appResults = CLIs[0].activateApp( appName )
2837 utilities.assert_equals( expect=main.TRUE,
2838 actual=appResults,
2839 onpass="Primitives app activated",
2840 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002841 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002842
2843 def CASE17( self, main ):
2844 """
2845 Check for basic functionality with distributed primitives
2846 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002847 import json
Jon Hall390696c2015-05-05 17:13:41 -07002848 # Make sure variables are defined/set
2849 assert numControllers, "numControllers not defined"
2850 assert main, "main not defined"
2851 assert utilities.assert_equals, "utilities.assert_equals not defined"
2852 assert CLIs, "CLIs not defined"
2853 assert nodes, "nodes not defined"
2854 assert pCounterName, "pCounterName not defined"
2855 assert iCounterName, "iCounterName not defined"
2856 assert onosSetName, "onosSetName not defined"
2857 # NOTE: assert fails if value is 0/None/Empty/False
2858 try:
2859 pCounterValue
2860 except NameError:
2861 main.log.error( "pCounterValue not defined, setting to 0" )
2862 pCounterValue = 0
2863 try:
2864 iCounterValue
2865 except NameError:
2866 main.log.error( "iCounterValue not defined, setting to 0" )
2867 iCounterValue = 0
2868 try:
2869 onosSet
2870 except NameError:
2871 main.log.error( "onosSet not defined, setting to empty Set" )
2872 onosSet = set([])
2873 # Variables for the distributed primitives tests. These are local only
2874 addValue = "a"
2875 addAllValue = "a b c d e f"
2876 retainValue = "c d e f"
2877
2878 description = "Check for basic functionality with distributed " +\
2879 "primitives"
2880 main.case( description )
2881 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2882 # DISTRIBUTED ATOMIC COUNTERS
2883 main.step( "Increment and get a default counter on each node" )
2884 pCounters = []
2885 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002886 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002887 for i in range( numControllers ):
2888 t = main.Thread( target=CLIs[i].counterTestIncrement,
2889 name="counterIncrement-" + str( i ),
2890 args=[ pCounterName ] )
2891 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002892 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002893 threads.append( t )
2894 t.start()
2895
2896 for t in threads:
2897 t.join()
2898 pCounters.append( t.result )
2899 # Check that counter incremented numController times
2900 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002901 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002902 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002903 pCounterResults = pCounterResults and tmpResult
2904 if not tmpResult:
2905 main.log.error( str( i ) + " is not in partitioned "
2906 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002907 utilities.assert_equals( expect=True,
2908 actual=pCounterResults,
2909 onpass="Default counter incremented",
2910 onfail="Error incrementing default" +
2911 " counter" )
2912
2913 main.step( "Increment and get an in memory counter on each node" )
2914 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002915 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002916 threads = []
2917 for i in range( numControllers ):
2918 t = main.Thread( target=CLIs[i].counterTestIncrement,
2919 name="icounterIncrement-" + str( i ),
2920 args=[ iCounterName ],
2921 kwargs={ "inMemory": True } )
2922 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002923 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002924 threads.append( t )
2925 t.start()
2926
2927 for t in threads:
2928 t.join()
2929 iCounters.append( t.result )
2930 # Check that counter incremented numController times
2931 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002932 for i in addedIValues:
2933 tmpResult = i in iCounters
2934 iCounterResults = iCounterResults and tmpResult
2935 if not tmpResult:
2936 main.log.error( str( i ) + " is not in the in-memory "
2937 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002938 utilities.assert_equals( expect=True,
2939 actual=iCounterResults,
2940 onpass="In memory counter incremented",
2941 onfail="Error incrementing in memory" +
2942 " counter" )
2943
2944 main.step( "Check counters are consistant across nodes" )
2945 onosCounters = []
2946 threads = []
2947 for i in range( numControllers ):
2948 t = main.Thread( target=CLIs[i].counters,
2949 name="counters-" + str( i ) )
2950 threads.append( t )
2951 t.start()
2952 for t in threads:
2953 t.join()
2954 onosCounters.append( t.result )
2955 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2956 if all( tmp ):
2957 main.log.info( "Counters are consistent across all nodes" )
2958 consistentCounterResults = main.TRUE
2959 else:
2960 main.log.error( "Counters are not consistent across all nodes" )
2961 consistentCounterResults = main.FALSE
2962 utilities.assert_equals( expect=main.TRUE,
2963 actual=consistentCounterResults,
2964 onpass="ONOS counters are consistent " +
2965 "across nodes",
2966 onfail="ONOS Counters are inconsistent " +
2967 "across nodes" )
2968
2969 main.step( "Counters we added have the correct values" )
2970 correctResults = main.TRUE
2971 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002972 current = json.loads( onosCounters[i] )
2973 pValue = None
2974 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002975 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002976 for database in current:
2977 partitioned = database.get( 'partitionedDatabaseCounters' )
2978 if partitioned:
2979 for value in partitioned:
2980 if value.get( 'name' ) == pCounterName:
2981 pValue = value.get( 'value' )
2982 break
2983 inMemory = database.get( 'inMemoryDatabaseCounters' )
2984 if inMemory:
2985 for value in inMemory:
2986 if value.get( 'name' ) == iCounterName:
2987 iValue = value.get( 'value' )
2988 break
Jon Hall390696c2015-05-05 17:13:41 -07002989 except AttributeError, e:
2990 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2991 "is not as expected" )
2992 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07002993 if pValue == pCounterValue:
2994 main.log.info( "Partitioned counter value is correct" )
2995 else:
2996 main.log.error( "Partitioned counter value is incorrect," +
2997 " expected value: " + str( pCounterValue )
2998 + " current value: " + str( pValue ) )
2999 correctResults = main.FALSE
3000 if iValue == iCounterValue:
3001 main.log.info( "In memory counter value is correct" )
3002 else:
3003 main.log.error( "In memory counter value is incorrect, " +
3004 "expected value: " + str( iCounterValue ) +
3005 " current value: " + str( iValue ) )
3006 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003007 utilities.assert_equals( expect=main.TRUE,
3008 actual=correctResults,
3009 onpass="Added counters are correct",
3010 onfail="Added counters are incorrect" )
3011 # DISTRIBUTED SETS
3012 main.step( "Distributed Set get" )
3013 size = len( onosSet )
3014 getResponses = []
3015 threads = []
3016 for i in range( numControllers ):
3017 t = main.Thread( target=CLIs[i].setTestGet,
3018 name="setTestGet-" + str( i ),
3019 args=[ onosSetName ] )
3020 threads.append( t )
3021 t.start()
3022 for t in threads:
3023 t.join()
3024 getResponses.append( t.result )
3025
3026 getResults = main.TRUE
3027 for i in range( numControllers ):
3028 if isinstance( getResponses[ i ], list):
3029 current = set( getResponses[ i ] )
3030 if len( current ) == len( getResponses[ i ] ):
3031 # no repeats
3032 if onosSet != current:
3033 main.log.error( "ONOS" + str( i + 1 ) +
3034 " has incorrect view" +
3035 " of set " + onosSetName + ":\n" +
3036 str( getResponses[ i ] ) )
3037 main.log.debug( "Expected: " + str( onosSet ) )
3038 main.log.debug( "Actual: " + str( current ) )
3039 getResults = main.FALSE
3040 else:
3041 # error, set is not a set
3042 main.log.error( "ONOS" + str( i + 1 ) +
3043 " has repeat elements in" +
3044 " set " + onosSetName + ":\n" +
3045 str( getResponses[ i ] ) )
3046 getResults = main.FALSE
3047 elif getResponses[ i ] == main.ERROR:
3048 getResults = main.FALSE
3049 utilities.assert_equals( expect=main.TRUE,
3050 actual=getResults,
3051 onpass="Set elements are correct",
3052 onfail="Set elements are incorrect" )
3053
3054 main.step( "Distributed Set size" )
3055 sizeResponses = []
3056 threads = []
3057 for i in range( numControllers ):
3058 t = main.Thread( target=CLIs[i].setTestSize,
3059 name="setTestSize-" + str( i ),
3060 args=[ onosSetName ] )
3061 threads.append( t )
3062 t.start()
3063 for t in threads:
3064 t.join()
3065 sizeResponses.append( t.result )
3066
3067 sizeResults = main.TRUE
3068 for i in range( numControllers ):
3069 if size != sizeResponses[ i ]:
3070 sizeResults = main.FALSE
3071 main.log.error( "ONOS" + str( i + 1 ) +
3072 " expected a size of " + str( size ) +
3073 " for set " + onosSetName +
3074 " but got " + str( sizeResponses[ i ] ) )
3075 utilities.assert_equals( expect=main.TRUE,
3076 actual=sizeResults,
3077 onpass="Set sizes are correct",
3078 onfail="Set sizes are incorrect" )
3079
3080 main.step( "Distributed Set add()" )
3081 onosSet.add( addValue )
3082 addResponses = []
3083 threads = []
3084 for i in range( numControllers ):
3085 t = main.Thread( target=CLIs[i].setTestAdd,
3086 name="setTestAdd-" + str( i ),
3087 args=[ onosSetName, addValue ] )
3088 threads.append( t )
3089 t.start()
3090 for t in threads:
3091 t.join()
3092 addResponses.append( t.result )
3093
3094 # main.TRUE = successfully changed the set
3095 # main.FALSE = action resulted in no change in set
3096 # main.ERROR - Some error in executing the function
3097 addResults = main.TRUE
3098 for i in range( numControllers ):
3099 if addResponses[ i ] == main.TRUE:
3100 # All is well
3101 pass
3102 elif addResponses[ i ] == main.FALSE:
3103 # Already in set, probably fine
3104 pass
3105 elif addResponses[ i ] == main.ERROR:
3106 # Error in execution
3107 addResults = main.FALSE
3108 else:
3109 # unexpected result
3110 addResults = main.FALSE
3111 if addResults != main.TRUE:
3112 main.log.error( "Error executing set add" )
3113
3114 # Check if set is still correct
3115 size = len( onosSet )
3116 getResponses = []
3117 threads = []
3118 for i in range( numControllers ):
3119 t = main.Thread( target=CLIs[i].setTestGet,
3120 name="setTestGet-" + str( i ),
3121 args=[ onosSetName ] )
3122 threads.append( t )
3123 t.start()
3124 for t in threads:
3125 t.join()
3126 getResponses.append( t.result )
3127 getResults = main.TRUE
3128 for i in range( numControllers ):
3129 if isinstance( getResponses[ i ], list):
3130 current = set( getResponses[ i ] )
3131 if len( current ) == len( getResponses[ i ] ):
3132 # no repeats
3133 if onosSet != current:
3134 main.log.error( "ONOS" + str( i + 1 ) +
3135 " has incorrect view" +
3136 " of set " + onosSetName + ":\n" +
3137 str( getResponses[ i ] ) )
3138 main.log.debug( "Expected: " + str( onosSet ) )
3139 main.log.debug( "Actual: " + str( current ) )
3140 getResults = main.FALSE
3141 else:
3142 # error, set is not a set
3143 main.log.error( "ONOS" + str( i + 1 ) +
3144 " has repeat elements in" +
3145 " set " + onosSetName + ":\n" +
3146 str( getResponses[ i ] ) )
3147 getResults = main.FALSE
3148 elif getResponses[ i ] == main.ERROR:
3149 getResults = main.FALSE
3150 sizeResponses = []
3151 threads = []
3152 for i in range( numControllers ):
3153 t = main.Thread( target=CLIs[i].setTestSize,
3154 name="setTestSize-" + str( i ),
3155 args=[ onosSetName ] )
3156 threads.append( t )
3157 t.start()
3158 for t in threads:
3159 t.join()
3160 sizeResponses.append( t.result )
3161 sizeResults = main.TRUE
3162 for i in range( numControllers ):
3163 if size != sizeResponses[ i ]:
3164 sizeResults = main.FALSE
3165 main.log.error( "ONOS" + str( i + 1 ) +
3166 " expected a size of " + str( size ) +
3167 " for set " + onosSetName +
3168 " but got " + str( sizeResponses[ i ] ) )
3169 addResults = addResults and getResults and sizeResults
3170 utilities.assert_equals( expect=main.TRUE,
3171 actual=addResults,
3172 onpass="Set add correct",
3173 onfail="Set add was incorrect" )
3174
3175 main.step( "Distributed Set addAll()" )
3176 onosSet.update( addAllValue.split() )
3177 addResponses = []
3178 threads = []
3179 for i in range( numControllers ):
3180 t = main.Thread( target=CLIs[i].setTestAdd,
3181 name="setTestAddAll-" + str( i ),
3182 args=[ onosSetName, addAllValue ] )
3183 threads.append( t )
3184 t.start()
3185 for t in threads:
3186 t.join()
3187 addResponses.append( t.result )
3188
3189 # main.TRUE = successfully changed the set
3190 # main.FALSE = action resulted in no change in set
3191 # main.ERROR - Some error in executing the function
3192 addAllResults = main.TRUE
3193 for i in range( numControllers ):
3194 if addResponses[ i ] == main.TRUE:
3195 # All is well
3196 pass
3197 elif addResponses[ i ] == main.FALSE:
3198 # Already in set, probably fine
3199 pass
3200 elif addResponses[ i ] == main.ERROR:
3201 # Error in execution
3202 addAllResults = main.FALSE
3203 else:
3204 # unexpected result
3205 addAllResults = main.FALSE
3206 if addAllResults != main.TRUE:
3207 main.log.error( "Error executing set addAll" )
3208
3209 # Check if set is still correct
3210 size = len( onosSet )
3211 getResponses = []
3212 threads = []
3213 for i in range( numControllers ):
3214 t = main.Thread( target=CLIs[i].setTestGet,
3215 name="setTestGet-" + str( i ),
3216 args=[ onosSetName ] )
3217 threads.append( t )
3218 t.start()
3219 for t in threads:
3220 t.join()
3221 getResponses.append( t.result )
3222 getResults = main.TRUE
3223 for i in range( numControllers ):
3224 if isinstance( getResponses[ i ], list):
3225 current = set( getResponses[ i ] )
3226 if len( current ) == len( getResponses[ i ] ):
3227 # no repeats
3228 if onosSet != current:
3229 main.log.error( "ONOS" + str( i + 1 ) +
3230 " has incorrect view" +
3231 " of set " + onosSetName + ":\n" +
3232 str( getResponses[ i ] ) )
3233 main.log.debug( "Expected: " + str( onosSet ) )
3234 main.log.debug( "Actual: " + str( current ) )
3235 getResults = main.FALSE
3236 else:
3237 # error, set is not a set
3238 main.log.error( "ONOS" + str( i + 1 ) +
3239 " has repeat elements in" +
3240 " set " + onosSetName + ":\n" +
3241 str( getResponses[ i ] ) )
3242 getResults = main.FALSE
3243 elif getResponses[ i ] == main.ERROR:
3244 getResults = main.FALSE
3245 sizeResponses = []
3246 threads = []
3247 for i in range( numControllers ):
3248 t = main.Thread( target=CLIs[i].setTestSize,
3249 name="setTestSize-" + str( i ),
3250 args=[ onosSetName ] )
3251 threads.append( t )
3252 t.start()
3253 for t in threads:
3254 t.join()
3255 sizeResponses.append( t.result )
3256 sizeResults = main.TRUE
3257 for i in range( numControllers ):
3258 if size != sizeResponses[ i ]:
3259 sizeResults = main.FALSE
3260 main.log.error( "ONOS" + str( i + 1 ) +
3261 " expected a size of " + str( size ) +
3262 " for set " + onosSetName +
3263 " but got " + str( sizeResponses[ i ] ) )
3264 addAllResults = addAllResults and getResults and sizeResults
3265 utilities.assert_equals( expect=main.TRUE,
3266 actual=addAllResults,
3267 onpass="Set addAll correct",
3268 onfail="Set addAll was incorrect" )
3269
3270 main.step( "Distributed Set contains()" )
3271 containsResponses = []
3272 threads = []
3273 for i in range( numControllers ):
3274 t = main.Thread( target=CLIs[i].setTestGet,
3275 name="setContains-" + str( i ),
3276 args=[ onosSetName ],
3277 kwargs={ "values": addValue } )
3278 threads.append( t )
3279 t.start()
3280 for t in threads:
3281 t.join()
3282 # NOTE: This is the tuple
3283 containsResponses.append( t.result )
3284
3285 containsResults = main.TRUE
3286 for i in range( numControllers ):
3287 if containsResponses[ i ] == main.ERROR:
3288 containsResults = main.FALSE
3289 else:
3290 containsResults = containsResults and\
3291 containsResponses[ i ][ 1 ]
3292 utilities.assert_equals( expect=main.TRUE,
3293 actual=containsResults,
3294 onpass="Set contains is functional",
3295 onfail="Set contains failed" )
3296
3297 main.step( "Distributed Set containsAll()" )
3298 containsAllResponses = []
3299 threads = []
3300 for i in range( numControllers ):
3301 t = main.Thread( target=CLIs[i].setTestGet,
3302 name="setContainsAll-" + str( i ),
3303 args=[ onosSetName ],
3304 kwargs={ "values": addAllValue } )
3305 threads.append( t )
3306 t.start()
3307 for t in threads:
3308 t.join()
3309 # NOTE: This is the tuple
3310 containsAllResponses.append( t.result )
3311
3312 containsAllResults = main.TRUE
3313 for i in range( numControllers ):
3314 if containsResponses[ i ] == main.ERROR:
3315 containsResults = main.FALSE
3316 else:
3317 containsResults = containsResults and\
3318 containsResponses[ i ][ 1 ]
3319 utilities.assert_equals( expect=main.TRUE,
3320 actual=containsAllResults,
3321 onpass="Set containsAll is functional",
3322 onfail="Set containsAll failed" )
3323
3324 main.step( "Distributed Set remove()" )
3325 onosSet.remove( addValue )
3326 removeResponses = []
3327 threads = []
3328 for i in range( numControllers ):
3329 t = main.Thread( target=CLIs[i].setTestRemove,
3330 name="setTestRemove-" + str( i ),
3331 args=[ onosSetName, addValue ] )
3332 threads.append( t )
3333 t.start()
3334 for t in threads:
3335 t.join()
3336 removeResponses.append( t.result )
3337
3338 # main.TRUE = successfully changed the set
3339 # main.FALSE = action resulted in no change in set
3340 # main.ERROR - Some error in executing the function
3341 removeResults = main.TRUE
3342 for i in range( numControllers ):
3343 if removeResponses[ i ] == main.TRUE:
3344 # All is well
3345 pass
3346 elif removeResponses[ i ] == main.FALSE:
3347 # not in set, probably fine
3348 pass
3349 elif removeResponses[ i ] == main.ERROR:
3350 # Error in execution
3351 removeResults = main.FALSE
3352 else:
3353 # unexpected result
3354 removeResults = main.FALSE
3355 if removeResults != main.TRUE:
3356 main.log.error( "Error executing set remove" )
3357
3358 # Check if set is still correct
3359 size = len( onosSet )
3360 getResponses = []
3361 threads = []
3362 for i in range( numControllers ):
3363 t = main.Thread( target=CLIs[i].setTestGet,
3364 name="setTestGet-" + str( i ),
3365 args=[ onosSetName ] )
3366 threads.append( t )
3367 t.start()
3368 for t in threads:
3369 t.join()
3370 getResponses.append( t.result )
3371 getResults = main.TRUE
3372 for i in range( numControllers ):
3373 if isinstance( getResponses[ i ], list):
3374 current = set( getResponses[ i ] )
3375 if len( current ) == len( getResponses[ i ] ):
3376 # no repeats
3377 if onosSet != current:
3378 main.log.error( "ONOS" + str( i + 1 ) +
3379 " has incorrect view" +
3380 " of set " + onosSetName + ":\n" +
3381 str( getResponses[ i ] ) )
3382 main.log.debug( "Expected: " + str( onosSet ) )
3383 main.log.debug( "Actual: " + str( current ) )
3384 getResults = main.FALSE
3385 else:
3386 # error, set is not a set
3387 main.log.error( "ONOS" + str( i + 1 ) +
3388 " has repeat elements in" +
3389 " set " + onosSetName + ":\n" +
3390 str( getResponses[ i ] ) )
3391 getResults = main.FALSE
3392 elif getResponses[ i ] == main.ERROR:
3393 getResults = main.FALSE
3394 sizeResponses = []
3395 threads = []
3396 for i in range( numControllers ):
3397 t = main.Thread( target=CLIs[i].setTestSize,
3398 name="setTestSize-" + str( i ),
3399 args=[ onosSetName ] )
3400 threads.append( t )
3401 t.start()
3402 for t in threads:
3403 t.join()
3404 sizeResponses.append( t.result )
3405 sizeResults = main.TRUE
3406 for i in range( numControllers ):
3407 if size != sizeResponses[ i ]:
3408 sizeResults = main.FALSE
3409 main.log.error( "ONOS" + str( i + 1 ) +
3410 " expected a size of " + str( size ) +
3411 " for set " + onosSetName +
3412 " but got " + str( sizeResponses[ i ] ) )
3413 removeResults = removeResults and getResults and sizeResults
3414 utilities.assert_equals( expect=main.TRUE,
3415 actual=removeResults,
3416 onpass="Set remove correct",
3417 onfail="Set remove was incorrect" )
3418
3419 main.step( "Distributed Set removeAll()" )
3420 onosSet.difference_update( addAllValue.split() )
3421 removeAllResponses = []
3422 threads = []
3423 try:
3424 for i in range( numControllers ):
3425 t = main.Thread( target=CLIs[i].setTestRemove,
3426 name="setTestRemoveAll-" + str( i ),
3427 args=[ onosSetName, addAllValue ] )
3428 threads.append( t )
3429 t.start()
3430 for t in threads:
3431 t.join()
3432 removeAllResponses.append( t.result )
3433 except Exception, e:
3434 main.log.exception(e)
3435
3436 # main.TRUE = successfully changed the set
3437 # main.FALSE = action resulted in no change in set
3438 # main.ERROR - Some error in executing the function
3439 removeAllResults = main.TRUE
3440 for i in range( numControllers ):
3441 if removeAllResponses[ i ] == main.TRUE:
3442 # All is well
3443 pass
3444 elif removeAllResponses[ i ] == main.FALSE:
3445 # not in set, probably fine
3446 pass
3447 elif removeAllResponses[ i ] == main.ERROR:
3448 # Error in execution
3449 removeAllResults = main.FALSE
3450 else:
3451 # unexpected result
3452 removeAllResults = main.FALSE
3453 if removeAllResults != main.TRUE:
3454 main.log.error( "Error executing set removeAll" )
3455
3456 # Check if set is still correct
3457 size = len( onosSet )
3458 getResponses = []
3459 threads = []
3460 for i in range( numControllers ):
3461 t = main.Thread( target=CLIs[i].setTestGet,
3462 name="setTestGet-" + str( i ),
3463 args=[ onosSetName ] )
3464 threads.append( t )
3465 t.start()
3466 for t in threads:
3467 t.join()
3468 getResponses.append( t.result )
3469 getResults = main.TRUE
3470 for i in range( numControllers ):
3471 if isinstance( getResponses[ i ], list):
3472 current = set( getResponses[ i ] )
3473 if len( current ) == len( getResponses[ i ] ):
3474 # no repeats
3475 if onosSet != current:
3476 main.log.error( "ONOS" + str( i + 1 ) +
3477 " has incorrect view" +
3478 " of set " + onosSetName + ":\n" +
3479 str( getResponses[ i ] ) )
3480 main.log.debug( "Expected: " + str( onosSet ) )
3481 main.log.debug( "Actual: " + str( current ) )
3482 getResults = main.FALSE
3483 else:
3484 # error, set is not a set
3485 main.log.error( "ONOS" + str( i + 1 ) +
3486 " has repeat elements in" +
3487 " set " + onosSetName + ":\n" +
3488 str( getResponses[ i ] ) )
3489 getResults = main.FALSE
3490 elif getResponses[ i ] == main.ERROR:
3491 getResults = main.FALSE
3492 sizeResponses = []
3493 threads = []
3494 for i in range( numControllers ):
3495 t = main.Thread( target=CLIs[i].setTestSize,
3496 name="setTestSize-" + str( i ),
3497 args=[ onosSetName ] )
3498 threads.append( t )
3499 t.start()
3500 for t in threads:
3501 t.join()
3502 sizeResponses.append( t.result )
3503 sizeResults = main.TRUE
3504 for i in range( numControllers ):
3505 if size != sizeResponses[ i ]:
3506 sizeResults = main.FALSE
3507 main.log.error( "ONOS" + str( i + 1 ) +
3508 " expected a size of " + str( size ) +
3509 " for set " + onosSetName +
3510 " but got " + str( sizeResponses[ i ] ) )
3511 removeAllResults = removeAllResults and getResults and sizeResults
3512 utilities.assert_equals( expect=main.TRUE,
3513 actual=removeAllResults,
3514 onpass="Set removeAll correct",
3515 onfail="Set removeAll was incorrect" )
3516
3517 main.step( "Distributed Set addAll()" )
3518 onosSet.update( addAllValue.split() )
3519 addResponses = []
3520 threads = []
3521 for i in range( numControllers ):
3522 t = main.Thread( target=CLIs[i].setTestAdd,
3523 name="setTestAddAll-" + str( i ),
3524 args=[ onosSetName, addAllValue ] )
3525 threads.append( t )
3526 t.start()
3527 for t in threads:
3528 t.join()
3529 addResponses.append( t.result )
3530
3531 # main.TRUE = successfully changed the set
3532 # main.FALSE = action resulted in no change in set
3533 # main.ERROR - Some error in executing the function
3534 addAllResults = main.TRUE
3535 for i in range( numControllers ):
3536 if addResponses[ i ] == main.TRUE:
3537 # All is well
3538 pass
3539 elif addResponses[ i ] == main.FALSE:
3540 # Already in set, probably fine
3541 pass
3542 elif addResponses[ i ] == main.ERROR:
3543 # Error in execution
3544 addAllResults = main.FALSE
3545 else:
3546 # unexpected result
3547 addAllResults = main.FALSE
3548 if addAllResults != main.TRUE:
3549 main.log.error( "Error executing set addAll" )
3550
3551 # Check if set is still correct
3552 size = len( onosSet )
3553 getResponses = []
3554 threads = []
3555 for i in range( numControllers ):
3556 t = main.Thread( target=CLIs[i].setTestGet,
3557 name="setTestGet-" + str( i ),
3558 args=[ onosSetName ] )
3559 threads.append( t )
3560 t.start()
3561 for t in threads:
3562 t.join()
3563 getResponses.append( t.result )
3564 getResults = main.TRUE
3565 for i in range( numControllers ):
3566 if isinstance( getResponses[ i ], list):
3567 current = set( getResponses[ i ] )
3568 if len( current ) == len( getResponses[ i ] ):
3569 # no repeats
3570 if onosSet != current:
3571 main.log.error( "ONOS" + str( i + 1 ) +
3572 " has incorrect view" +
3573 " of set " + onosSetName + ":\n" +
3574 str( getResponses[ i ] ) )
3575 main.log.debug( "Expected: " + str( onosSet ) )
3576 main.log.debug( "Actual: " + str( current ) )
3577 getResults = main.FALSE
3578 else:
3579 # error, set is not a set
3580 main.log.error( "ONOS" + str( i + 1 ) +
3581 " has repeat elements in" +
3582 " set " + onosSetName + ":\n" +
3583 str( getResponses[ i ] ) )
3584 getResults = main.FALSE
3585 elif getResponses[ i ] == main.ERROR:
3586 getResults = main.FALSE
3587 sizeResponses = []
3588 threads = []
3589 for i in range( numControllers ):
3590 t = main.Thread( target=CLIs[i].setTestSize,
3591 name="setTestSize-" + str( i ),
3592 args=[ onosSetName ] )
3593 threads.append( t )
3594 t.start()
3595 for t in threads:
3596 t.join()
3597 sizeResponses.append( t.result )
3598 sizeResults = main.TRUE
3599 for i in range( numControllers ):
3600 if size != sizeResponses[ i ]:
3601 sizeResults = main.FALSE
3602 main.log.error( "ONOS" + str( i + 1 ) +
3603 " expected a size of " + str( size ) +
3604 " for set " + onosSetName +
3605 " but got " + str( sizeResponses[ i ] ) )
3606 addAllResults = addAllResults and getResults and sizeResults
3607 utilities.assert_equals( expect=main.TRUE,
3608 actual=addAllResults,
3609 onpass="Set addAll correct",
3610 onfail="Set addAll was incorrect" )
3611
3612 main.step( "Distributed Set clear()" )
3613 onosSet.clear()
3614 clearResponses = []
3615 threads = []
3616 for i in range( numControllers ):
3617 t = main.Thread( target=CLIs[i].setTestRemove,
3618 name="setTestClear-" + str( i ),
3619 args=[ onosSetName, " "], # Values doesn't matter
3620 kwargs={ "clear": True } )
3621 threads.append( t )
3622 t.start()
3623 for t in threads:
3624 t.join()
3625 clearResponses.append( t.result )
3626
3627 # main.TRUE = successfully changed the set
3628 # main.FALSE = action resulted in no change in set
3629 # main.ERROR - Some error in executing the function
3630 clearResults = main.TRUE
3631 for i in range( numControllers ):
3632 if clearResponses[ i ] == main.TRUE:
3633 # All is well
3634 pass
3635 elif clearResponses[ i ] == main.FALSE:
3636 # Nothing set, probably fine
3637 pass
3638 elif clearResponses[ i ] == main.ERROR:
3639 # Error in execution
3640 clearResults = main.FALSE
3641 else:
3642 # unexpected result
3643 clearResults = main.FALSE
3644 if clearResults != main.TRUE:
3645 main.log.error( "Error executing set clear" )
3646
3647 # Check if set is still correct
3648 size = len( onosSet )
3649 getResponses = []
3650 threads = []
3651 for i in range( numControllers ):
3652 t = main.Thread( target=CLIs[i].setTestGet,
3653 name="setTestGet-" + str( i ),
3654 args=[ onosSetName ] )
3655 threads.append( t )
3656 t.start()
3657 for t in threads:
3658 t.join()
3659 getResponses.append( t.result )
3660 getResults = main.TRUE
3661 for i in range( numControllers ):
3662 if isinstance( getResponses[ i ], list):
3663 current = set( getResponses[ i ] )
3664 if len( current ) == len( getResponses[ i ] ):
3665 # no repeats
3666 if onosSet != current:
3667 main.log.error( "ONOS" + str( i + 1 ) +
3668 " has incorrect view" +
3669 " of set " + onosSetName + ":\n" +
3670 str( getResponses[ i ] ) )
3671 main.log.debug( "Expected: " + str( onosSet ) )
3672 main.log.debug( "Actual: " + str( current ) )
3673 getResults = main.FALSE
3674 else:
3675 # error, set is not a set
3676 main.log.error( "ONOS" + str( i + 1 ) +
3677 " has repeat elements in" +
3678 " set " + onosSetName + ":\n" +
3679 str( getResponses[ i ] ) )
3680 getResults = main.FALSE
3681 elif getResponses[ i ] == main.ERROR:
3682 getResults = main.FALSE
3683 sizeResponses = []
3684 threads = []
3685 for i in range( numControllers ):
3686 t = main.Thread( target=CLIs[i].setTestSize,
3687 name="setTestSize-" + str( i ),
3688 args=[ onosSetName ] )
3689 threads.append( t )
3690 t.start()
3691 for t in threads:
3692 t.join()
3693 sizeResponses.append( t.result )
3694 sizeResults = main.TRUE
3695 for i in range( numControllers ):
3696 if size != sizeResponses[ i ]:
3697 sizeResults = main.FALSE
3698 main.log.error( "ONOS" + str( i + 1 ) +
3699 " expected a size of " + str( size ) +
3700 " for set " + onosSetName +
3701 " but got " + str( sizeResponses[ i ] ) )
3702 clearResults = clearResults and getResults and sizeResults
3703 utilities.assert_equals( expect=main.TRUE,
3704 actual=clearResults,
3705 onpass="Set clear correct",
3706 onfail="Set clear was incorrect" )
3707
3708 main.step( "Distributed Set addAll()" )
3709 onosSet.update( addAllValue.split() )
3710 addResponses = []
3711 threads = []
3712 for i in range( numControllers ):
3713 t = main.Thread( target=CLIs[i].setTestAdd,
3714 name="setTestAddAll-" + str( i ),
3715 args=[ onosSetName, addAllValue ] )
3716 threads.append( t )
3717 t.start()
3718 for t in threads:
3719 t.join()
3720 addResponses.append( t.result )
3721
3722 # main.TRUE = successfully changed the set
3723 # main.FALSE = action resulted in no change in set
3724 # main.ERROR - Some error in executing the function
3725 addAllResults = main.TRUE
3726 for i in range( numControllers ):
3727 if addResponses[ i ] == main.TRUE:
3728 # All is well
3729 pass
3730 elif addResponses[ i ] == main.FALSE:
3731 # Already in set, probably fine
3732 pass
3733 elif addResponses[ i ] == main.ERROR:
3734 # Error in execution
3735 addAllResults = main.FALSE
3736 else:
3737 # unexpected result
3738 addAllResults = main.FALSE
3739 if addAllResults != main.TRUE:
3740 main.log.error( "Error executing set addAll" )
3741
3742 # Check if set is still correct
3743 size = len( onosSet )
3744 getResponses = []
3745 threads = []
3746 for i in range( numControllers ):
3747 t = main.Thread( target=CLIs[i].setTestGet,
3748 name="setTestGet-" + str( i ),
3749 args=[ onosSetName ] )
3750 threads.append( t )
3751 t.start()
3752 for t in threads:
3753 t.join()
3754 getResponses.append( t.result )
3755 getResults = main.TRUE
3756 for i in range( numControllers ):
3757 if isinstance( getResponses[ i ], list):
3758 current = set( getResponses[ i ] )
3759 if len( current ) == len( getResponses[ i ] ):
3760 # no repeats
3761 if onosSet != current:
3762 main.log.error( "ONOS" + str( i + 1 ) +
3763 " has incorrect view" +
3764 " of set " + onosSetName + ":\n" +
3765 str( getResponses[ i ] ) )
3766 main.log.debug( "Expected: " + str( onosSet ) )
3767 main.log.debug( "Actual: " + str( current ) )
3768 getResults = main.FALSE
3769 else:
3770 # error, set is not a set
3771 main.log.error( "ONOS" + str( i + 1 ) +
3772 " has repeat elements in" +
3773 " set " + onosSetName + ":\n" +
3774 str( getResponses[ i ] ) )
3775 getResults = main.FALSE
3776 elif getResponses[ i ] == main.ERROR:
3777 getResults = main.FALSE
3778 sizeResponses = []
3779 threads = []
3780 for i in range( numControllers ):
3781 t = main.Thread( target=CLIs[i].setTestSize,
3782 name="setTestSize-" + str( i ),
3783 args=[ onosSetName ] )
3784 threads.append( t )
3785 t.start()
3786 for t in threads:
3787 t.join()
3788 sizeResponses.append( t.result )
3789 sizeResults = main.TRUE
3790 for i in range( numControllers ):
3791 if size != sizeResponses[ i ]:
3792 sizeResults = main.FALSE
3793 main.log.error( "ONOS" + str( i + 1 ) +
3794 " expected a size of " + str( size ) +
3795 " for set " + onosSetName +
3796 " but got " + str( sizeResponses[ i ] ) )
3797 addAllResults = addAllResults and getResults and sizeResults
3798 utilities.assert_equals( expect=main.TRUE,
3799 actual=addAllResults,
3800 onpass="Set addAll correct",
3801 onfail="Set addAll was incorrect" )
3802
3803 main.step( "Distributed Set retain()" )
3804 onosSet.intersection_update( retainValue.split() )
3805 retainResponses = []
3806 threads = []
3807 for i in range( numControllers ):
3808 t = main.Thread( target=CLIs[i].setTestRemove,
3809 name="setTestRetain-" + str( i ),
3810 args=[ onosSetName, retainValue ],
3811 kwargs={ "retain": True } )
3812 threads.append( t )
3813 t.start()
3814 for t in threads:
3815 t.join()
3816 retainResponses.append( t.result )
3817
3818 # main.TRUE = successfully changed the set
3819 # main.FALSE = action resulted in no change in set
3820 # main.ERROR - Some error in executing the function
3821 retainResults = main.TRUE
3822 for i in range( numControllers ):
3823 if retainResponses[ i ] == main.TRUE:
3824 # All is well
3825 pass
3826 elif retainResponses[ i ] == main.FALSE:
3827 # Already in set, probably fine
3828 pass
3829 elif retainResponses[ i ] == main.ERROR:
3830 # Error in execution
3831 retainResults = main.FALSE
3832 else:
3833 # unexpected result
3834 retainResults = main.FALSE
3835 if retainResults != main.TRUE:
3836 main.log.error( "Error executing set retain" )
3837
3838 # Check if set is still correct
3839 size = len( onosSet )
3840 getResponses = []
3841 threads = []
3842 for i in range( numControllers ):
3843 t = main.Thread( target=CLIs[i].setTestGet,
3844 name="setTestGet-" + str( i ),
3845 args=[ onosSetName ] )
3846 threads.append( t )
3847 t.start()
3848 for t in threads:
3849 t.join()
3850 getResponses.append( t.result )
3851 getResults = main.TRUE
3852 for i in range( numControllers ):
3853 if isinstance( getResponses[ i ], list):
3854 current = set( getResponses[ i ] )
3855 if len( current ) == len( getResponses[ i ] ):
3856 # no repeats
3857 if onosSet != current:
3858 main.log.error( "ONOS" + str( i + 1 ) +
3859 " has incorrect view" +
3860 " of set " + onosSetName + ":\n" +
3861 str( getResponses[ i ] ) )
3862 main.log.debug( "Expected: " + str( onosSet ) )
3863 main.log.debug( "Actual: " + str( current ) )
3864 getResults = main.FALSE
3865 else:
3866 # error, set is not a set
3867 main.log.error( "ONOS" + str( i + 1 ) +
3868 " has repeat elements in" +
3869 " set " + onosSetName + ":\n" +
3870 str( getResponses[ i ] ) )
3871 getResults = main.FALSE
3872 elif getResponses[ i ] == main.ERROR:
3873 getResults = main.FALSE
3874 sizeResponses = []
3875 threads = []
3876 for i in range( numControllers ):
3877 t = main.Thread( target=CLIs[i].setTestSize,
3878 name="setTestSize-" + str( i ),
3879 args=[ onosSetName ] )
3880 threads.append( t )
3881 t.start()
3882 for t in threads:
3883 t.join()
3884 sizeResponses.append( t.result )
3885 sizeResults = main.TRUE
3886 for i in range( numControllers ):
3887 if size != sizeResponses[ i ]:
3888 sizeResults = main.FALSE
3889 main.log.error( "ONOS" + str( i + 1 ) +
3890 " expected a size of " +
3891 str( size ) + " for set " + onosSetName +
3892 " but got " + str( sizeResponses[ i ] ) )
3893 retainResults = retainResults and getResults and sizeResults
3894 utilities.assert_equals( expect=main.TRUE,
3895 actual=retainResults,
3896 onpass="Set retain correct",
3897 onfail="Set retain was incorrect" )
3898