blob: 8d952c743ac967965348e7a6a9ce27f2e8913da9 [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 Hallb1290e82014-11-18 16:17:48 -05001085
Jon Hall6aec96b2015-01-19 14:49:31 -08001086 main.case( "Setting up and gathering data for current state" )
1087 # The general idea for this test case is to pull the state of
1088 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -07001089 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -05001090
Jon Hall65844a32015-03-09 19:09:37 -07001091 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001092 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001093 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001094
Jon Hall6aec96b2015-01-19 14:49:31 -08001095 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001096 rolesNotNull = main.TRUE
1097 threads = []
1098 for i in range( numControllers ):
1099 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001100 name="rolesNotNull-" + str( i ),
1101 args=[] )
1102 threads.append( t )
1103 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001104
1105 for t in threads:
1106 t.join()
1107 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 utilities.assert_equals(
1109 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001110 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001111 onpass="Each device has a master",
1112 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001113
Jon Hall65844a32015-03-09 19:09:37 -07001114 main.step( "Get the Mastership of each switch from each controller" )
1115 ONOSMastership = []
1116 mastershipCheck = main.FALSE
1117 consistentMastership = True
1118 rolesResults = True
1119 threads = []
1120 for i in range( numControllers ):
1121 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001122 name="roles-" + str( i ),
1123 args=[] )
1124 threads.append( t )
1125 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001126
1127 for t in threads:
1128 t.join()
1129 ONOSMastership.append( t.result )
1130
1131 for i in range( numControllers ):
1132 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001133 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001134 " roles" )
1135 main.log.warn(
1136 "ONOS" + str( i + 1 ) + " mastership response: " +
1137 repr( ONOSMastership[i] ) )
1138 rolesResults = False
1139 utilities.assert_equals(
1140 expect=True,
1141 actual=rolesResults,
1142 onpass="No error in reading roles output",
1143 onfail="Error in reading roles from ONOS" )
1144
1145 main.step( "Check for consistency in roles from each controller" )
1146 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001147 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001148 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001149 else:
Jon Hall65844a32015-03-09 19:09:37 -07001150 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001151 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001152 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001153 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001154 onpass="Switch roles are consistent across all ONOS nodes",
1155 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001156
Jon Hall65844a32015-03-09 19:09:37 -07001157 if rolesResults and not consistentMastership:
1158 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001159 try:
1160 main.log.warn(
1161 "ONOS" + str( i + 1 ) + " roles: ",
1162 json.dumps(
1163 json.loads( ONOSMastership[ i ] ),
1164 sort_keys=True,
1165 indent=4,
1166 separators=( ',', ': ' ) ) )
1167 except ( ValueError, TypeError ):
1168 main.log.warn( repr( ONOSMastership[ i ] ) )
1169 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001170 mastershipCheck = main.TRUE
1171 mastershipState = ONOSMastership[ 0 ]
1172
Jon Hall6aec96b2015-01-19 14:49:31 -08001173 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001174 global intentState
1175 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001176 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001177 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001178 consistentIntents = True
1179 intentsResults = True
1180 threads = []
1181 for i in range( numControllers ):
1182 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001183 name="intents-" + str( i ),
1184 args=[],
1185 kwargs={ 'jsonFormat': True } )
1186 threads.append( t )
1187 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001188
1189 for t in threads:
1190 t.join()
1191 ONOSIntents.append( t.result )
1192
1193 for i in range( numControllers ):
1194 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001195 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001196 " intents" )
1197 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1198 repr( ONOSIntents[ i ] ) )
1199 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001200 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001201 expect=True,
1202 actual=intentsResults,
1203 onpass="No error in reading intents output",
1204 onfail="Error in reading intents from ONOS" )
1205
1206 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001207 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001208 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001209 "nodes" )
1210 else:
1211 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001212 main.log.error( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001213 utilities.assert_equals(
1214 expect=True,
1215 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001216 onpass="Intents are consistent across all ONOS nodes",
1217 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001218
Jon Hall390696c2015-05-05 17:13:41 -07001219 if intentsResults:
1220 # Try to make it easy to figure out what is happening
1221 #
1222 # Intent ONOS1 ONOS2 ...
1223 # 0x01 INSTALLED INSTALLING
1224 # ... ... ...
1225 # ... ... ...
1226 title = " Id"
1227 for n in range( numControllers ):
1228 title += " " * 10 + "ONOS" + str( n + 1 )
1229 main.log.warn( title )
Jon Hall390696c2015-05-05 17:13:41 -07001230 keys = []
Jon Hall40d2cbd2015-06-03 16:24:29 -07001231 try:
1232 # Get the set of all intent keys
Jon Hall390696c2015-05-05 17:13:41 -07001233 for nodeStr in ONOSIntents:
1234 node = json.loads( nodeStr )
1235 for intent in node:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001236 keys.append( intent.get( 'id' ) )
1237 keys = set( keys )
1238 # For each intent key, print the state on each node
1239 for key in keys:
1240 row = "%-13s" % key
1241 for nodeStr in ONOSIntents:
1242 node = json.loads( nodeStr )
1243 for intent in node:
1244 if intent.get( 'id', "Error" ) == key:
1245 row += "%-15s" % intent.get( 'state' )
1246 main.log.warn( row )
1247 # End of intent state table
1248 except ValueError as e:
1249 main.log.exception( e )
1250 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall390696c2015-05-05 17:13:41 -07001251
Jon Hall65844a32015-03-09 19:09:37 -07001252 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001253 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001254 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001255 main.log.debug( "ONOS" + str( n ) + " intents: " )
1256 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1257 sort_keys=True,
1258 indent=4,
1259 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001260 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001261 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001262 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1263 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1264 sort_keys=True,
1265 indent=4,
1266 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001267 else:
Jon Hall390696c2015-05-05 17:13:41 -07001268 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1269 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001270 elif intentsResults and consistentIntents:
1271 intentCheck = main.TRUE
1272 intentState = ONOSIntents[ 0 ]
1273
Jon Hall6aec96b2015-01-19 14:49:31 -08001274 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001275 global flowState
1276 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001277 ONOSFlows = []
1278 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001279 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001280 consistentFlows = True
1281 flowsResults = True
1282 threads = []
1283 for i in range( numControllers ):
1284 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001285 name="flows-" + str( i ),
1286 args=[],
1287 kwargs={ 'jsonFormat': True } )
1288 threads.append( t )
1289 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001290
Jon Halla9d26da2015-03-30 16:45:32 -07001291 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001292 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001293 for t in threads:
1294 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001295 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001296 ONOSFlows.append( result )
1297
1298 for i in range( numControllers ):
1299 num = str( i + 1 )
1300 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001301 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall65844a32015-03-09 19:09:37 -07001302 main.log.warn( "ONOS" + num + " flows response: " +
1303 repr( ONOSFlows[ i ] ) )
1304 flowsResults = False
1305 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001306 else:
Jon Hall65844a32015-03-09 19:09:37 -07001307 try:
1308 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1309 except ( ValueError, TypeError ):
1310 # FIXME: change this to log.error?
1311 main.log.exception( "Error in parsing ONOS" + num +
1312 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001313 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001314 ONOSFlowsJson.append( None )
1315 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001316 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001317 expect=True,
1318 actual=flowsResults,
1319 onpass="No error in reading flows output",
1320 onfail="Error in reading flows from ONOS" )
1321
1322 main.step( "Check for consistency in Flows from each controller" )
1323 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1324 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001325 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001326 else:
1327 consistentFlows = False
1328 utilities.assert_equals(
1329 expect=True,
1330 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001331 onpass="The flow count is consistent across all ONOS nodes",
1332 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001333
Jon Hall65844a32015-03-09 19:09:37 -07001334 if flowsResults and not consistentFlows:
1335 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001336 try:
1337 main.log.warn(
1338 "ONOS" + str( i + 1 ) + " flows: " +
1339 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1340 indent=4, separators=( ',', ': ' ) ) )
1341 except ( ValueError, TypeError ):
1342 main.log.warn(
1343 "ONOS" + str( i + 1 ) + " flows: " +
1344 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001345 elif flowsResults and consistentFlows:
1346 flowCheck = main.TRUE
1347 flowState = ONOSFlows[ 0 ]
1348
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001350 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 flows = []
1352 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001353 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001354 if flowCheck == main.FALSE:
1355 for table in flows:
1356 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001357 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001358
Jon Hall6aec96b2015-01-19 14:49:31 -08001359 main.step( "Start continuous pings" )
1360 main.Mininet2.pingLong(
1361 src=main.params[ 'PING' ][ 'source1' ],
1362 target=main.params[ 'PING' ][ 'target1' ],
1363 pingTime=500 )
1364 main.Mininet2.pingLong(
1365 src=main.params[ 'PING' ][ 'source2' ],
1366 target=main.params[ 'PING' ][ 'target2' ],
1367 pingTime=500 )
1368 main.Mininet2.pingLong(
1369 src=main.params[ 'PING' ][ 'source3' ],
1370 target=main.params[ 'PING' ][ 'target3' ],
1371 pingTime=500 )
1372 main.Mininet2.pingLong(
1373 src=main.params[ 'PING' ][ 'source4' ],
1374 target=main.params[ 'PING' ][ 'target4' ],
1375 pingTime=500 )
1376 main.Mininet2.pingLong(
1377 src=main.params[ 'PING' ][ 'source5' ],
1378 target=main.params[ 'PING' ][ 'target5' ],
1379 pingTime=500 )
1380 main.Mininet2.pingLong(
1381 src=main.params[ 'PING' ][ 'source6' ],
1382 target=main.params[ 'PING' ][ 'target6' ],
1383 pingTime=500 )
1384 main.Mininet2.pingLong(
1385 src=main.params[ 'PING' ][ 'source7' ],
1386 target=main.params[ 'PING' ][ 'target7' ],
1387 pingTime=500 )
1388 main.Mininet2.pingLong(
1389 src=main.params[ 'PING' ][ 'source8' ],
1390 target=main.params[ 'PING' ][ 'target8' ],
1391 pingTime=500 )
1392 main.Mininet2.pingLong(
1393 src=main.params[ 'PING' ][ 'source9' ],
1394 target=main.params[ 'PING' ][ 'target9' ],
1395 pingTime=500 )
1396 main.Mininet2.pingLong(
1397 src=main.params[ 'PING' ][ 'source10' ],
1398 target=main.params[ 'PING' ][ 'target10' ],
1399 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001400
Jon Hall6aec96b2015-01-19 14:49:31 -08001401 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001402 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001403 threads = []
1404 for i in range( numControllers ):
1405 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001406 name="devices-" + str( i ),
1407 args=[ ] )
1408 threads.append( t )
1409 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001410
1411 for t in threads:
1412 t.join()
1413 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001414 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001415 threads = []
1416 for i in range( numControllers ):
1417 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001418 name="hosts-" + str( i ),
1419 args=[ ] )
1420 threads.append( t )
1421 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001422
1423 for t in threads:
1424 t.join()
1425 try:
1426 hosts.append( json.loads( t.result ) )
1427 except ( ValueError, TypeError ):
1428 # FIXME: better handling of this, print which node
1429 # Maybe use thread name?
1430 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001431 # FIXME: should this be an empty json object instead?
1432 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001433
Jon Hallb1290e82014-11-18 16:17:48 -05001434 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001435 threads = []
1436 for i in range( numControllers ):
1437 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001438 name="ports-" + str( i ),
1439 args=[ ] )
1440 threads.append( t )
1441 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001442
1443 for t in threads:
1444 t.join()
1445 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001446 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001447 threads = []
1448 for i in range( numControllers ):
1449 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001450 name="links-" + str( i ),
1451 args=[ ] )
1452 threads.append( t )
1453 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001454
1455 for t in threads:
1456 t.join()
1457 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001458 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001459 threads = []
1460 for i in range( numControllers ):
1461 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001462 name="clusters-" + str( i ),
1463 args=[ ] )
1464 threads.append( t )
1465 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001466
1467 for t in threads:
1468 t.join()
1469 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001470 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001471
Jon Hall6aec96b2015-01-19 14:49:31 -08001472 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001473 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001474 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001475 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001476 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001477 if "Error" not in hosts[ controller ]:
1478 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001479 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001480 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001481 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001482 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001483 " is inconsistent with ONOS1" )
1484 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001485 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001486
1487 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001488 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001489 controllerStr )
1490 consistentHostsResult = main.FALSE
1491 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001492 " hosts response: " +
1493 repr( hosts[ controller ] ) )
1494 utilities.assert_equals(
1495 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001496 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001497 onpass="Hosts view is consistent across all ONOS nodes",
1498 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001499
Jon Hall390696c2015-05-05 17:13:41 -07001500 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001501 ipResult = main.TRUE
1502 for controller in range( 0, len( hosts ) ):
1503 controllerStr = str( controller + 1 )
1504 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001505 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001506 main.log.error( "DEBUG:Error with host ips on controller" +
1507 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001508 ipResult = main.FALSE
1509 utilities.assert_equals(
1510 expect=main.TRUE,
1511 actual=ipResult,
1512 onpass="The ips of the hosts aren't empty",
1513 onfail="The ip of at least one host is missing" )
1514
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001516 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001517 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001518 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001519 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001520 if "Error" not in clusters[ controller ]:
1521 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001522 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001523 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001524 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001525 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001526 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001527
1528 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001529 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001530 "from ONOS" + controllerStr )
1531 consistentClustersResult = main.FALSE
1532 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001533 " clusters response: " +
1534 repr( clusters[ controller ] ) )
1535 utilities.assert_equals(
1536 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001537 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001538 onpass="Clusters view is consistent across all ONOS nodes",
1539 onfail="ONOS nodes have different views of clusters" )
1540 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001541 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001542 try:
1543 numClusters = len( json.loads( clusters[ 0 ] ) )
1544 except ( ValueError, TypeError ):
1545 main.log.exception( "Error parsing clusters[0]: " +
1546 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001547 clusterResults = main.FALSE
1548 if numClusters == 1:
1549 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001550 utilities.assert_equals(
1551 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001552 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001553 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001554 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001555
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001557 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001558 linksResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001559 hostsResults = main.TRUE
1560 mnSwitches = main.Mininet1.getSwitches()
1561 mnLinks = main.Mininet1.getLinks()
1562 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001563 for controller in range( numControllers ):
1564 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001565 if devices[ controller ] and ports[ controller ] and\
1566 "Error" not in devices[ controller ] and\
1567 "Error" not in ports[ controller ]:
1568
Jon Hall8f89dda2015-01-22 16:03:33 -08001569 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001570 mnSwitches,
1571 json.loads( devices[ controller ] ),
1572 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001573 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001574 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001575 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001576 actual=currentDevicesResult,
1577 onpass="ONOS" + controllerStr +
1578 " Switches view is correct",
1579 onfail="ONOS" + controllerStr +
1580 " Switches view is incorrect" )
Jon Hallafa8a472015-06-12 14:02:42 -07001581 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001582 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001583 mnSwitches, mnLinks,
1584 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001585 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001586 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001587 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001588 actual=currentLinksResult,
1589 onpass="ONOS" + controllerStr +
1590 " links view is correct",
1591 onfail="ONOS" + controllerStr +
1592 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001593
Jon Hallafa8a472015-06-12 14:02:42 -07001594 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1595 currentHostsResult = main.Mininet1.compareHosts(
1596 mnHosts,
1597 hosts[ controller ] )
1598 else:
1599 currentHostsResult = main.FALSE
1600 utilities.assert_equals( expect=main.TRUE,
1601 actual=currentHostsResult,
1602 onpass="ONOS" + controllerStr +
1603 " hosts exist in Mininet",
1604 onfail="ONOS" + controllerStr +
1605 " hosts don't match Mininet" )
Jon Hallb6a54872015-06-12 14:02:42 -07001606
Jon Hallafa8a472015-06-12 14:02:42 -07001607 devicesResults = devicesResults and currentDevicesResult
1608 linksResults = linksResults and currentLinksResult
1609 hostsResults = hostsResults and currentHostsResult
1610
1611 main.step( "Device information is correct" )
1612 utilities.assert_equals(
1613 expect=main.TRUE,
1614 actual=devicesResults,
1615 onpass="Device information is correct",
1616 onfail="Device information is incorrect" )
1617
1618 main.step( "Links are correct" )
1619 utilities.assert_equals(
1620 expect=main.TRUE,
1621 actual=linksResults,
1622 onpass="Link are correct",
1623 onfail="Links are incorrect" )
1624
1625 main.step( "Hosts are correct" )
1626 utilities.assert_equals(
1627 expect=main.TRUE,
1628 actual=hostsResults,
1629 onpass="Hosts are correct",
1630 onfail="Hosts are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001631
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 def CASE6( self, main ):
1633 """
Jon Hallb1290e82014-11-18 16:17:48 -05001634 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001635 """
Jon Hall368769f2014-11-19 15:43:35 -08001636 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001637 assert numControllers, "numControllers not defined"
1638 assert main, "main not defined"
1639 assert utilities.assert_equals, "utilities.assert_equals not defined"
1640 assert CLIs, "CLIs not defined"
1641 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001642 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001643 time.sleep( 60 )
1644 utilities.assert_equals(
1645 expect=main.TRUE,
1646 actual=main.TRUE,
1647 onpass="Sleeping 60 seconds",
1648 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001649
Jon Hall6aec96b2015-01-19 14:49:31 -08001650 def CASE7( self, main ):
1651 """
Jon Hall368769f2014-11-19 15:43:35 -08001652 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001653 """
Jon Hallb1290e82014-11-18 16:17:48 -05001654 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001655 assert numControllers, "numControllers not defined"
1656 assert main, "main not defined"
1657 assert utilities.assert_equals, "utilities.assert_equals not defined"
1658 assert CLIs, "CLIs not defined"
1659 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001660 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001661
Jon Hall65844a32015-03-09 19:09:37 -07001662 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001663 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001664 rolesNotNull = main.TRUE
1665 threads = []
1666 for i in range( numControllers ):
1667 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001668 name="rolesNotNull-" + str( i ),
1669 args=[ ] )
1670 threads.append( t )
1671 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001672
1673 for t in threads:
1674 t.join()
1675 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001676 utilities.assert_equals(
1677 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001678 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001679 onpass="Each device has a master",
1680 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001681
Jon Hall390696c2015-05-05 17:13:41 -07001682 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001683 ONOSMastership = []
1684 mastershipCheck = main.FALSE
1685 consistentMastership = True
1686 rolesResults = True
1687 threads = []
1688 for i in range( numControllers ):
1689 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001690 name="roles-" + str( i ),
1691 args=[] )
1692 threads.append( t )
1693 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001694
1695 for t in threads:
1696 t.join()
1697 ONOSMastership.append( t.result )
1698
1699 for i in range( numControllers ):
1700 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001701 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001702 " roles" )
1703 main.log.warn(
1704 "ONOS" + str( i + 1 ) + " mastership response: " +
1705 repr( ONOSMastership[i] ) )
1706 rolesResults = False
1707 utilities.assert_equals(
1708 expect=True,
1709 actual=rolesResults,
1710 onpass="No error in reading roles output",
1711 onfail="Error in reading roles from ONOS" )
1712
1713 main.step( "Check for consistency in roles from each controller" )
1714 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001715 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001716 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001717 else:
Jon Hall65844a32015-03-09 19:09:37 -07001718 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001719 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001720 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001721 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001722 onpass="Switch roles are consistent across all ONOS nodes",
1723 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001724
Jon Hall65844a32015-03-09 19:09:37 -07001725 if rolesResults and not consistentMastership:
1726 for i in range( numControllers ):
1727 main.log.warn(
1728 "ONOS" + str( i + 1 ) + " roles: ",
1729 json.dumps(
1730 json.loads( ONOSMastership[ i ] ),
1731 sort_keys=True,
1732 indent=4,
1733 separators=( ',', ': ' ) ) )
1734 elif rolesResults and not consistentMastership:
1735 mastershipCheck = main.TRUE
1736
Jon Hallb1290e82014-11-18 16:17:48 -05001737 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001738 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001739 try:
1740 currentJson = json.loads( ONOSMastership[0] )
1741 oldJson = json.loads( mastershipState )
1742 except ( ValueError, TypeError ):
1743 main.log.exception( "Something is wrong with parsing " +
1744 "ONOSMastership[0] or mastershipState" )
1745 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1746 main.log.error( "mastershipState" + repr( mastershipState ) )
1747 main.cleanup()
1748 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001749 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001750 for i in range( 1, 29 ):
1751 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001752 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001753 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001755 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001756 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001757 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001758 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001759 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001760 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001761 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 utilities.assert_equals(
1763 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001764 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001765 onpass="Mastership of Switches was not changed",
1766 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001767 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001768
Jon Hall6aec96b2015-01-19 14:49:31 -08001769 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001770 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001771 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001772 consistentIntents = True
1773 intentsResults = True
1774 threads = []
1775 for i in range( numControllers ):
1776 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001777 name="intents-" + str( i ),
1778 args=[],
1779 kwargs={ 'jsonFormat': True } )
1780 threads.append( t )
1781 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001782
1783 for t in threads:
1784 t.join()
1785 ONOSIntents.append( t.result )
1786
1787 for i in range( numControllers ):
1788 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001789 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001790 " intents" )
1791 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1792 repr( ONOSIntents[ i ] ) )
1793 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001794 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001795 expect=True,
1796 actual=intentsResults,
1797 onpass="No error in reading intents output",
1798 onfail="Error in reading intents from ONOS" )
1799
1800 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001801 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001802 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001803 "nodes" )
1804 else:
1805 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001806
1807 # Try to make it easy to figure out what is happening
1808 #
1809 # Intent ONOS1 ONOS2 ...
1810 # 0x01 INSTALLED INSTALLING
1811 # ... ... ...
1812 # ... ... ...
1813 title = " ID"
1814 for n in range( numControllers ):
1815 title += " " * 10 + "ONOS" + str( n + 1 )
1816 main.log.warn( title )
1817 # get all intent keys in the cluster
1818 keys = []
1819 for nodeStr in ONOSIntents:
1820 node = json.loads( nodeStr )
1821 for intent in node:
1822 keys.append( intent.get( 'id' ) )
1823 keys = set( keys )
1824 for key in keys:
1825 row = "%-13s" % key
1826 for nodeStr in ONOSIntents:
1827 node = json.loads( nodeStr )
1828 for intent in node:
1829 if intent.get( 'id' ) == key:
1830 row += "%-15s" % intent.get( 'state' )
1831 main.log.warn( row )
1832 # End table view
1833
Jon Hall65844a32015-03-09 19:09:37 -07001834 utilities.assert_equals(
1835 expect=True,
1836 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001837 onpass="Intents are consistent across all ONOS nodes",
1838 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001839 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001840 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001841 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001842 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001843 try:
1844 for intent in json.loads( node ):
1845 nodeStates.append( intent[ 'state' ] )
1846 except ( ValueError, TypeError ):
1847 main.log.exception( "Error in parsing intents" )
1848 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001849 intentStates.append( nodeStates )
1850 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1851 main.log.info( dict( out ) )
1852
Jon Hall65844a32015-03-09 19:09:37 -07001853 if intentsResults and not consistentIntents:
1854 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001855 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1856 main.log.warn( json.dumps(
1857 json.loads( ONOSIntents[ i ] ),
1858 sort_keys=True,
1859 indent=4,
1860 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001861 elif intentsResults and consistentIntents:
1862 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001863
Jon Hall58c76b72015-02-23 11:09:24 -08001864 # NOTE: Store has no durability, so intents are lost across system
1865 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001866 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001868 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001869 sameIntents = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001870 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001871 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001872 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001873 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001874 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001875 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1876 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001877 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001878 before = json.loads( intentState )
1879 after = json.loads( ONOSIntents[ 0 ] )
1880 for intent in before:
1881 if intent not in after:
1882 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001883 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001884 "(at least in the same form):" )
1885 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001886 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001887 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001888 main.log.debug( repr( ONOSIntents[0] ) )
1889 main.log.debug( repr( intentState ) )
1890 if sameIntents == main.FALSE:
1891 try:
1892 main.log.debug( "ONOS intents before: " )
1893 main.log.debug( json.dumps( json.loads( intentState ),
1894 sort_keys=True, indent=4,
1895 separators=( ',', ': ' ) ) )
1896 main.log.debug( "Current ONOS intents: " )
1897 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1898 sort_keys=True, indent=4,
1899 separators=( ',', ': ' ) ) )
1900 except ( ValueError, TypeError ):
1901 main.log.exception( "Exception printing intents" )
1902 main.log.debug( repr( ONOSIntents[0] ) )
1903 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001904 utilities.assert_equals(
1905 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001906 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001907 onpass="Intents are consistent with before failure",
1908 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001909 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001910
Jon Hall6aec96b2015-01-19 14:49:31 -08001911 main.step( "Get the OF Table entries and compare to before " +
1912 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001913 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001914 flows2 = []
1915 for i in range( 28 ):
1916 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001917 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1918 flows2.append( tmpFlows )
1919 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001920 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001921 flow2=tmpFlows )
1922 FlowTables = FlowTables and tempResult
1923 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001924 main.log.info( "Differences in flow table for switch: s" +
1925 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001926 utilities.assert_equals(
1927 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001928 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001929 onpass="No changes were found in the flow tables",
1930 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001931
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 main.step( "Check the continuous pings to ensure that no packets " +
1933 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001934 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1935 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001936 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001937 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1938 for i in range( 8, 18 ):
1939 main.log.info(
1940 "Checking for a loss in pings along flow from s" +
1941 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001942 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001943 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001944 str( i ) ) or LossInPings
1945 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001947 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001949 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001950 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001951 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001952 utilities.assert_equals(
1953 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001954 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001955 onpass="No Loss of connectivity",
1956 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001957
Jon Hall390696c2015-05-05 17:13:41 -07001958 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001959 # Test of LeadershipElection
1960 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001961 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001962 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001963 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001964 for cli in CLIs:
1965 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001966 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001967 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 # all is well
1969 # NOTE: In failure scenario, this could be a new node, maybe
1970 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001971 pass
1972 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001973 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001974 main.log.error( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001975 "electionTestLeader function, check the" +
1976 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001977 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001978 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001979 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001980 main.log.error( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001981 " as the leader of the election app. " +
1982 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001983 utilities.assert_equals(
1984 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001985 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001986 onpass="Leadership election passed",
1987 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001988
Jon Hall6aec96b2015-01-19 14:49:31 -08001989 def CASE8( self, main ):
1990 """
Jon Hallb1290e82014-11-18 16:17:48 -05001991 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001992 """
Jon Hallb1290e82014-11-18 16:17:48 -05001993 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001994 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001995 assert numControllers, "numControllers not defined"
1996 assert main, "main not defined"
1997 assert utilities.assert_equals, "utilities.assert_equals not defined"
1998 assert CLIs, "CLIs not defined"
1999 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002000
Jon Hallfeff3082015-05-19 10:23:26 -07002001 main.case( "Compare ONOS Topology view to Mininet topology" )
2002 main.caseExplaination = "Compare topology objects between Mininet" +\
2003 " and ONOS"
Jon Hallb1290e82014-11-18 16:17:48 -05002004
Jon Hallfeff3082015-05-19 10:23:26 -07002005 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002006 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002007 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002008 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002009 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002010 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002011 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002012 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002013 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002015 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002016 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07002017 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002018 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002019 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07002020 threads = []
2021 for i in range( numControllers ):
2022 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07002023 name="devices-" + str( i ),
2024 args=[ ] )
2025 threads.append( t )
2026 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002027
2028 for t in threads:
2029 t.join()
2030 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002031 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002032 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07002033 threads = []
2034 for i in range( numControllers ):
2035 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07002036 name="hosts-" + str( i ),
2037 args=[ ] )
2038 threads.append( t )
2039 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002040
2041 for t in threads:
2042 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002043 try:
2044 hosts.append( json.loads( t.result ) )
2045 except ( ValueError, TypeError ):
2046 main.log.exception( "Error parsing hosts results" )
2047 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002048 for controller in range( 0, len( hosts ) ):
2049 controllerStr = str( controller + 1 )
2050 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002051 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002052 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002053 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002054 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002055 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002056 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07002057 threads = []
2058 for i in range( numControllers ):
2059 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07002060 name="ports-" + str( i ),
2061 args=[ ] )
2062 threads.append( t )
2063 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002064
2065 for t in threads:
2066 t.join()
2067 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002068 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002069 threads = []
2070 for i in range( numControllers ):
2071 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002072 name="links-" + str( i ),
2073 args=[ ] )
2074 threads.append( t )
2075 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002076
2077 for t in threads:
2078 t.join()
2079 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002080 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002081 threads = []
2082 for i in range( numControllers ):
2083 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002084 name="clusters-" + str( i ),
2085 args=[ ] )
2086 threads.append( t )
2087 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002088
2089 for t in threads:
2090 t.join()
2091 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002092
Jon Hall8f89dda2015-01-22 16:03:33 -08002093 elapsed = time.time() - startTime
2094 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002095 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002096 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002097
Jon Hallafa8a472015-06-12 14:02:42 -07002098 mnSwitches = main.Mininet1.getSwitches()
2099 mnLinks = main.Mininet1.getLinks()
2100 mnHosts = main.Mininet1.getHosts()
Jon Hall21270ac2015-02-16 17:59:55 -08002101 for controller in range( numControllers ):
2102 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07002103 if devices[ controller ] and ports[ controller ] and\
2104 "Error" not in devices[ controller ] and\
2105 "Error" not in ports[ controller ]:
2106
Jon Hall21270ac2015-02-16 17:59:55 -08002107 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07002108 mnSwitches,
2109 json.loads( devices[ controller ] ),
2110 json.loads( ports[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002111 else:
2112 currentDevicesResult = main.FALSE
2113 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002114 actual=currentDevicesResult,
2115 onpass="ONOS" + controllerStr +
2116 " Switches view is correct",
2117 onfail="ONOS" + controllerStr +
2118 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002119
Jon Hallafa8a472015-06-12 14:02:42 -07002120 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall21270ac2015-02-16 17:59:55 -08002121 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07002122 mnSwitches, mnLinks,
2123 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002124 else:
2125 currentLinksResult = main.FALSE
2126 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002127 actual=currentLinksResult,
2128 onpass="ONOS" + controllerStr +
2129 " links view is correct",
2130 onfail="ONOS" + controllerStr +
2131 " links view is incorrect" )
2132
2133 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2134 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07002135 mnHosts,
2136 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002137 else:
2138 currentHostsResult = main.FALSE
2139 utilities.assert_equals( expect=main.TRUE,
2140 actual=currentHostsResult,
2141 onpass="ONOS" + controllerStr +
2142 " hosts exist in Mininet",
2143 onfail="ONOS" + controllerStr +
2144 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002145 # CHECKING HOST ATTACHMENT POINTS
2146 hostAttachment = True
Jon Hallafa8a472015-06-12 14:02:42 -07002147 zeroHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002148 # FIXME: topo-HA/obelisk specific mappings:
2149 # key is mac and value is dpid
2150 mappings = {}
2151 for i in range( 1, 29 ): # hosts 1 through 28
2152 # set up correct variables:
2153 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2154 if i == 1:
2155 deviceId = "1000".zfill(16)
2156 elif i == 2:
2157 deviceId = "2000".zfill(16)
2158 elif i == 3:
2159 deviceId = "3000".zfill(16)
2160 elif i == 4:
2161 deviceId = "3004".zfill(16)
2162 elif i == 5:
2163 deviceId = "5000".zfill(16)
2164 elif i == 6:
2165 deviceId = "6000".zfill(16)
2166 elif i == 7:
2167 deviceId = "6007".zfill(16)
2168 elif i >= 8 and i <= 17:
2169 dpid = '3' + str( i ).zfill( 3 )
2170 deviceId = dpid.zfill(16)
2171 elif i >= 18 and i <= 27:
2172 dpid = '6' + str( i ).zfill( 3 )
2173 deviceId = dpid.zfill(16)
2174 elif i == 28:
2175 deviceId = "2800".zfill(16)
2176 mappings[ macId ] = deviceId
2177 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2178 if hosts[ controller ] == []:
2179 main.log.warn( "There are no hosts discovered" )
Jon Hallafa8a472015-06-12 14:02:42 -07002180 zeroHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002181 else:
2182 for host in hosts[ controller ]:
2183 mac = None
2184 location = None
2185 device = None
2186 port = None
2187 try:
2188 mac = host.get( 'mac' )
2189 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002190
Jon Hallc9eabec2015-06-10 14:33:14 -07002191 location = host.get( 'location' )
2192 assert location, "location field could not be found for this host object"
2193
2194 # Trim the protocol identifier off deviceId
2195 device = str( location.get( 'elementId' ) ).split(':')[1]
2196 assert device, "elementId field could not be found for this host location object"
2197
2198 port = location.get( 'port' )
2199 assert port, "port field could not be found for this host location object"
2200
2201 # Now check if this matches where they should be
2202 if mac and device and port:
2203 if str( port ) != "1":
2204 main.log.error( "The attachment port is incorrect for " +
2205 "host " + str( mac ) +
2206 ". Expected: 1 Actual: " + str( port) )
2207 hostAttachment = False
2208 if device != mappings[ str( mac ) ]:
2209 main.log.error( "The attachment device is incorrect for " +
2210 "host " + str( mac ) +
2211 ". Expected: " + mappings[ str( mac ) ] +
2212 " Actual: " + device )
2213 hostAttachment = False
2214 else:
2215 hostAttachment = False
2216 except AssertionError:
2217 main.log.exception( "Json object not as expected" )
2218 main.log.error( repr( host ) )
2219 hostAttachment = False
2220 else:
2221 main.log.error( "No hosts json output or \"Error\"" +
2222 " in output. hosts = " +
2223 repr( hosts[ controller ] ) )
Jon Hallafa8a472015-06-12 14:02:42 -07002224 if zeroHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002225 hostAttachment = True
2226
2227 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002228 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002229 linksResults = linksResults and currentLinksResult
2230 hostsResults = hostsResults and currentHostsResult
Jon Hallafa8a472015-06-12 14:02:42 -07002231 hostAttachmentResults = hostAttachmentResults and\
2232 hostAttachment
2233 topoResult = ( devicesResults and linksResults
2234 and hostsResults and ipResult and
2235 hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002236
Jon Hallc9eabec2015-06-10 14:33:14 -07002237 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002238
Jon Hallc9eabec2015-06-10 14:33:14 -07002239 # hosts
2240 main.step( "Hosts view is consistent across all ONOS nodes" )
2241 consistentHostsResult = main.TRUE
2242 for controller in range( len( hosts ) ):
2243 controllerStr = str( controller + 1 )
2244 if "Error" not in hosts[ controller ]:
2245 if hosts[ controller ] == hosts[ 0 ]:
2246 continue
2247 else: # hosts not consistent
2248 main.log.error( "hosts from ONOS" + controllerStr +
2249 " is inconsistent with ONOS1" )
2250 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002251 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002252
Jon Hallc9eabec2015-06-10 14:33:14 -07002253 else:
2254 main.log.error( "Error in getting ONOS hosts from ONOS" +
2255 controllerStr )
2256 consistentHostsResult = main.FALSE
2257 main.log.warn( "ONOS" + controllerStr +
2258 " hosts response: " +
2259 repr( hosts[ controller ] ) )
2260 utilities.assert_equals(
2261 expect=main.TRUE,
2262 actual=consistentHostsResult,
2263 onpass="Hosts view is consistent across all ONOS nodes",
2264 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002265
Jon Hallc9eabec2015-06-10 14:33:14 -07002266 main.step( "Hosts information is correct" )
2267 hostsResults = hostsResults and ipResult
2268 utilities.assert_equals(
2269 expect=main.TRUE,
2270 actual=hostsResults,
2271 onpass="Host information is correct",
2272 onfail="Host information is incorrect" )
2273
2274 main.step( "Host attachment points to the network" )
2275 utilities.assert_equals(
2276 expect=True,
2277 actual=hostAttachmentResults,
2278 onpass="Hosts are correctly attached to the network",
2279 onfail="ONOS did not correctly attach hosts to the network" )
2280
2281 # Strongly connected clusters of devices
2282 main.step( "Clusters view is consistent across all ONOS nodes" )
2283 consistentClustersResult = main.TRUE
2284 for controller in range( len( clusters ) ):
2285 controllerStr = str( controller + 1 )
2286 if "Error" not in clusters[ controller ]:
2287 if clusters[ controller ] == clusters[ 0 ]:
2288 continue
2289 else: # clusters not consistent
2290 main.log.error( "clusters from ONOS" +
2291 controllerStr +
2292 " is inconsistent with ONOS1" )
Jon Hall21270ac2015-02-16 17:59:55 -08002293 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002294
Jon Hallc9eabec2015-06-10 14:33:14 -07002295 else:
2296 main.log.error( "Error in getting dataplane clusters " +
2297 "from ONOS" + controllerStr )
2298 consistentClustersResult = main.FALSE
2299 main.log.warn( "ONOS" + controllerStr +
2300 " clusters response: " +
2301 repr( clusters[ controller ] ) )
2302 utilities.assert_equals(
2303 expect=main.TRUE,
2304 actual=consistentClustersResult,
2305 onpass="Clusters view is consistent across all ONOS nodes",
2306 onfail="ONOS nodes have different views of clusters" )
2307
2308 main.step( "There is only one SCC" )
2309 # there should always only be one cluster
2310 try:
2311 numClusters = len( json.loads( clusters[ 0 ] ) )
2312 except ( ValueError, TypeError ):
2313 main.log.exception( "Error parsing clusters[0]: " +
2314 repr( clusters[0] ) )
2315 clusterResults = main.FALSE
2316 if numClusters == 1:
2317 clusterResults = main.TRUE
2318 utilities.assert_equals(
2319 expect=1,
2320 actual=numClusters,
2321 onpass="ONOS shows 1 SCC",
2322 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2323
Jon Hallafa8a472015-06-12 14:02:42 -07002324 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002325 and hostsResults and consistentHostsResult
2326 and consistentClustersResult and clusterResults
2327 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002328
Jon Hall21270ac2015-02-16 17:59:55 -08002329 topoResult = topoResult and int( count <= 2 )
2330 note = "note it takes about " + str( int( cliTime ) ) + \
2331 " seconds for the test to make all the cli calls to fetch " +\
2332 "the topology from each ONOS instance"
2333 main.log.info(
2334 "Very crass estimate for topology discovery/convergence( " +
2335 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2336 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002337
2338 main.step( "Device information is correct" )
2339 utilities.assert_equals(
2340 expect=main.TRUE,
2341 actual=devicesResults,
2342 onpass="Device information is correct",
2343 onfail="Device information is incorrect" )
2344
Jon Hallc9eabec2015-06-10 14:33:14 -07002345 main.step( "Links are correct" )
2346 utilities.assert_equals(
2347 expect=main.TRUE,
2348 actual=linksResults,
2349 onpass="Link are correct",
2350 onfail="Links are incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002351
Jon Hallafa8a472015-06-12 14:02:42 -07002352 main.step( "Hosts are correct" )
2353 utilities.assert_equals(
2354 expect=main.TRUE,
2355 actual=hostsResults,
2356 onpass="Hosts are correct",
2357 onfail="Hosts are incorrect" )
2358
Jon Halla9d26da2015-03-30 16:45:32 -07002359 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002360 main.step( "Checking ONOS nodes" )
2361 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002362 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002363 threads = []
2364 for i in range( numControllers ):
2365 t = main.Thread( target=CLIs[i].nodes,
2366 name="nodes-" + str( i ),
2367 args=[ ] )
2368 threads.append( t )
2369 t.start()
2370
2371 for t in threads:
2372 t.join()
2373 nodesOutput.append( t.result )
2374 ips = [ node.ip_address for node in nodes ]
2375 for i in nodesOutput:
2376 try:
2377 current = json.loads( i )
2378 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002379 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002380 if node['ip'] in ips: # node in nodes() output is in cell
2381 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002382 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002383 else:
2384 main.log.error( "Error in ONOS node availability" )
2385 main.log.error(
2386 json.dumps( current,
2387 sort_keys=True,
2388 indent=4,
2389 separators=( ',', ': ' ) ) )
2390 break
Jon Hall390696c2015-05-05 17:13:41 -07002391 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002392 except ( ValueError, TypeError ):
2393 main.log.error( "Error parsing nodes output" )
2394 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002395 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2396 onpass="Nodes check successful",
2397 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002398
Jon Hall6aec96b2015-01-19 14:49:31 -08002399 def CASE9( self, main ):
2400 """
Jon Hallb1290e82014-11-18 16:17:48 -05002401 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002402 """
2403 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002404 assert numControllers, "numControllers not defined"
2405 assert main, "main not defined"
2406 assert utilities.assert_equals, "utilities.assert_equals not defined"
2407 assert CLIs, "CLIs not defined"
2408 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002409 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002410
Jon Hall8f89dda2015-01-22 16:03:33 -08002411 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002412
Jon Hall6aec96b2015-01-19 14:49:31 -08002413 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002414 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002415 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002416
Jon Hall6aec96b2015-01-19 14:49:31 -08002417 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002418 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002419 main.log.info( "Waiting " + str( linkSleep ) +
2420 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002421 time.sleep( linkSleep )
2422 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002423 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002424 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002425 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002426
Jon Hall6aec96b2015-01-19 14:49:31 -08002427 def CASE10( self, main ):
2428 """
Jon Hallb1290e82014-11-18 16:17:48 -05002429 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002430 """
2431 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002432 assert numControllers, "numControllers not defined"
2433 assert main, "main not defined"
2434 assert utilities.assert_equals, "utilities.assert_equals not defined"
2435 assert CLIs, "CLIs not defined"
2436 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002437 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002438
Jon Hall8f89dda2015-01-22 16:03:33 -08002439 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002440
Jon Hall6aec96b2015-01-19 14:49:31 -08002441 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002442 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002443 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002444
Jon Hall6aec96b2015-01-19 14:49:31 -08002445 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002446 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002447 main.log.info( "Waiting " + str( linkSleep ) +
2448 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002449 time.sleep( linkSleep )
2450 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002451 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002452 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002453 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002454
Jon Hall6aec96b2015-01-19 14:49:31 -08002455 def CASE11( self, main ):
2456 """
Jon Hallb1290e82014-11-18 16:17:48 -05002457 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002458 """
2459 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002460 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002461 assert numControllers, "numControllers not defined"
2462 assert main, "main not defined"
2463 assert utilities.assert_equals, "utilities.assert_equals not defined"
2464 assert CLIs, "CLIs not defined"
2465 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002466
Jon Hall8f89dda2015-01-22 16:03:33 -08002467 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002468
2469 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002470 main.case( description )
2471 switch = main.params[ 'kill' ][ 'switch' ]
2472 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002473
Jon Hall6aec96b2015-01-19 14:49:31 -08002474 # TODO: Make this switch parameterizable
2475 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002476 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002477 main.Mininet1.delSwitch( switch )
2478 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002479 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002480 time.sleep( switchSleep )
2481 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002482 # Peek at the deleted switch
2483 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002484 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002485 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002486 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002487 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002488 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002489 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002490
Jon Hall6aec96b2015-01-19 14:49:31 -08002491 def CASE12( self, main ):
2492 """
Jon Hallb1290e82014-11-18 16:17:48 -05002493 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002494 """
2495 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002496 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002497 assert numControllers, "numControllers not defined"
2498 assert main, "main not defined"
2499 assert utilities.assert_equals, "utilities.assert_equals not defined"
2500 assert CLIs, "CLIs not defined"
2501 assert nodes, "nodes not defined"
2502 assert ONOS1Port, "ONOS1Port not defined"
2503 assert ONOS2Port, "ONOS2Port not defined"
2504 assert ONOS3Port, "ONOS3Port not defined"
2505 assert ONOS4Port, "ONOS4Port not defined"
2506 assert ONOS5Port, "ONOS5Port not defined"
2507 assert ONOS6Port, "ONOS6Port not defined"
2508 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002509
Jon Hall8f89dda2015-01-22 16:03:33 -08002510 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002511 switch = main.params[ 'kill' ][ 'switch' ]
2512 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2513 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002514 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002515 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002516
Jon Hall6aec96b2015-01-19 14:49:31 -08002517 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002518 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002519 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002520 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002521 ipList = []
2522 for i in range( numControllers ):
2523 ipList.append( nodes[ i ].ip_address )
2524 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002525 main.log.info( "Waiting " + str( switchSleep ) +
2526 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002527 time.sleep( switchSleep )
2528 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002529 # Peek at the deleted switch
2530 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002531 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002533 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002534 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002535 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002536 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002537
Jon Hall6aec96b2015-01-19 14:49:31 -08002538 def CASE13( self, main ):
2539 """
Jon Hallb1290e82014-11-18 16:17:48 -05002540 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002541 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002542 import os
2543 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002544 assert numControllers, "numControllers not defined"
2545 assert main, "main not defined"
2546 assert utilities.assert_equals, "utilities.assert_equals not defined"
2547 assert CLIs, "CLIs not defined"
2548 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002549
2550 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002551 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2552 'blue': '\033[94m', 'green': '\033[92m',
2553 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002554 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002556 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002557
Jon Hall6aec96b2015-01-19 14:49:31 -08002558 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002559 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002560 teststationUser = main.params[ 'TESTONUSER' ]
2561 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002562 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002563 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002564 # FIXME: scp
2565 # mn files
2566 # TODO: Load these from params
2567 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002568 logFolder = "/opt/onos/log/"
2569 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002570 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002571 dstDir = "~/packet_captures/"
2572 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002573 for node in nodes:
2574 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2575 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002576 teststationUser + "@" +
2577 teststationIP + ":" +
2578 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002579 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002580 main.ONOSbench.handle.expect( "\$" )
2581
Jon Hall6aec96b2015-01-19 14:49:31 -08002582 # std*.log's
2583 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002584 logFolder = "/opt/onos/var/"
2585 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002586 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002587 dstDir = "~/packet_captures/"
2588 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002589 for node in nodes:
2590 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2591 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002592 teststationUser + "@" +
2593 teststationIP + ":" +
2594 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002595 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002596 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002597 # sleep so scp can finish
2598 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002599
2600 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002601 mnResult = main.Mininet1.stopNet()
2602 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2603 onpass="Mininet stopped",
2604 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002605
2606 main.step( "Checking ONOS Logs for errors" )
2607 for node in nodes:
2608 print colors[ 'purple' ] + "Checking logs for errors on " + \
2609 node.name + ":" + colors[ 'end' ]
2610 print main.ONOSbench.checkLogs( node.ip_address )
2611
Jon Hall6aec96b2015-01-19 14:49:31 -08002612 main.step( "Packing and rotating pcap archives" )
2613 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002614
Jon Hall390696c2015-05-05 17:13:41 -07002615 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002616 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002617 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002618 labels = "Gossip Intents"
2619 data = str( gossipTime )
2620 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002621 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002622 except NameError, e:
2623 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002624
Jon Hall6aec96b2015-01-19 14:49:31 -08002625 def CASE14( self, main ):
2626 """
Jon Hall94fd0472014-12-08 11:52:42 -08002627 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002628 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002629 assert numControllers, "numControllers not defined"
2630 assert main, "main not defined"
2631 assert utilities.assert_equals, "utilities.assert_equals not defined"
2632 assert CLIs, "CLIs not defined"
2633 assert nodes, "nodes not defined"
2634
Jon Hall390696c2015-05-05 17:13:41 -07002635 main.case("Start Leadership Election app")
2636 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002637 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2638 utilities.assert_equals(
2639 expect=main.TRUE,
2640 actual=appResult,
2641 onpass="Election app installed",
2642 onfail="Something went wrong with installing Leadership election" )
2643
2644 main.step( "Run for election on each node" )
2645 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002646 leaders = []
2647 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002648 cli.electionTestRun()
2649 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002650 leader = cli.electionTestLeader()
2651 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002652 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002653 "should be an ONOS node, instead got '" +
2654 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002655 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002656 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002657 utilities.assert_equals(
2658 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002659 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002660 onpass="Successfully ran for leadership",
2661 onfail="Failed to run for leadership" )
2662
2663 main.step( "Check that each node shows the same leader" )
2664 sameLeader = main.TRUE
2665 if len( set( leaders ) ) != 1:
2666 sameLeader = main.FALSE
2667 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2668 str( leaders ) )
2669 utilities.assert_equals(
2670 expect=main.TRUE,
2671 actual=sameLeader,
2672 onpass="Leadership is consistent for the election topic",
2673 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002674
Jon Hall6aec96b2015-01-19 14:49:31 -08002675 def CASE15( self, main ):
2676 """
Jon Hall669173b2014-12-17 11:36:30 -08002677 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002678 """
Jon Hall390696c2015-05-05 17:13:41 -07002679 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002680 assert numControllers, "numControllers not defined"
2681 assert main, "main not defined"
2682 assert utilities.assert_equals, "utilities.assert_equals not defined"
2683 assert CLIs, "CLIs not defined"
2684 assert nodes, "nodes not defined"
2685
Jon Hall8f89dda2015-01-22 16:03:33 -08002686 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002687 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002688 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002689
2690 main.step( "Check that each node shows the same leader" )
2691 sameLeader = main.TRUE
2692 leaders = []
2693 for cli in CLIs:
2694 leader = cli.electionTestLeader()
2695 leaders.append( leader )
2696 if len( set( leaders ) ) != 1:
2697 sameLeader = main.FALSE
2698 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2699 str( leaders ) )
2700 utilities.assert_equals(
2701 expect=main.TRUE,
2702 actual=sameLeader,
2703 onpass="Leadership is consistent for the election topic",
2704 onfail="Nodes have different leaders" )
2705
Jon Hall6aec96b2015-01-19 14:49:31 -08002706 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002707 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002708 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002709 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002710 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002711 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002712 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002713 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002714 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002715 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002716 for i in range( len( CLIs ) ):
2717 if leader == nodes[ i ].ip_address:
2718 oldLeader = CLIs[ i ]
2719 break
Jon Halla9d26da2015-03-30 16:45:32 -07002720 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002721 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002722 if oldLeader:
2723 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002724 utilities.assert_equals(
2725 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002726 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002727 onpass="Node was withdrawn from election",
2728 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002729
Jon Hall6aec96b2015-01-19 14:49:31 -08002730 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002731 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002732 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002733 for cli in CLIs:
2734 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002735 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002736 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002737 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002738 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002739 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002740 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002741 # error in response
2742 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002743 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002744 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002745 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002746 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002747 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002748 elif leaderN is None:
2749 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002750 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002751 leaderN = cli.electionTestLeader()
2752 leaderList.pop()
2753 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002754 consistentLeader = main.FALSE
2755 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002756 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002757 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002758 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002759 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002760 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002761 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002762 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002763 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002764 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002765 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002766 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002767 utilities.assert_equals(
2768 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002769 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002770 onpass="Leadership election passed",
2771 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002772
Jon Hall58c76b72015-02-23 11:09:24 -08002773 main.step( "Run for election on old leader( just so everyone " +
2774 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002775 if oldLeader:
2776 runResult = oldLeader.electionTestRun()
2777 else:
2778 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002779 utilities.assert_equals(
2780 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002781 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002782 onpass="App re-ran for election",
2783 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002784
Jon Hallfeff3082015-05-19 10:23:26 -07002785 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002786 afterRun = main.ONOScli1.electionTestLeader()
2787 # verify leader didn't just change
2788 if afterRun == leaderList[ 0 ]:
2789 afterResult = main.TRUE
2790 else:
2791 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002792
Jon Hall6aec96b2015-01-19 14:49:31 -08002793 utilities.assert_equals(
2794 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002795 actual=afterResult,
2796 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002797 onfail="Something went wrong with Leadership election after " +
2798 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002799
Jon Hall390696c2015-05-05 17:13:41 -07002800 def CASE16( self, main ):
2801 """
2802 Install Distributed Primitives app
2803 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002804 import time
Jon Hall390696c2015-05-05 17:13:41 -07002805 assert numControllers, "numControllers not defined"
2806 assert main, "main not defined"
2807 assert utilities.assert_equals, "utilities.assert_equals not defined"
2808 assert CLIs, "CLIs not defined"
2809 assert nodes, "nodes not defined"
2810
2811 # Variables for the distributed primitives tests
2812 global pCounterName
2813 global iCounterName
2814 global pCounterValue
2815 global iCounterValue
2816 global onosSet
2817 global onosSetName
2818 pCounterName = "TestON-Partitions"
2819 iCounterName = "TestON-inMemory"
2820 pCounterValue = 0
2821 iCounterValue = 0
2822 onosSet = set([])
2823 onosSetName = "TestON-set"
2824
2825 description = "Install Primitives app"
2826 main.case( description )
2827 main.step( "Install Primitives app" )
2828 appName = "org.onosproject.distributedprimitives"
2829 appResults = CLIs[0].activateApp( appName )
2830 utilities.assert_equals( expect=main.TRUE,
2831 actual=appResults,
2832 onpass="Primitives app activated",
2833 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002834 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002835
2836 def CASE17( self, main ):
2837 """
2838 Check for basic functionality with distributed primitives
2839 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002840 import json
Jon Hall390696c2015-05-05 17:13:41 -07002841 # Make sure variables are defined/set
2842 assert numControllers, "numControllers not defined"
2843 assert main, "main not defined"
2844 assert utilities.assert_equals, "utilities.assert_equals not defined"
2845 assert CLIs, "CLIs not defined"
2846 assert nodes, "nodes not defined"
2847 assert pCounterName, "pCounterName not defined"
2848 assert iCounterName, "iCounterName not defined"
2849 assert onosSetName, "onosSetName not defined"
2850 # NOTE: assert fails if value is 0/None/Empty/False
2851 try:
2852 pCounterValue
2853 except NameError:
2854 main.log.error( "pCounterValue not defined, setting to 0" )
2855 pCounterValue = 0
2856 try:
2857 iCounterValue
2858 except NameError:
2859 main.log.error( "iCounterValue not defined, setting to 0" )
2860 iCounterValue = 0
2861 try:
2862 onosSet
2863 except NameError:
2864 main.log.error( "onosSet not defined, setting to empty Set" )
2865 onosSet = set([])
2866 # Variables for the distributed primitives tests. These are local only
2867 addValue = "a"
2868 addAllValue = "a b c d e f"
2869 retainValue = "c d e f"
2870
2871 description = "Check for basic functionality with distributed " +\
2872 "primitives"
2873 main.case( description )
2874 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2875 # DISTRIBUTED ATOMIC COUNTERS
2876 main.step( "Increment and get a default counter on each node" )
2877 pCounters = []
2878 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002879 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002880 for i in range( numControllers ):
2881 t = main.Thread( target=CLIs[i].counterTestIncrement,
2882 name="counterIncrement-" + str( i ),
2883 args=[ pCounterName ] )
2884 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002885 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002886 threads.append( t )
2887 t.start()
2888
2889 for t in threads:
2890 t.join()
2891 pCounters.append( t.result )
2892 # Check that counter incremented numController times
2893 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002894 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002895 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002896 pCounterResults = pCounterResults and tmpResult
2897 if not tmpResult:
2898 main.log.error( str( i ) + " is not in partitioned "
2899 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002900 utilities.assert_equals( expect=True,
2901 actual=pCounterResults,
2902 onpass="Default counter incremented",
2903 onfail="Error incrementing default" +
2904 " counter" )
2905
2906 main.step( "Increment and get an in memory counter on each node" )
2907 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002908 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002909 threads = []
2910 for i in range( numControllers ):
2911 t = main.Thread( target=CLIs[i].counterTestIncrement,
2912 name="icounterIncrement-" + str( i ),
2913 args=[ iCounterName ],
2914 kwargs={ "inMemory": True } )
2915 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002916 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002917 threads.append( t )
2918 t.start()
2919
2920 for t in threads:
2921 t.join()
2922 iCounters.append( t.result )
2923 # Check that counter incremented numController times
2924 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002925 for i in addedIValues:
2926 tmpResult = i in iCounters
2927 iCounterResults = iCounterResults and tmpResult
2928 if not tmpResult:
2929 main.log.error( str( i ) + " is not in the in-memory "
2930 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002931 utilities.assert_equals( expect=True,
2932 actual=iCounterResults,
2933 onpass="In memory counter incremented",
2934 onfail="Error incrementing in memory" +
2935 " counter" )
2936
2937 main.step( "Check counters are consistant across nodes" )
2938 onosCounters = []
2939 threads = []
2940 for i in range( numControllers ):
2941 t = main.Thread( target=CLIs[i].counters,
2942 name="counters-" + str( i ) )
2943 threads.append( t )
2944 t.start()
2945 for t in threads:
2946 t.join()
2947 onosCounters.append( t.result )
2948 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2949 if all( tmp ):
2950 main.log.info( "Counters are consistent across all nodes" )
2951 consistentCounterResults = main.TRUE
2952 else:
2953 main.log.error( "Counters are not consistent across all nodes" )
2954 consistentCounterResults = main.FALSE
2955 utilities.assert_equals( expect=main.TRUE,
2956 actual=consistentCounterResults,
2957 onpass="ONOS counters are consistent " +
2958 "across nodes",
2959 onfail="ONOS Counters are inconsistent " +
2960 "across nodes" )
2961
2962 main.step( "Counters we added have the correct values" )
2963 correctResults = main.TRUE
2964 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002965 current = json.loads( onosCounters[i] )
2966 pValue = None
2967 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002968 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002969 for database in current:
2970 partitioned = database.get( 'partitionedDatabaseCounters' )
2971 if partitioned:
2972 for value in partitioned:
2973 if value.get( 'name' ) == pCounterName:
2974 pValue = value.get( 'value' )
2975 break
2976 inMemory = database.get( 'inMemoryDatabaseCounters' )
2977 if inMemory:
2978 for value in inMemory:
2979 if value.get( 'name' ) == iCounterName:
2980 iValue = value.get( 'value' )
2981 break
Jon Hall390696c2015-05-05 17:13:41 -07002982 except AttributeError, e:
2983 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2984 "is not as expected" )
2985 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07002986 if pValue == pCounterValue:
2987 main.log.info( "Partitioned counter value is correct" )
2988 else:
2989 main.log.error( "Partitioned counter value is incorrect," +
2990 " expected value: " + str( pCounterValue )
2991 + " current value: " + str( pValue ) )
2992 correctResults = main.FALSE
2993 if iValue == iCounterValue:
2994 main.log.info( "In memory counter value is correct" )
2995 else:
2996 main.log.error( "In memory counter value is incorrect, " +
2997 "expected value: " + str( iCounterValue ) +
2998 " current value: " + str( iValue ) )
2999 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003000 utilities.assert_equals( expect=main.TRUE,
3001 actual=correctResults,
3002 onpass="Added counters are correct",
3003 onfail="Added counters are incorrect" )
3004 # DISTRIBUTED SETS
3005 main.step( "Distributed Set get" )
3006 size = len( onosSet )
3007 getResponses = []
3008 threads = []
3009 for i in range( numControllers ):
3010 t = main.Thread( target=CLIs[i].setTestGet,
3011 name="setTestGet-" + str( i ),
3012 args=[ onosSetName ] )
3013 threads.append( t )
3014 t.start()
3015 for t in threads:
3016 t.join()
3017 getResponses.append( t.result )
3018
3019 getResults = main.TRUE
3020 for i in range( numControllers ):
3021 if isinstance( getResponses[ i ], list):
3022 current = set( getResponses[ i ] )
3023 if len( current ) == len( getResponses[ i ] ):
3024 # no repeats
3025 if onosSet != current:
3026 main.log.error( "ONOS" + str( i + 1 ) +
3027 " has incorrect view" +
3028 " of set " + onosSetName + ":\n" +
3029 str( getResponses[ i ] ) )
3030 main.log.debug( "Expected: " + str( onosSet ) )
3031 main.log.debug( "Actual: " + str( current ) )
3032 getResults = main.FALSE
3033 else:
3034 # error, set is not a set
3035 main.log.error( "ONOS" + str( i + 1 ) +
3036 " has repeat elements in" +
3037 " set " + onosSetName + ":\n" +
3038 str( getResponses[ i ] ) )
3039 getResults = main.FALSE
3040 elif getResponses[ i ] == main.ERROR:
3041 getResults = main.FALSE
3042 utilities.assert_equals( expect=main.TRUE,
3043 actual=getResults,
3044 onpass="Set elements are correct",
3045 onfail="Set elements are incorrect" )
3046
3047 main.step( "Distributed Set size" )
3048 sizeResponses = []
3049 threads = []
3050 for i in range( numControllers ):
3051 t = main.Thread( target=CLIs[i].setTestSize,
3052 name="setTestSize-" + str( i ),
3053 args=[ onosSetName ] )
3054 threads.append( t )
3055 t.start()
3056 for t in threads:
3057 t.join()
3058 sizeResponses.append( t.result )
3059
3060 sizeResults = main.TRUE
3061 for i in range( numControllers ):
3062 if size != sizeResponses[ i ]:
3063 sizeResults = main.FALSE
3064 main.log.error( "ONOS" + str( i + 1 ) +
3065 " expected a size of " + str( size ) +
3066 " for set " + onosSetName +
3067 " but got " + str( sizeResponses[ i ] ) )
3068 utilities.assert_equals( expect=main.TRUE,
3069 actual=sizeResults,
3070 onpass="Set sizes are correct",
3071 onfail="Set sizes are incorrect" )
3072
3073 main.step( "Distributed Set add()" )
3074 onosSet.add( addValue )
3075 addResponses = []
3076 threads = []
3077 for i in range( numControllers ):
3078 t = main.Thread( target=CLIs[i].setTestAdd,
3079 name="setTestAdd-" + str( i ),
3080 args=[ onosSetName, addValue ] )
3081 threads.append( t )
3082 t.start()
3083 for t in threads:
3084 t.join()
3085 addResponses.append( t.result )
3086
3087 # main.TRUE = successfully changed the set
3088 # main.FALSE = action resulted in no change in set
3089 # main.ERROR - Some error in executing the function
3090 addResults = main.TRUE
3091 for i in range( numControllers ):
3092 if addResponses[ i ] == main.TRUE:
3093 # All is well
3094 pass
3095 elif addResponses[ i ] == main.FALSE:
3096 # Already in set, probably fine
3097 pass
3098 elif addResponses[ i ] == main.ERROR:
3099 # Error in execution
3100 addResults = main.FALSE
3101 else:
3102 # unexpected result
3103 addResults = main.FALSE
3104 if addResults != main.TRUE:
3105 main.log.error( "Error executing set add" )
3106
3107 # Check if set is still correct
3108 size = len( onosSet )
3109 getResponses = []
3110 threads = []
3111 for i in range( numControllers ):
3112 t = main.Thread( target=CLIs[i].setTestGet,
3113 name="setTestGet-" + str( i ),
3114 args=[ onosSetName ] )
3115 threads.append( t )
3116 t.start()
3117 for t in threads:
3118 t.join()
3119 getResponses.append( t.result )
3120 getResults = main.TRUE
3121 for i in range( numControllers ):
3122 if isinstance( getResponses[ i ], list):
3123 current = set( getResponses[ i ] )
3124 if len( current ) == len( getResponses[ i ] ):
3125 # no repeats
3126 if onosSet != current:
3127 main.log.error( "ONOS" + str( i + 1 ) +
3128 " has incorrect view" +
3129 " of set " + onosSetName + ":\n" +
3130 str( getResponses[ i ] ) )
3131 main.log.debug( "Expected: " + str( onosSet ) )
3132 main.log.debug( "Actual: " + str( current ) )
3133 getResults = main.FALSE
3134 else:
3135 # error, set is not a set
3136 main.log.error( "ONOS" + str( i + 1 ) +
3137 " has repeat elements in" +
3138 " set " + onosSetName + ":\n" +
3139 str( getResponses[ i ] ) )
3140 getResults = main.FALSE
3141 elif getResponses[ i ] == main.ERROR:
3142 getResults = main.FALSE
3143 sizeResponses = []
3144 threads = []
3145 for i in range( numControllers ):
3146 t = main.Thread( target=CLIs[i].setTestSize,
3147 name="setTestSize-" + str( i ),
3148 args=[ onosSetName ] )
3149 threads.append( t )
3150 t.start()
3151 for t in threads:
3152 t.join()
3153 sizeResponses.append( t.result )
3154 sizeResults = main.TRUE
3155 for i in range( numControllers ):
3156 if size != sizeResponses[ i ]:
3157 sizeResults = main.FALSE
3158 main.log.error( "ONOS" + str( i + 1 ) +
3159 " expected a size of " + str( size ) +
3160 " for set " + onosSetName +
3161 " but got " + str( sizeResponses[ i ] ) )
3162 addResults = addResults and getResults and sizeResults
3163 utilities.assert_equals( expect=main.TRUE,
3164 actual=addResults,
3165 onpass="Set add correct",
3166 onfail="Set add was incorrect" )
3167
3168 main.step( "Distributed Set addAll()" )
3169 onosSet.update( addAllValue.split() )
3170 addResponses = []
3171 threads = []
3172 for i in range( numControllers ):
3173 t = main.Thread( target=CLIs[i].setTestAdd,
3174 name="setTestAddAll-" + str( i ),
3175 args=[ onosSetName, addAllValue ] )
3176 threads.append( t )
3177 t.start()
3178 for t in threads:
3179 t.join()
3180 addResponses.append( t.result )
3181
3182 # main.TRUE = successfully changed the set
3183 # main.FALSE = action resulted in no change in set
3184 # main.ERROR - Some error in executing the function
3185 addAllResults = main.TRUE
3186 for i in range( numControllers ):
3187 if addResponses[ i ] == main.TRUE:
3188 # All is well
3189 pass
3190 elif addResponses[ i ] == main.FALSE:
3191 # Already in set, probably fine
3192 pass
3193 elif addResponses[ i ] == main.ERROR:
3194 # Error in execution
3195 addAllResults = main.FALSE
3196 else:
3197 # unexpected result
3198 addAllResults = main.FALSE
3199 if addAllResults != main.TRUE:
3200 main.log.error( "Error executing set addAll" )
3201
3202 # Check if set is still correct
3203 size = len( onosSet )
3204 getResponses = []
3205 threads = []
3206 for i in range( numControllers ):
3207 t = main.Thread( target=CLIs[i].setTestGet,
3208 name="setTestGet-" + str( i ),
3209 args=[ onosSetName ] )
3210 threads.append( t )
3211 t.start()
3212 for t in threads:
3213 t.join()
3214 getResponses.append( t.result )
3215 getResults = main.TRUE
3216 for i in range( numControllers ):
3217 if isinstance( getResponses[ i ], list):
3218 current = set( getResponses[ i ] )
3219 if len( current ) == len( getResponses[ i ] ):
3220 # no repeats
3221 if onosSet != current:
3222 main.log.error( "ONOS" + str( i + 1 ) +
3223 " has incorrect view" +
3224 " of set " + onosSetName + ":\n" +
3225 str( getResponses[ i ] ) )
3226 main.log.debug( "Expected: " + str( onosSet ) )
3227 main.log.debug( "Actual: " + str( current ) )
3228 getResults = main.FALSE
3229 else:
3230 # error, set is not a set
3231 main.log.error( "ONOS" + str( i + 1 ) +
3232 " has repeat elements in" +
3233 " set " + onosSetName + ":\n" +
3234 str( getResponses[ i ] ) )
3235 getResults = main.FALSE
3236 elif getResponses[ i ] == main.ERROR:
3237 getResults = main.FALSE
3238 sizeResponses = []
3239 threads = []
3240 for i in range( numControllers ):
3241 t = main.Thread( target=CLIs[i].setTestSize,
3242 name="setTestSize-" + str( i ),
3243 args=[ onosSetName ] )
3244 threads.append( t )
3245 t.start()
3246 for t in threads:
3247 t.join()
3248 sizeResponses.append( t.result )
3249 sizeResults = main.TRUE
3250 for i in range( numControllers ):
3251 if size != sizeResponses[ i ]:
3252 sizeResults = main.FALSE
3253 main.log.error( "ONOS" + str( i + 1 ) +
3254 " expected a size of " + str( size ) +
3255 " for set " + onosSetName +
3256 " but got " + str( sizeResponses[ i ] ) )
3257 addAllResults = addAllResults and getResults and sizeResults
3258 utilities.assert_equals( expect=main.TRUE,
3259 actual=addAllResults,
3260 onpass="Set addAll correct",
3261 onfail="Set addAll was incorrect" )
3262
3263 main.step( "Distributed Set contains()" )
3264 containsResponses = []
3265 threads = []
3266 for i in range( numControllers ):
3267 t = main.Thread( target=CLIs[i].setTestGet,
3268 name="setContains-" + str( i ),
3269 args=[ onosSetName ],
3270 kwargs={ "values": addValue } )
3271 threads.append( t )
3272 t.start()
3273 for t in threads:
3274 t.join()
3275 # NOTE: This is the tuple
3276 containsResponses.append( t.result )
3277
3278 containsResults = main.TRUE
3279 for i in range( numControllers ):
3280 if containsResponses[ i ] == main.ERROR:
3281 containsResults = main.FALSE
3282 else:
3283 containsResults = containsResults and\
3284 containsResponses[ i ][ 1 ]
3285 utilities.assert_equals( expect=main.TRUE,
3286 actual=containsResults,
3287 onpass="Set contains is functional",
3288 onfail="Set contains failed" )
3289
3290 main.step( "Distributed Set containsAll()" )
3291 containsAllResponses = []
3292 threads = []
3293 for i in range( numControllers ):
3294 t = main.Thread( target=CLIs[i].setTestGet,
3295 name="setContainsAll-" + str( i ),
3296 args=[ onosSetName ],
3297 kwargs={ "values": addAllValue } )
3298 threads.append( t )
3299 t.start()
3300 for t in threads:
3301 t.join()
3302 # NOTE: This is the tuple
3303 containsAllResponses.append( t.result )
3304
3305 containsAllResults = main.TRUE
3306 for i in range( numControllers ):
3307 if containsResponses[ i ] == main.ERROR:
3308 containsResults = main.FALSE
3309 else:
3310 containsResults = containsResults and\
3311 containsResponses[ i ][ 1 ]
3312 utilities.assert_equals( expect=main.TRUE,
3313 actual=containsAllResults,
3314 onpass="Set containsAll is functional",
3315 onfail="Set containsAll failed" )
3316
3317 main.step( "Distributed Set remove()" )
3318 onosSet.remove( addValue )
3319 removeResponses = []
3320 threads = []
3321 for i in range( numControllers ):
3322 t = main.Thread( target=CLIs[i].setTestRemove,
3323 name="setTestRemove-" + str( i ),
3324 args=[ onosSetName, addValue ] )
3325 threads.append( t )
3326 t.start()
3327 for t in threads:
3328 t.join()
3329 removeResponses.append( t.result )
3330
3331 # main.TRUE = successfully changed the set
3332 # main.FALSE = action resulted in no change in set
3333 # main.ERROR - Some error in executing the function
3334 removeResults = main.TRUE
3335 for i in range( numControllers ):
3336 if removeResponses[ i ] == main.TRUE:
3337 # All is well
3338 pass
3339 elif removeResponses[ i ] == main.FALSE:
3340 # not in set, probably fine
3341 pass
3342 elif removeResponses[ i ] == main.ERROR:
3343 # Error in execution
3344 removeResults = main.FALSE
3345 else:
3346 # unexpected result
3347 removeResults = main.FALSE
3348 if removeResults != main.TRUE:
3349 main.log.error( "Error executing set remove" )
3350
3351 # Check if set is still correct
3352 size = len( onosSet )
3353 getResponses = []
3354 threads = []
3355 for i in range( numControllers ):
3356 t = main.Thread( target=CLIs[i].setTestGet,
3357 name="setTestGet-" + str( i ),
3358 args=[ onosSetName ] )
3359 threads.append( t )
3360 t.start()
3361 for t in threads:
3362 t.join()
3363 getResponses.append( t.result )
3364 getResults = main.TRUE
3365 for i in range( numControllers ):
3366 if isinstance( getResponses[ i ], list):
3367 current = set( getResponses[ i ] )
3368 if len( current ) == len( getResponses[ i ] ):
3369 # no repeats
3370 if onosSet != current:
3371 main.log.error( "ONOS" + str( i + 1 ) +
3372 " has incorrect view" +
3373 " of set " + onosSetName + ":\n" +
3374 str( getResponses[ i ] ) )
3375 main.log.debug( "Expected: " + str( onosSet ) )
3376 main.log.debug( "Actual: " + str( current ) )
3377 getResults = main.FALSE
3378 else:
3379 # error, set is not a set
3380 main.log.error( "ONOS" + str( i + 1 ) +
3381 " has repeat elements in" +
3382 " set " + onosSetName + ":\n" +
3383 str( getResponses[ i ] ) )
3384 getResults = main.FALSE
3385 elif getResponses[ i ] == main.ERROR:
3386 getResults = main.FALSE
3387 sizeResponses = []
3388 threads = []
3389 for i in range( numControllers ):
3390 t = main.Thread( target=CLIs[i].setTestSize,
3391 name="setTestSize-" + str( i ),
3392 args=[ onosSetName ] )
3393 threads.append( t )
3394 t.start()
3395 for t in threads:
3396 t.join()
3397 sizeResponses.append( t.result )
3398 sizeResults = main.TRUE
3399 for i in range( numControllers ):
3400 if size != sizeResponses[ i ]:
3401 sizeResults = main.FALSE
3402 main.log.error( "ONOS" + str( i + 1 ) +
3403 " expected a size of " + str( size ) +
3404 " for set " + onosSetName +
3405 " but got " + str( sizeResponses[ i ] ) )
3406 removeResults = removeResults and getResults and sizeResults
3407 utilities.assert_equals( expect=main.TRUE,
3408 actual=removeResults,
3409 onpass="Set remove correct",
3410 onfail="Set remove was incorrect" )
3411
3412 main.step( "Distributed Set removeAll()" )
3413 onosSet.difference_update( addAllValue.split() )
3414 removeAllResponses = []
3415 threads = []
3416 try:
3417 for i in range( numControllers ):
3418 t = main.Thread( target=CLIs[i].setTestRemove,
3419 name="setTestRemoveAll-" + str( i ),
3420 args=[ onosSetName, addAllValue ] )
3421 threads.append( t )
3422 t.start()
3423 for t in threads:
3424 t.join()
3425 removeAllResponses.append( t.result )
3426 except Exception, e:
3427 main.log.exception(e)
3428
3429 # main.TRUE = successfully changed the set
3430 # main.FALSE = action resulted in no change in set
3431 # main.ERROR - Some error in executing the function
3432 removeAllResults = main.TRUE
3433 for i in range( numControllers ):
3434 if removeAllResponses[ i ] == main.TRUE:
3435 # All is well
3436 pass
3437 elif removeAllResponses[ i ] == main.FALSE:
3438 # not in set, probably fine
3439 pass
3440 elif removeAllResponses[ i ] == main.ERROR:
3441 # Error in execution
3442 removeAllResults = main.FALSE
3443 else:
3444 # unexpected result
3445 removeAllResults = main.FALSE
3446 if removeAllResults != main.TRUE:
3447 main.log.error( "Error executing set removeAll" )
3448
3449 # Check if set is still correct
3450 size = len( onosSet )
3451 getResponses = []
3452 threads = []
3453 for i in range( numControllers ):
3454 t = main.Thread( target=CLIs[i].setTestGet,
3455 name="setTestGet-" + str( i ),
3456 args=[ onosSetName ] )
3457 threads.append( t )
3458 t.start()
3459 for t in threads:
3460 t.join()
3461 getResponses.append( t.result )
3462 getResults = main.TRUE
3463 for i in range( numControllers ):
3464 if isinstance( getResponses[ i ], list):
3465 current = set( getResponses[ i ] )
3466 if len( current ) == len( getResponses[ i ] ):
3467 # no repeats
3468 if onosSet != current:
3469 main.log.error( "ONOS" + str( i + 1 ) +
3470 " has incorrect view" +
3471 " of set " + onosSetName + ":\n" +
3472 str( getResponses[ i ] ) )
3473 main.log.debug( "Expected: " + str( onosSet ) )
3474 main.log.debug( "Actual: " + str( current ) )
3475 getResults = main.FALSE
3476 else:
3477 # error, set is not a set
3478 main.log.error( "ONOS" + str( i + 1 ) +
3479 " has repeat elements in" +
3480 " set " + onosSetName + ":\n" +
3481 str( getResponses[ i ] ) )
3482 getResults = main.FALSE
3483 elif getResponses[ i ] == main.ERROR:
3484 getResults = main.FALSE
3485 sizeResponses = []
3486 threads = []
3487 for i in range( numControllers ):
3488 t = main.Thread( target=CLIs[i].setTestSize,
3489 name="setTestSize-" + str( i ),
3490 args=[ onosSetName ] )
3491 threads.append( t )
3492 t.start()
3493 for t in threads:
3494 t.join()
3495 sizeResponses.append( t.result )
3496 sizeResults = main.TRUE
3497 for i in range( numControllers ):
3498 if size != sizeResponses[ i ]:
3499 sizeResults = main.FALSE
3500 main.log.error( "ONOS" + str( i + 1 ) +
3501 " expected a size of " + str( size ) +
3502 " for set " + onosSetName +
3503 " but got " + str( sizeResponses[ i ] ) )
3504 removeAllResults = removeAllResults and getResults and sizeResults
3505 utilities.assert_equals( expect=main.TRUE,
3506 actual=removeAllResults,
3507 onpass="Set removeAll correct",
3508 onfail="Set removeAll was incorrect" )
3509
3510 main.step( "Distributed Set addAll()" )
3511 onosSet.update( addAllValue.split() )
3512 addResponses = []
3513 threads = []
3514 for i in range( numControllers ):
3515 t = main.Thread( target=CLIs[i].setTestAdd,
3516 name="setTestAddAll-" + str( i ),
3517 args=[ onosSetName, addAllValue ] )
3518 threads.append( t )
3519 t.start()
3520 for t in threads:
3521 t.join()
3522 addResponses.append( t.result )
3523
3524 # main.TRUE = successfully changed the set
3525 # main.FALSE = action resulted in no change in set
3526 # main.ERROR - Some error in executing the function
3527 addAllResults = main.TRUE
3528 for i in range( numControllers ):
3529 if addResponses[ i ] == main.TRUE:
3530 # All is well
3531 pass
3532 elif addResponses[ i ] == main.FALSE:
3533 # Already in set, probably fine
3534 pass
3535 elif addResponses[ i ] == main.ERROR:
3536 # Error in execution
3537 addAllResults = main.FALSE
3538 else:
3539 # unexpected result
3540 addAllResults = main.FALSE
3541 if addAllResults != main.TRUE:
3542 main.log.error( "Error executing set addAll" )
3543
3544 # Check if set is still correct
3545 size = len( onosSet )
3546 getResponses = []
3547 threads = []
3548 for i in range( numControllers ):
3549 t = main.Thread( target=CLIs[i].setTestGet,
3550 name="setTestGet-" + str( i ),
3551 args=[ onosSetName ] )
3552 threads.append( t )
3553 t.start()
3554 for t in threads:
3555 t.join()
3556 getResponses.append( t.result )
3557 getResults = main.TRUE
3558 for i in range( numControllers ):
3559 if isinstance( getResponses[ i ], list):
3560 current = set( getResponses[ i ] )
3561 if len( current ) == len( getResponses[ i ] ):
3562 # no repeats
3563 if onosSet != current:
3564 main.log.error( "ONOS" + str( i + 1 ) +
3565 " has incorrect view" +
3566 " of set " + onosSetName + ":\n" +
3567 str( getResponses[ i ] ) )
3568 main.log.debug( "Expected: " + str( onosSet ) )
3569 main.log.debug( "Actual: " + str( current ) )
3570 getResults = main.FALSE
3571 else:
3572 # error, set is not a set
3573 main.log.error( "ONOS" + str( i + 1 ) +
3574 " has repeat elements in" +
3575 " set " + onosSetName + ":\n" +
3576 str( getResponses[ i ] ) )
3577 getResults = main.FALSE
3578 elif getResponses[ i ] == main.ERROR:
3579 getResults = main.FALSE
3580 sizeResponses = []
3581 threads = []
3582 for i in range( numControllers ):
3583 t = main.Thread( target=CLIs[i].setTestSize,
3584 name="setTestSize-" + str( i ),
3585 args=[ onosSetName ] )
3586 threads.append( t )
3587 t.start()
3588 for t in threads:
3589 t.join()
3590 sizeResponses.append( t.result )
3591 sizeResults = main.TRUE
3592 for i in range( numControllers ):
3593 if size != sizeResponses[ i ]:
3594 sizeResults = main.FALSE
3595 main.log.error( "ONOS" + str( i + 1 ) +
3596 " expected a size of " + str( size ) +
3597 " for set " + onosSetName +
3598 " but got " + str( sizeResponses[ i ] ) )
3599 addAllResults = addAllResults and getResults and sizeResults
3600 utilities.assert_equals( expect=main.TRUE,
3601 actual=addAllResults,
3602 onpass="Set addAll correct",
3603 onfail="Set addAll was incorrect" )
3604
3605 main.step( "Distributed Set clear()" )
3606 onosSet.clear()
3607 clearResponses = []
3608 threads = []
3609 for i in range( numControllers ):
3610 t = main.Thread( target=CLIs[i].setTestRemove,
3611 name="setTestClear-" + str( i ),
3612 args=[ onosSetName, " "], # Values doesn't matter
3613 kwargs={ "clear": True } )
3614 threads.append( t )
3615 t.start()
3616 for t in threads:
3617 t.join()
3618 clearResponses.append( t.result )
3619
3620 # main.TRUE = successfully changed the set
3621 # main.FALSE = action resulted in no change in set
3622 # main.ERROR - Some error in executing the function
3623 clearResults = main.TRUE
3624 for i in range( numControllers ):
3625 if clearResponses[ i ] == main.TRUE:
3626 # All is well
3627 pass
3628 elif clearResponses[ i ] == main.FALSE:
3629 # Nothing set, probably fine
3630 pass
3631 elif clearResponses[ i ] == main.ERROR:
3632 # Error in execution
3633 clearResults = main.FALSE
3634 else:
3635 # unexpected result
3636 clearResults = main.FALSE
3637 if clearResults != main.TRUE:
3638 main.log.error( "Error executing set clear" )
3639
3640 # Check if set is still correct
3641 size = len( onosSet )
3642 getResponses = []
3643 threads = []
3644 for i in range( numControllers ):
3645 t = main.Thread( target=CLIs[i].setTestGet,
3646 name="setTestGet-" + str( i ),
3647 args=[ onosSetName ] )
3648 threads.append( t )
3649 t.start()
3650 for t in threads:
3651 t.join()
3652 getResponses.append( t.result )
3653 getResults = main.TRUE
3654 for i in range( numControllers ):
3655 if isinstance( getResponses[ i ], list):
3656 current = set( getResponses[ i ] )
3657 if len( current ) == len( getResponses[ i ] ):
3658 # no repeats
3659 if onosSet != current:
3660 main.log.error( "ONOS" + str( i + 1 ) +
3661 " has incorrect view" +
3662 " of set " + onosSetName + ":\n" +
3663 str( getResponses[ i ] ) )
3664 main.log.debug( "Expected: " + str( onosSet ) )
3665 main.log.debug( "Actual: " + str( current ) )
3666 getResults = main.FALSE
3667 else:
3668 # error, set is not a set
3669 main.log.error( "ONOS" + str( i + 1 ) +
3670 " has repeat elements in" +
3671 " set " + onosSetName + ":\n" +
3672 str( getResponses[ i ] ) )
3673 getResults = main.FALSE
3674 elif getResponses[ i ] == main.ERROR:
3675 getResults = main.FALSE
3676 sizeResponses = []
3677 threads = []
3678 for i in range( numControllers ):
3679 t = main.Thread( target=CLIs[i].setTestSize,
3680 name="setTestSize-" + str( i ),
3681 args=[ onosSetName ] )
3682 threads.append( t )
3683 t.start()
3684 for t in threads:
3685 t.join()
3686 sizeResponses.append( t.result )
3687 sizeResults = main.TRUE
3688 for i in range( numControllers ):
3689 if size != sizeResponses[ i ]:
3690 sizeResults = main.FALSE
3691 main.log.error( "ONOS" + str( i + 1 ) +
3692 " expected a size of " + str( size ) +
3693 " for set " + onosSetName +
3694 " but got " + str( sizeResponses[ i ] ) )
3695 clearResults = clearResults and getResults and sizeResults
3696 utilities.assert_equals( expect=main.TRUE,
3697 actual=clearResults,
3698 onpass="Set clear correct",
3699 onfail="Set clear was incorrect" )
3700
3701 main.step( "Distributed Set addAll()" )
3702 onosSet.update( addAllValue.split() )
3703 addResponses = []
3704 threads = []
3705 for i in range( numControllers ):
3706 t = main.Thread( target=CLIs[i].setTestAdd,
3707 name="setTestAddAll-" + str( i ),
3708 args=[ onosSetName, addAllValue ] )
3709 threads.append( t )
3710 t.start()
3711 for t in threads:
3712 t.join()
3713 addResponses.append( t.result )
3714
3715 # main.TRUE = successfully changed the set
3716 # main.FALSE = action resulted in no change in set
3717 # main.ERROR - Some error in executing the function
3718 addAllResults = main.TRUE
3719 for i in range( numControllers ):
3720 if addResponses[ i ] == main.TRUE:
3721 # All is well
3722 pass
3723 elif addResponses[ i ] == main.FALSE:
3724 # Already in set, probably fine
3725 pass
3726 elif addResponses[ i ] == main.ERROR:
3727 # Error in execution
3728 addAllResults = main.FALSE
3729 else:
3730 # unexpected result
3731 addAllResults = main.FALSE
3732 if addAllResults != main.TRUE:
3733 main.log.error( "Error executing set addAll" )
3734
3735 # Check if set is still correct
3736 size = len( onosSet )
3737 getResponses = []
3738 threads = []
3739 for i in range( numControllers ):
3740 t = main.Thread( target=CLIs[i].setTestGet,
3741 name="setTestGet-" + str( i ),
3742 args=[ onosSetName ] )
3743 threads.append( t )
3744 t.start()
3745 for t in threads:
3746 t.join()
3747 getResponses.append( t.result )
3748 getResults = main.TRUE
3749 for i in range( numControllers ):
3750 if isinstance( getResponses[ i ], list):
3751 current = set( getResponses[ i ] )
3752 if len( current ) == len( getResponses[ i ] ):
3753 # no repeats
3754 if onosSet != current:
3755 main.log.error( "ONOS" + str( i + 1 ) +
3756 " has incorrect view" +
3757 " of set " + onosSetName + ":\n" +
3758 str( getResponses[ i ] ) )
3759 main.log.debug( "Expected: " + str( onosSet ) )
3760 main.log.debug( "Actual: " + str( current ) )
3761 getResults = main.FALSE
3762 else:
3763 # error, set is not a set
3764 main.log.error( "ONOS" + str( i + 1 ) +
3765 " has repeat elements in" +
3766 " set " + onosSetName + ":\n" +
3767 str( getResponses[ i ] ) )
3768 getResults = main.FALSE
3769 elif getResponses[ i ] == main.ERROR:
3770 getResults = main.FALSE
3771 sizeResponses = []
3772 threads = []
3773 for i in range( numControllers ):
3774 t = main.Thread( target=CLIs[i].setTestSize,
3775 name="setTestSize-" + str( i ),
3776 args=[ onosSetName ] )
3777 threads.append( t )
3778 t.start()
3779 for t in threads:
3780 t.join()
3781 sizeResponses.append( t.result )
3782 sizeResults = main.TRUE
3783 for i in range( numControllers ):
3784 if size != sizeResponses[ i ]:
3785 sizeResults = main.FALSE
3786 main.log.error( "ONOS" + str( i + 1 ) +
3787 " expected a size of " + str( size ) +
3788 " for set " + onosSetName +
3789 " but got " + str( sizeResponses[ i ] ) )
3790 addAllResults = addAllResults and getResults and sizeResults
3791 utilities.assert_equals( expect=main.TRUE,
3792 actual=addAllResults,
3793 onpass="Set addAll correct",
3794 onfail="Set addAll was incorrect" )
3795
3796 main.step( "Distributed Set retain()" )
3797 onosSet.intersection_update( retainValue.split() )
3798 retainResponses = []
3799 threads = []
3800 for i in range( numControllers ):
3801 t = main.Thread( target=CLIs[i].setTestRemove,
3802 name="setTestRetain-" + str( i ),
3803 args=[ onosSetName, retainValue ],
3804 kwargs={ "retain": True } )
3805 threads.append( t )
3806 t.start()
3807 for t in threads:
3808 t.join()
3809 retainResponses.append( t.result )
3810
3811 # main.TRUE = successfully changed the set
3812 # main.FALSE = action resulted in no change in set
3813 # main.ERROR - Some error in executing the function
3814 retainResults = main.TRUE
3815 for i in range( numControllers ):
3816 if retainResponses[ i ] == main.TRUE:
3817 # All is well
3818 pass
3819 elif retainResponses[ i ] == main.FALSE:
3820 # Already in set, probably fine
3821 pass
3822 elif retainResponses[ i ] == main.ERROR:
3823 # Error in execution
3824 retainResults = main.FALSE
3825 else:
3826 # unexpected result
3827 retainResults = main.FALSE
3828 if retainResults != main.TRUE:
3829 main.log.error( "Error executing set retain" )
3830
3831 # Check if set is still correct
3832 size = len( onosSet )
3833 getResponses = []
3834 threads = []
3835 for i in range( numControllers ):
3836 t = main.Thread( target=CLIs[i].setTestGet,
3837 name="setTestGet-" + str( i ),
3838 args=[ onosSetName ] )
3839 threads.append( t )
3840 t.start()
3841 for t in threads:
3842 t.join()
3843 getResponses.append( t.result )
3844 getResults = main.TRUE
3845 for i in range( numControllers ):
3846 if isinstance( getResponses[ i ], list):
3847 current = set( getResponses[ i ] )
3848 if len( current ) == len( getResponses[ i ] ):
3849 # no repeats
3850 if onosSet != current:
3851 main.log.error( "ONOS" + str( i + 1 ) +
3852 " has incorrect view" +
3853 " of set " + onosSetName + ":\n" +
3854 str( getResponses[ i ] ) )
3855 main.log.debug( "Expected: " + str( onosSet ) )
3856 main.log.debug( "Actual: " + str( current ) )
3857 getResults = main.FALSE
3858 else:
3859 # error, set is not a set
3860 main.log.error( "ONOS" + str( i + 1 ) +
3861 " has repeat elements in" +
3862 " set " + onosSetName + ":\n" +
3863 str( getResponses[ i ] ) )
3864 getResults = main.FALSE
3865 elif getResponses[ i ] == main.ERROR:
3866 getResults = main.FALSE
3867 sizeResponses = []
3868 threads = []
3869 for i in range( numControllers ):
3870 t = main.Thread( target=CLIs[i].setTestSize,
3871 name="setTestSize-" + str( i ),
3872 args=[ onosSetName ] )
3873 threads.append( t )
3874 t.start()
3875 for t in threads:
3876 t.join()
3877 sizeResponses.append( t.result )
3878 sizeResults = main.TRUE
3879 for i in range( numControllers ):
3880 if size != sizeResponses[ i ]:
3881 sizeResults = main.FALSE
3882 main.log.error( "ONOS" + str( i + 1 ) +
3883 " expected a size of " +
3884 str( size ) + " for set " + onosSetName +
3885 " but got " + str( sizeResponses[ i ] ) )
3886 retainResults = retainResults and getResults and sizeResults
3887 utilities.assert_equals( expect=main.TRUE,
3888 actual=retainResults,
3889 onpass="Set retain correct",
3890 onfail="Set retain was incorrect" )
3891