blob: 8bc21b04556bb8d1192684657f8616c3fca898a5 [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
8CASE2: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall368769f2014-11-19 15:43:35 -080013CASE7: Check state after control plane failure
Jon Hallb1290e82014-11-18 16:17:48 -050014CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080020CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070022CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080024"""
Jon Hall8f89dda2015-01-22 16:03:33 -080025
26
Jon Hallb1290e82014-11-18 16:17:48 -050027class HATestSanity:
28
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def __init__( self ):
Jon Hallb1290e82014-11-18 16:17:48 -050030 self.default = ''
31
Jon Hall6aec96b2015-01-19 14:49:31 -080032 def CASE1( self, main ):
33 """
Jon Hallb1290e82014-11-18 16:17:48 -050034 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
Jon Hallb1290e82014-11-18 16:17:48 -050037 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080040 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
Jon Hallb1290e82014-11-18 16:17:48 -050045 onos-install -f
46 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080047 start cli sessions
48 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080049 """
50 main.log.report( "ONOS HA Sanity test - initialization" )
51 main.case( "Setting up test environment" )
52 # TODO: save all the timers and output them for plotting
Jon Hallb1290e82014-11-18 16:17:48 -050053
Jon Hall65844a32015-03-09 19:09:37 -070054 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080055 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080056 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080057 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080058 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080059 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080060
61 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080062 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080063 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080064 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS7Port
69 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080070 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall5cfd23c2015-03-19 11:40:57 -070071
Jon Hall65844a32015-03-09 19:09:37 -070072 # FIXME: just get controller port from params?
73 # TODO: do we really need all these?
74 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
75 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
76 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
77 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
78 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
79 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
80 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
81
82 global CLIs
83 CLIs = []
84 global nodes
85 nodes = []
86 for i in range( 1, numControllers + 1 ):
87 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
88 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -050089
Jon Hall6aec96b2015-01-19 14:49:31 -080090 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080091 cellResult = main.ONOSbench.setCell( cellName )
92 verifyResult = main.ONOSbench.verifyCell()
Jon Hall368769f2014-11-19 15:43:35 -080093
Jon Hall6aec96b2015-01-19 14:49:31 -080094 # FIXME:this is short term fix
95 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080096 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall65844a32015-03-09 19:09:37 -070097
Jon Hall6aec96b2015-01-19 14:49:31 -080098 main.log.report( "Uninstalling ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -070099 for node in nodes:
100 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hallb1290e82014-11-18 16:17:48 -0500101
Jon Hall390696c2015-05-05 17:13:41 -0700102 # Make sure ONOS is DEAD
103 main.log.report( "Killing any ONOS processes" )
104 killResults = main.TRUE
105 for node in nodes:
106 killed = main.ONOSbench.onosKill( node.ip_address )
107 killResults = killResults and killed
108
Jon Hall8f89dda2015-01-22 16:03:33 -0800109 cleanInstallResult = main.TRUE
110 gitPullResult = main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -0500111
Jon Hall97f31752015-02-04 12:01:04 -0800112 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700113 mnResult = main.Mininet1.startNet( )
114 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
115 onpass="Mininet Started",
116 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800117
Jon Hall6aec96b2015-01-19 14:49:31 -0800118 main.step( "Compiling the latest version of ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800119 if PULLCODE:
Jon Hall58c76b72015-02-23 11:09:24 -0800120 main.step( "Git checkout and pull " + gitBranch )
Jon Hall529a37f2015-01-28 10:02:00 -0800121 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700123 # values of 1 or 3 are good
124 utilities.assert_lesser( expect=0, actual=gitPullResult,
125 onpass="Git pull successful",
126 onfail="Git pull failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500127
Jon Hall390696c2015-05-05 17:13:41 -0700128 main.step( "Using mvn clean and install" )
Jon Hall529a37f2015-01-28 10:02:00 -0800129 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall390696c2015-05-05 17:13:41 -0700130 utilities.assert_equals( expect=main.TRUE,
131 actual=cleanInstallResult,
132 onpass="MCI successful",
133 onfail="MCI failed" )
Jon Hall529a37f2015-01-28 10:02:00 -0800134 else:
135 main.log.warn( "Did not pull new code so skipping mvn " +
136 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800137 main.ONOSbench.getVersion( report=True )
Jon Hall390696c2015-05-05 17:13:41 -0700138 # GRAPHS
139 # NOTE: important params here:
140 # job = name of Jenkins job
141 # Plot Name = Plot-HA, only can be used if multiple plots
142 # index = The number of the graph under plot name
143 job = "HASanity"
144 plotName = "Plot-HA"
145 graphs = '<ac:structured-macro ac:name="html">\n'
146 graphs += '<ac:plain-text-body><![CDATA[\n'
147 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
148 '/plot/' + plotName + '/getPlot?index=0' +\
149 '&width=500&height=300"' +\
150 'noborder="0" width="500" height="300" scrolling="yes" ' +\
151 'seamless="seamless"></iframe>\n'
152 graphs += ']]></ac:plain-text-body>\n'
153 graphs += '</ac:structured-macro>\n'
154 main.log.wiki(graphs)
Jon Hallb1290e82014-11-18 16:17:48 -0500155
Jon Hall6aec96b2015-01-19 14:49:31 -0800156 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800157 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700158 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
159 onpass="ONOS package successful",
160 onfail="ONOS package failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500161
Jon Hall6aec96b2015-01-19 14:49:31 -0800162 main.step( "Installing ONOS package" )
Jon Hall65844a32015-03-09 19:09:37 -0700163 onosInstallResult = main.TRUE
164 for node in nodes:
165 tmpResult = main.ONOSbench.onosInstall( options="-f",
166 node=node.ip_address )
167 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700168 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
169 onpass="ONOS install successful",
170 onfail="ONOS install failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500171
Jon Hall6aec96b2015-01-19 14:49:31 -0800172 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800173 for i in range( 2 ):
Jon Hall65844a32015-03-09 19:09:37 -0700174 onosIsupResult = main.TRUE
175 for node in nodes:
176 started = main.ONOSbench.isup( node.ip_address )
177 if not started:
178 main.log.report( node.name + " didn't start!" )
179 main.ONOSbench.onosStop( node.ip_address )
180 main.ONOSbench.onosStart( node.ip_address )
181 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800182 if onosIsupResult == main.TRUE:
Jon Hallffb386d2014-11-21 13:43:38 -0800183 break
Jon Hall390696c2015-05-05 17:13:41 -0700184 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
185 onpass="ONOS startup successful",
186 onfail="ONOS startup failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500187
Jon Hall65844a32015-03-09 19:09:37 -0700188 main.log.step( "Starting ONOS CLI sessions" )
189 cliResults = main.TRUE
190 threads = []
191 for i in range( numControllers ):
192 t = main.Thread( target=CLIs[i].startOnosCli,
Jon Hall65844a32015-03-09 19:09:37 -0700193 name="startOnosCli-" + str( i ),
194 args=[nodes[i].ip_address] )
195 threads.append( t )
196 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700197
198 for t in threads:
199 t.join()
200 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700201 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
202 onpass="ONOS cli startup successful",
203 onfail="ONOS cli startup failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500204
Jon Hall6aec96b2015-01-19 14:49:31 -0800205 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800206 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800207 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
208 + "-MN.pcap",
209 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
210 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hallb1290e82014-11-18 16:17:48 -0500211
Jon Hall390696c2015-05-05 17:13:41 -0700212 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700213 appCheck = main.TRUE
214 threads = []
215 for i in range( numControllers ):
216 t = main.Thread( target=CLIs[i].appToIDCheck,
217 name="appToIDCheck-" + str( i ),
218 args=[] )
219 threads.append( t )
220 t.start()
221
222 for t in threads:
223 t.join()
224 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700225 if appCheck != main.TRUE:
226 main.log.warn( CLIs[0].apps() )
227 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700228 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
229 onpass="App Ids seem to be correct",
230 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700231
Jon Hall8f89dda2015-01-22 16:03:33 -0800232 case1Result = ( cleanInstallResult and packageResult and
233 cellResult and verifyResult and onosInstallResult
Jon Hall390696c2015-05-05 17:13:41 -0700234 and onosIsupResult and cliResults )
Jon Hall8f89dda2015-01-22 16:03:33 -0800235 if case1Result == main.FALSE:
Jon Hallffb386d2014-11-21 13:43:38 -0800236 main.cleanup()
237 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -0500238
Jon Hall6aec96b2015-01-19 14:49:31 -0800239 def CASE2( self, main ):
240 """
Jon Hallb1290e82014-11-18 16:17:48 -0500241 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800242 """
Jon Hallb1290e82014-11-18 16:17:48 -0500243 import re
Jon Hall390696c2015-05-05 17:13:41 -0700244 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700245 assert numControllers, "numControllers not defined"
246 assert main, "main not defined"
247 assert utilities.assert_equals, "utilities.assert_equals not defined"
248 assert CLIs, "CLIs not defined"
249 assert nodes, "nodes not defined"
250 assert ONOS1Port, "ONOS1Port not defined"
251 assert ONOS2Port, "ONOS2Port not defined"
252 assert ONOS3Port, "ONOS3Port not defined"
253 assert ONOS4Port, "ONOS4Port not defined"
254 assert ONOS5Port, "ONOS5Port not defined"
255 assert ONOS6Port, "ONOS6Port not defined"
256 assert ONOS7Port, "ONOS7Port not defined"
Jon Hallb1290e82014-11-18 16:17:48 -0500257
Jon Hall6aec96b2015-01-19 14:49:31 -0800258 main.log.report( "Assigning switches to controllers" )
259 main.case( "Assigning Controllers" )
260 main.step( "Assign switches to controllers" )
Jon Hallb1290e82014-11-18 16:17:48 -0500261
Jon Hall65844a32015-03-09 19:09:37 -0700262 # TODO: rewrite this function to take lists of ips and ports?
263 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800264 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800265 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800266 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800267 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -0700268 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
269 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
270 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
271 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
272 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
273 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
274 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
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 Hall8f89dda2015-01-22 16:03:33 -0800291 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800292 main.log.report( "Switch mastership assigned correctly" )
293 utilities.assert_equals(
294 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800295 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800296 onpass="Switch mastership assigned correctly",
297 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700298
299 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800300 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800301 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700302
303 ipList = [ ]
304 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800305 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700306 for i in range( 1, 29 ): # switches 1 through 28
307 # set up correct variables:
308 if i == 1:
309 ip = nodes[ 0 ].ip_address # ONOS1
310 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
311 elif i == 2:
312 ip = nodes[ 1 ].ip_address # ONOS2
313 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
314 elif i == 3:
315 ip = nodes[ 1 ].ip_address # ONOS2
316 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
317 elif i == 4:
318 ip = nodes[ 3 ].ip_address # ONOS4
319 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
320 elif i == 5:
321 ip = nodes[ 2 ].ip_address # ONOS3
322 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
323 elif i == 6:
324 ip = nodes[ 2 ].ip_address # ONOS3
325 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
326 elif i == 7:
327 ip = nodes[ 5 ].ip_address # ONOS6
328 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
329 elif i >= 8 and i <= 17:
330 ip = nodes[ 4 ].ip_address # ONOS5
331 dpid = '3' + str( i ).zfill( 3 )
332 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
333 elif i >= 18 and i <= 27:
334 ip = nodes[ 6 ].ip_address # ONOS7
335 dpid = '6' + str( i ).zfill( 3 )
336 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
337 elif i == 28:
338 ip = nodes[ 0 ].ip_address # ONOS1
339 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
340 else:
341 main.log.error( "You didn't write an else statement for " +
342 "switch s" + str( i ) )
343 # Assign switch
344 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
345 # TODO: make this controller dynamic
346 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
347 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700348 ipList.append( ip )
349 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800350 except ( AttributeError, AssertionError ):
351 main.log.exception( "Something is wrong with ONOS device view" )
352 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800353 utilities.assert_equals(
354 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800355 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800356 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800357 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800358
Jon Hall390696c2015-05-05 17:13:41 -0700359 main.step( "Check mastership was correctly assigned" )
360 roleCheck = main.TRUE
361 # NOTE: This is due to the fact that device mastership change is not
362 # atomic and is actually a multi step process
363 time.sleep( 5 )
364 for i in range( len( ipList ) ):
365 ip = ipList[i]
366 deviceId = deviceList[i]
367 # Check assignment
368 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
369 if ip in master:
370 roleCheck = roleCheck and main.TRUE
371 else:
372 roleCheck = roleCheck and main.FALSE
373 main.log.error( "Error, controller " + ip + " is not" +
374 " master " + "of device " +
375 str( deviceId ) + ". Master is " +
376 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800377 utilities.assert_equals(
378 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800379 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800380 onpass="Switches were successfully reassigned to designated " +
381 "controller",
382 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800383 mastershipCheck = mastershipCheck and roleCall and roleCheck
384 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 onpass="Switch mastership correctly assigned",
386 onfail="Error in (re)assigning switch" +
Jon Hall8f89dda2015-01-22 16:03:33 -0800387 " mastership" )
Jon Hallb1290e82014-11-18 16:17:48 -0500388
Jon Hall6aec96b2015-01-19 14:49:31 -0800389 def CASE3( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500390 """
391 Assign intents
Jon Hallb1290e82014-11-18 16:17:48 -0500392 """
393 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800394 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700395 assert numControllers, "numControllers not defined"
396 assert main, "main not defined"
397 assert utilities.assert_equals, "utilities.assert_equals not defined"
398 assert CLIs, "CLIs not defined"
399 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 main.log.report( "Adding host intents" )
401 main.case( "Adding host Intents" )
Jon Hallb1290e82014-11-18 16:17:48 -0500402
Jon Hall390696c2015-05-05 17:13:41 -0700403 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800404 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hallb1290e82014-11-18 16:17:48 -0500405
Jon Hall6aec96b2015-01-19 14:49:31 -0800406 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700407 main.step( "Install reactive forwarding app" )
408 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
409 utilities.assert_equals( expect=main.TRUE, actual=installResults,
410 onpass="Install fwd successful",
411 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700412
Jon Halla9d26da2015-03-30 16:45:32 -0700413 appCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700414 threads = []
415 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700416 t = main.Thread( target=CLIs[i].appToIDCheck,
417 name="appToIDCheck-" + str( i ),
418 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700419 threads.append( t )
420 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700421
422 for t in threads:
423 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700424 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700425 if appCheck != main.TRUE:
426 main.log.warn( CLIs[0].apps() )
427 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700428 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
429 onpass="App Ids seem to be correct",
430 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800431
Jon Hall6aec96b2015-01-19 14:49:31 -0800432 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800433 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700434 for i in range(2): # Retry if pingall fails first time
435 time1 = time.time()
436 pingResult = main.Mininet1.pingall()
437 utilities.assert_equals(
438 expect=main.TRUE,
439 actual=pingResult,
440 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700441 onfail="Reactive Pingall failed, " +
442 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700443 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700444 main.log.info( "Time for pingall: %2f seconds" %
445 ( time2 - time1 ) )
446 # timeout for fwd flows
447 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800448 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700449 main.step( "Uninstall reactive forwarding app" )
450 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
451 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
452 onpass="Uninstall fwd successful",
453 onfail="Uninstall fwd failed" )
454 main.step( "Check app ids check" )
Jon Hall65844a32015-03-09 19:09:37 -0700455 threads = []
456 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700457 t = main.Thread( target=CLIs[i].appToIDCheck,
458 name="appToIDCheck-" + str( i ),
459 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700460 threads.append( t )
461 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700462
463 for t in threads:
464 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700465 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700466 if appCheck != main.TRUE:
467 main.log.warn( CLIs[0].apps() )
468 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700469 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
470 onpass="App Ids seem to be correct",
471 onfail="Something is wrong with app Ids" )
Jon Hallb1290e82014-11-18 16:17:48 -0500472
Jon Hall5cfd23c2015-03-19 11:40:57 -0700473 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800474 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800475 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800476 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800477 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800478 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800479 for i in range( 8, 18 ):
480 main.log.info( "Adding host intent between h" + str( i ) +
481 " and h" + str( i + 10 ) )
482 host1 = "00:00:00:00:00:" + \
483 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
484 host2 = "00:00:00:00:00:" + \
485 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800486 # NOTE: getHost can return None
Jon Hall5cfd23c2015-03-19 11:40:57 -0700487 host1Dict = main.ONOScli1.getHost( host1 )
488 host2Dict = main.ONOScli1.getHost( host2 )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800489 host1Id = None
490 host2Id = None
491 if host1Dict and host2Dict:
492 host1Id = host1Dict.get( 'id', None )
493 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800494 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700495 nodeNum = ( i % 7 )
496 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800497 if tmpId:
498 main.log.info( "Added intent with id: " + tmpId )
499 intentIds.append( tmpId )
500 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700501 main.log.error( "addHostIntent returned: " +
502 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800503 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700504 main.log.error( "Error, getHost() failed for h" + str( i ) +
505 " and/or h" + str( i + 10 ) )
506 hosts = CLIs[ 0 ].hosts()
507 main.log.warn( "Hosts output: " )
508 try:
509 main.log.warn( json.dumps( json.loads( hosts ),
510 sort_keys=True,
511 indent=4,
512 separators=( ',', ': ' ) ) )
513 except ( ValueError, TypeError ):
514 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800515 hostResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700516 # FIXME: DEBUG
517 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800518 onosIds = main.ONOScli1.getAllIntentsId()
519 main.log.info( "Submitted intents: " + str( intentIds ) )
520 main.log.info( "Intents in ONOS: " + str( onosIds ) )
521 for intent in intentIds:
522 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700523 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800524 else:
525 intentAddResult = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700526 # FIXME: DEBUG
527 if intentAddResult:
528 intentStop = time.time()
529 else:
530 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800531 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800532 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800533 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -0700534 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800535 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
536 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700537 try:
538 for intent in json.loads( intents ):
539 state = intent.get( 'state', None )
540 if "INSTALLED" not in state:
541 installedCheck = False
542 intentId = intent.get( 'id', None )
543 intentStates.append( ( intentId, state ) )
544 except ( ValueError, TypeError ):
545 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800546 # add submitted intents not in the store
547 tmplist = [ i for i, s in intentStates ]
548 missingIntents = False
549 for i in intentIds:
550 if i not in tmplist:
551 intentStates.append( ( i, " - " ) )
552 missingIntents = True
553 intentStates.sort()
554 for i, s in intentStates:
555 count += 1
556 main.log.info( "%-6s%-15s%-15s" %
557 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700558 leaders = main.ONOScli1.leaders()
559 try:
560 if leaders:
561 parsedLeaders = json.loads( leaders )
562 main.log.warn( json.dumps( parsedLeaders,
563 sort_keys=True,
564 indent=4,
565 separators=( ',', ': ' ) ) )
566 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700567 topics = []
568 for i in range( 14 ):
569 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700570 main.log.debug( topics )
571 ONOStopics = [ j['topic'] for j in parsedLeaders ]
572 for topic in topics:
573 if topic not in ONOStopics:
574 main.log.error( "Error: " + topic +
575 " not in leaders" )
576 else:
577 main.log.error( "leaders() returned None" )
578 except ( ValueError, TypeError ):
579 main.log.exception( "Error parsing leaders" )
580 main.log.error( repr( leaders ) )
581 partitions = main.ONOScli1.partitions()
582 try:
583 if partitions :
584 parsedPartitions = json.loads( partitions )
585 main.log.warn( json.dumps( parsedPartitions,
586 sort_keys=True,
587 indent=4,
588 separators=( ',', ': ' ) ) )
589 # TODO check for a leader in all paritions
590 # TODO check for consistency among nodes
591 else:
592 main.log.error( "partitions() returned None" )
593 except ( ValueError, TypeError ):
594 main.log.exception( "Error parsing partitions" )
595 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800596 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700597 try:
598 if pendingMap :
599 parsedPending = json.loads( pendingMap )
600 main.log.warn( json.dumps( parsedPending,
601 sort_keys=True,
602 indent=4,
603 separators=( ',', ': ' ) ) )
604 # TODO check something here?
605 else:
606 main.log.error( "pendingMap() returned None" )
607 except ( ValueError, TypeError ):
608 main.log.exception( "Error parsing pending map" )
609 main.log.error( repr( pendingMap ) )
610
Jon Hall58c76b72015-02-23 11:09:24 -0800611 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800612 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800613 utilities.assert_equals(
614 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800615 actual=intentAddResult,
616 onpass="Pushed host intents to ONOS",
617 onfail="Error in pushing host intents to ONOS" )
Jon Hall390696c2015-05-05 17:13:41 -0700618 main.step( "Intent Anti-Entropy dispersion" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700619 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700620 correct = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700621 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700622 for cli in CLIs:
623 onosIds = []
624 ids = cli.getAllIntentsId()
625 onosIds.append( ids )
626 main.log.debug( "Intents in " + cli.name + ": " +
627 str( sorted( onosIds ) ) )
628 if sorted( ids ) != sorted( intentIds ):
629 correct = False
630 if correct:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700631 break
632 else:
633 time.sleep(1)
Jon Hall5cfd23c2015-03-19 11:40:57 -0700634 if not intentStop:
635 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700636 global gossipTime
Jon Hall5cfd23c2015-03-19 11:40:57 -0700637 gossipTime = intentStop - intentStart
638 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700639 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700640 # FIXME: make this time configurable/calculate based off of number of
641 # nodes and gossip rounds
Jon Hall5cfd23c2015-03-19 11:40:57 -0700642 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700643 expect=40, actual=gossipTime,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700644 onpass="ECM anti-entropy for intents worked within " +
645 "expected time",
646 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700647 if gossipTime <= 40:
Jon Halla9d26da2015-03-30 16:45:32 -0700648 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800649
Jon Hall63604932015-02-26 17:09:50 -0800650 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800651 import time
Jon Hall63604932015-02-26 17:09:50 -0800652 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800653 main.log.info( "Sleeping 60 seconds to see if intents are found" )
654 time.sleep( 60 )
655 onosIds = main.ONOScli1.getAllIntentsId()
656 main.log.info( "Submitted intents: " + str( intentIds ) )
657 main.log.info( "Intents in ONOS: " + str( onosIds ) )
658 # Print the intent states
659 intents = main.ONOScli1.intents()
660 intentStates = []
661 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
662 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700663 try:
664 for intent in json.loads( intents ):
665 # Iter through intents of a node
666 state = intent.get( 'state', None )
667 if "INSTALLED" not in state:
668 installedCheck = False
669 intentId = intent.get( 'id', None )
670 intentStates.append( ( intentId, state ) )
671 except ( ValueError, TypeError ):
672 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800673 # add submitted intents not in the store
674 tmplist = [ i for i, s in intentStates ]
675 for i in intentIds:
676 if i not in tmplist:
677 intentStates.append( ( i, " - " ) )
678 intentStates.sort()
679 for i, s in intentStates:
680 count += 1
681 main.log.info( "%-6s%-15s%-15s" %
682 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700683 leaders = main.ONOScli1.leaders()
684 try:
685 if leaders:
686 parsedLeaders = json.loads( leaders )
687 main.log.warn( json.dumps( parsedLeaders,
688 sort_keys=True,
689 indent=4,
690 separators=( ',', ': ' ) ) )
691 # check for all intent partitions
692 # check for election
693 topics = []
694 for i in range( 14 ):
695 topics.append( "intent-partition-" + str( i ) )
696 # FIXME: this should only be after we start the app
697 topics.append( "org.onosproject.election" )
698 main.log.debug( topics )
699 ONOStopics = [ j['topic'] for j in parsedLeaders ]
700 for topic in topics:
701 if topic not in ONOStopics:
702 main.log.error( "Error: " + topic +
703 " not in leaders" )
704 else:
705 main.log.error( "leaders() returned None" )
706 except ( ValueError, TypeError ):
707 main.log.exception( "Error parsing leaders" )
708 main.log.error( repr( leaders ) )
709 partitions = main.ONOScli1.partitions()
710 try:
711 if partitions :
712 parsedPartitions = json.loads( partitions )
713 main.log.warn( json.dumps( parsedPartitions,
714 sort_keys=True,
715 indent=4,
716 separators=( ',', ': ' ) ) )
717 # TODO check for a leader in all paritions
718 # TODO check for consistency among nodes
719 else:
720 main.log.error( "partitions() returned None" )
721 except ( ValueError, TypeError ):
722 main.log.exception( "Error parsing partitions" )
723 main.log.error( repr( partitions ) )
724 pendingMap = main.ONOScli1.pendingMap()
725 try:
726 if pendingMap :
727 parsedPending = json.loads( pendingMap )
728 main.log.warn( json.dumps( parsedPending,
729 sort_keys=True,
730 indent=4,
731 separators=( ',', ': ' ) ) )
732 # TODO check something here?
733 else:
734 main.log.error( "pendingMap() returned None" )
735 except ( ValueError, TypeError ):
736 main.log.exception( "Error parsing pending map" )
737 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500738
Jon Hall6aec96b2015-01-19 14:49:31 -0800739 def CASE4( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500740 """
741 Ping across added host intents
742 """
Jon Hall58c76b72015-02-23 11:09:24 -0800743 import json
Jon Hall65844a32015-03-09 19:09:37 -0700744 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700745 assert numControllers, "numControllers not defined"
746 assert main, "main not defined"
747 assert utilities.assert_equals, "utilities.assert_equals not defined"
748 assert CLIs, "CLIs not defined"
749 assert nodes, "nodes not defined"
Jon Hall368769f2014-11-19 15:43:35 -0800750 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800751 main.log.report( description )
752 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800753 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800754 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800755 ping = main.Mininet1.pingHost( src="h" + str( i ),
756 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800757 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800758 if ping == main.FALSE:
759 main.log.warn( "Ping failed between h" + str( i ) +
760 " and h" + str( i + 10 ) )
761 elif ping == main.TRUE:
762 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800763 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800764 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800765 main.log.report(
766 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800767 # TODO: pretty print
Jon Hall65844a32015-03-09 19:09:37 -0700768 main.log.warn( "ONOS1 intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700769 try:
770 tmpIntents = main.ONOScli1.intents()
771 main.log.warn( json.dumps( json.loads( tmpIntents ),
772 sort_keys=True,
773 indent=4,
774 separators=( ',', ': ' ) ) )
775 except ( ValueError, TypeError ):
776 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800777 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800778 main.log.report(
779 "Intents have been installed correctly and verified by pings" )
780 utilities.assert_equals(
781 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800782 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800783 onpass="Intents have been installed correctly and pings work",
784 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallb1290e82014-11-18 16:17:48 -0500785
Jon Hall63604932015-02-26 17:09:50 -0800786 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800787 if PingResult is not main.TRUE:
788 # Print the intent states
789 intents = main.ONOScli1.intents()
790 intentStates = []
791 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
792 count = 0
793 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700794 try:
795 for intent in json.loads( intents ):
796 state = intent.get( 'state', None )
797 if "INSTALLED" not in state:
798 installedCheck = False
799 intentId = intent.get( 'id', None )
800 intentStates.append( ( intentId, state ) )
801 except ( ValueError, TypeError ):
802 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800803 intentStates.sort()
804 for i, s in intentStates:
805 count += 1
806 main.log.info( "%-6s%-15s%-15s" %
807 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700808 leaders = main.ONOScli1.leaders()
809 try:
810 if leaders:
811 parsedLeaders = json.loads( leaders )
812 main.log.warn( json.dumps( parsedLeaders,
813 sort_keys=True,
814 indent=4,
815 separators=( ',', ': ' ) ) )
816 # check for all intent partitions
817 # check for election
818 topics = []
819 for i in range( 14 ):
820 topics.append( "intent-partition-" + str( i ) )
821 # FIXME: this should only be after we start the app
822 topics.append( "org.onosproject.election" )
823 main.log.debug( topics )
824 ONOStopics = [ j['topic'] for j in parsedLeaders ]
825 for topic in topics:
826 if topic not in ONOStopics:
827 main.log.error( "Error: " + topic +
828 " not in leaders" )
829 else:
830 main.log.error( "leaders() returned None" )
831 except ( ValueError, TypeError ):
832 main.log.exception( "Error parsing leaders" )
833 main.log.error( repr( leaders ) )
834 partitions = main.ONOScli1.partitions()
835 try:
836 if partitions :
837 parsedPartitions = json.loads( partitions )
838 main.log.warn( json.dumps( parsedPartitions,
839 sort_keys=True,
840 indent=4,
841 separators=( ',', ': ' ) ) )
842 # TODO check for a leader in all paritions
843 # TODO check for consistency among nodes
844 else:
845 main.log.error( "partitions() returned None" )
846 except ( ValueError, TypeError ):
847 main.log.exception( "Error parsing partitions" )
848 main.log.error( repr( partitions ) )
849 pendingMap = main.ONOScli1.pendingMap()
850 try:
851 if pendingMap :
852 parsedPending = json.loads( pendingMap )
853 main.log.warn( json.dumps( parsedPending,
854 sort_keys=True,
855 indent=4,
856 separators=( ',', ': ' ) ) )
857 # TODO check something here?
858 else:
859 main.log.error( "pendingMap() returned None" )
860 except ( ValueError, TypeError ):
861 main.log.exception( "Error parsing pending map" )
862 main.log.error( repr( pendingMap ) )
863
Jon Hall63604932015-02-26 17:09:50 -0800864 if not installedCheck:
Jon Hall65844a32015-03-09 19:09:37 -0700865 main.log.info( "Waiting 60 seconds to see if the state of " +
866 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800867 time.sleep( 60 )
868 # Print the intent states
869 intents = main.ONOScli1.intents()
870 intentStates = []
871 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
872 count = 0
873 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700874 try:
875 for intent in json.loads( intents ):
876 state = intent.get( 'state', None )
877 if "INSTALLED" not in state:
878 installedCheck = False
879 intentId = intent.get( 'id', None )
880 intentStates.append( ( intentId, state ) )
881 except ( ValueError, TypeError ):
882 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800883 intentStates.sort()
884 for i, s in intentStates:
885 count += 1
886 main.log.info( "%-6s%-15s%-15s" %
887 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700888 leaders = main.ONOScli1.leaders()
889 try:
890 if leaders:
891 parsedLeaders = json.loads( leaders )
892 main.log.warn( json.dumps( parsedLeaders,
893 sort_keys=True,
894 indent=4,
895 separators=( ',', ': ' ) ) )
896 # check for all intent partitions
897 # check for election
898 topics = []
899 for i in range( 14 ):
900 topics.append( "intent-partition-" + str( i ) )
901 # FIXME: this should only be after we start the app
902 topics.append( "org.onosproject.election" )
903 main.log.debug( topics )
904 ONOStopics = [ j['topic'] for j in parsedLeaders ]
905 for topic in topics:
906 if topic not in ONOStopics:
907 main.log.error( "Error: " + topic +
908 " not in leaders" )
909 else:
910 main.log.error( "leaders() returned None" )
911 except ( ValueError, TypeError ):
912 main.log.exception( "Error parsing leaders" )
913 main.log.error( repr( leaders ) )
914 partitions = main.ONOScli1.partitions()
915 try:
916 if partitions :
917 parsedPartitions = json.loads( partitions )
918 main.log.warn( json.dumps( parsedPartitions,
919 sort_keys=True,
920 indent=4,
921 separators=( ',', ': ' ) ) )
922 # TODO check for a leader in all paritions
923 # TODO check for consistency among nodes
924 else:
925 main.log.error( "partitions() returned None" )
926 except ( ValueError, TypeError ):
927 main.log.exception( "Error parsing partitions" )
928 main.log.error( repr( partitions ) )
929 pendingMap = main.ONOScli1.pendingMap()
930 try:
931 if pendingMap :
932 parsedPending = json.loads( pendingMap )
933 main.log.warn( json.dumps( parsedPending,
934 sort_keys=True,
935 indent=4,
936 separators=( ',', ': ' ) ) )
937 # TODO check something here?
938 else:
939 main.log.error( "pendingMap() returned None" )
940 except ( ValueError, TypeError ):
941 main.log.exception( "Error parsing pending map" )
942 main.log.error( repr( pendingMap ) )
Jon Hall390696c2015-05-05 17:13:41 -0700943 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500944
Jon Hall6aec96b2015-01-19 14:49:31 -0800945 def CASE5( self, main ):
946 """
Jon Hallb1290e82014-11-18 16:17:48 -0500947 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800948 """
Jon Hallb1290e82014-11-18 16:17:48 -0500949 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700950 import time
951 assert numControllers, "numControllers not defined"
952 assert main, "main not defined"
953 assert utilities.assert_equals, "utilities.assert_equals not defined"
954 assert CLIs, "CLIs not defined"
955 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800956 # assumes that sts is already in you PYTHONPATH
957 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -0500958
Jon Hall6aec96b2015-01-19 14:49:31 -0800959 main.log.report( "Setting up and gathering data for current state" )
960 main.case( "Setting up and gathering data for current state" )
961 # The general idea for this test case is to pull the state of
962 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -0700963 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -0500964
Jon Hall65844a32015-03-09 19:09:37 -0700965 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800966 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700967 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800968
Jon Hall6aec96b2015-01-19 14:49:31 -0800969 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -0700970 rolesNotNull = main.TRUE
971 threads = []
972 for i in range( numControllers ):
973 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -0700974 name="rolesNotNull-" + str( i ),
975 args=[] )
976 threads.append( t )
977 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700978
979 for t in threads:
980 t.join()
981 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800982 utilities.assert_equals(
983 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800984 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800985 onpass="Each device has a master",
986 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800987
Jon Hall65844a32015-03-09 19:09:37 -0700988 main.step( "Get the Mastership of each switch from each controller" )
989 ONOSMastership = []
990 mastershipCheck = main.FALSE
991 consistentMastership = True
992 rolesResults = True
993 threads = []
994 for i in range( numControllers ):
995 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -0700996 name="roles-" + str( i ),
997 args=[] )
998 threads.append( t )
999 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001000
1001 for t in threads:
1002 t.join()
1003 ONOSMastership.append( t.result )
1004
1005 for i in range( numControllers ):
1006 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1007 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1008 " roles" )
1009 main.log.warn(
1010 "ONOS" + str( i + 1 ) + " mastership response: " +
1011 repr( ONOSMastership[i] ) )
1012 rolesResults = False
1013 utilities.assert_equals(
1014 expect=True,
1015 actual=rolesResults,
1016 onpass="No error in reading roles output",
1017 onfail="Error in reading roles from ONOS" )
1018
1019 main.step( "Check for consistency in roles from each controller" )
1020 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001021 main.log.report(
1022 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001023 else:
Jon Hall65844a32015-03-09 19:09:37 -07001024 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001025 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001026 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001027 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001028 onpass="Switch roles are consistent across all ONOS nodes",
1029 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001030
Jon Hall65844a32015-03-09 19:09:37 -07001031 if rolesResults and not consistentMastership:
1032 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001033 try:
1034 main.log.warn(
1035 "ONOS" + str( i + 1 ) + " roles: ",
1036 json.dumps(
1037 json.loads( ONOSMastership[ i ] ),
1038 sort_keys=True,
1039 indent=4,
1040 separators=( ',', ': ' ) ) )
1041 except ( ValueError, TypeError ):
1042 main.log.warn( repr( ONOSMastership[ i ] ) )
1043 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001044 mastershipCheck = main.TRUE
1045 mastershipState = ONOSMastership[ 0 ]
1046
Jon Hall6aec96b2015-01-19 14:49:31 -08001047 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001048 global intentState
1049 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001050 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001051 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001052 consistentIntents = True
1053 intentsResults = True
1054 threads = []
1055 for i in range( numControllers ):
1056 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001057 name="intents-" + str( i ),
1058 args=[],
1059 kwargs={ 'jsonFormat': True } )
1060 threads.append( t )
1061 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001062
1063 for t in threads:
1064 t.join()
1065 ONOSIntents.append( t.result )
1066
1067 for i in range( numControllers ):
1068 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1069 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1070 " intents" )
1071 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1072 repr( ONOSIntents[ i ] ) )
1073 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001074 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001075 expect=True,
1076 actual=intentsResults,
1077 onpass="No error in reading intents output",
1078 onfail="Error in reading intents from ONOS" )
1079
1080 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001081 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001082 main.log.report( "Intents are consistent across all ONOS " +
1083 "nodes" )
1084 else:
1085 consistentIntents = False
Jon Hall5cfd23c2015-03-19 11:40:57 -07001086 main.log.report( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001087 utilities.assert_equals(
1088 expect=True,
1089 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001090 onpass="Intents are consistent across all ONOS nodes",
1091 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001092
Jon Hall390696c2015-05-05 17:13:41 -07001093 if intentsResults:
1094 # Try to make it easy to figure out what is happening
1095 #
1096 # Intent ONOS1 ONOS2 ...
1097 # 0x01 INSTALLED INSTALLING
1098 # ... ... ...
1099 # ... ... ...
1100 title = " Id"
1101 for n in range( numControllers ):
1102 title += " " * 10 + "ONOS" + str( n + 1 )
1103 main.log.warn( title )
1104 # get all intent keys in the cluster
1105 keys = []
1106 for nodeStr in ONOSIntents:
1107 node = json.loads( nodeStr )
1108 for intent in node:
1109 keys.append( intent.get( 'id' ) )
1110 keys = set( keys )
1111 for key in keys:
1112 row = "%-13s" % key
1113 for nodeStr in ONOSIntents:
1114 node = json.loads( nodeStr )
1115 for intent in node:
1116 if intent.get( 'id', "Error" ) == key:
1117 row += "%-15s" % intent.get( 'state' )
1118 main.log.warn( row )
1119 # End table view
1120
Jon Hall65844a32015-03-09 19:09:37 -07001121 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001122 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001123 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001124 main.log.debug( "ONOS" + str( n ) + " intents: " )
1125 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1126 sort_keys=True,
1127 indent=4,
1128 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001129 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001130 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001131 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1132 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1133 sort_keys=True,
1134 indent=4,
1135 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001136 else:
Jon Hall390696c2015-05-05 17:13:41 -07001137 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1138 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001139 elif intentsResults and consistentIntents:
1140 intentCheck = main.TRUE
1141 intentState = ONOSIntents[ 0 ]
1142
Jon Hall6aec96b2015-01-19 14:49:31 -08001143 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001144 global flowState
1145 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001146 ONOSFlows = []
1147 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001148 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001149 consistentFlows = True
1150 flowsResults = True
1151 threads = []
1152 for i in range( numControllers ):
1153 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001154 name="flows-" + str( i ),
1155 args=[],
1156 kwargs={ 'jsonFormat': True } )
1157 threads.append( t )
1158 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001159
Jon Halla9d26da2015-03-30 16:45:32 -07001160 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001161 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001162 for t in threads:
1163 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001164 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001165 ONOSFlows.append( result )
1166
1167 for i in range( numControllers ):
1168 num = str( i + 1 )
1169 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1170 main.log.report( "Error in getting ONOS" + num + " flows" )
1171 main.log.warn( "ONOS" + num + " flows response: " +
1172 repr( ONOSFlows[ i ] ) )
1173 flowsResults = False
1174 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001175 else:
Jon Hall65844a32015-03-09 19:09:37 -07001176 try:
1177 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1178 except ( ValueError, TypeError ):
1179 # FIXME: change this to log.error?
1180 main.log.exception( "Error in parsing ONOS" + num +
1181 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001182 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001183 ONOSFlowsJson.append( None )
1184 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001185 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001186 expect=True,
1187 actual=flowsResults,
1188 onpass="No error in reading flows output",
1189 onfail="Error in reading flows from ONOS" )
1190
1191 main.step( "Check for consistency in Flows from each controller" )
1192 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1193 if all( tmp ):
1194 main.log.report( "Flow count is consistent across all ONOS nodes" )
1195 else:
1196 consistentFlows = False
1197 utilities.assert_equals(
1198 expect=True,
1199 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001200 onpass="The flow count is consistent across all ONOS nodes",
1201 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001202
Jon Hall65844a32015-03-09 19:09:37 -07001203 if flowsResults and not consistentFlows:
1204 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001205 try:
1206 main.log.warn(
1207 "ONOS" + str( i + 1 ) + " flows: " +
1208 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1209 indent=4, separators=( ',', ': ' ) ) )
1210 except ( ValueError, TypeError ):
1211 main.log.warn(
1212 "ONOS" + str( i + 1 ) + " flows: " +
1213 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001214 elif flowsResults and consistentFlows:
1215 flowCheck = main.TRUE
1216 flowState = ONOSFlows[ 0 ]
1217
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001219 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001220 flows = []
1221 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001222 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001223 if flowCheck == main.FALSE:
1224 for table in flows:
1225 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001226 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001227
Jon Hall6aec96b2015-01-19 14:49:31 -08001228 main.step( "Start continuous pings" )
1229 main.Mininet2.pingLong(
1230 src=main.params[ 'PING' ][ 'source1' ],
1231 target=main.params[ 'PING' ][ 'target1' ],
1232 pingTime=500 )
1233 main.Mininet2.pingLong(
1234 src=main.params[ 'PING' ][ 'source2' ],
1235 target=main.params[ 'PING' ][ 'target2' ],
1236 pingTime=500 )
1237 main.Mininet2.pingLong(
1238 src=main.params[ 'PING' ][ 'source3' ],
1239 target=main.params[ 'PING' ][ 'target3' ],
1240 pingTime=500 )
1241 main.Mininet2.pingLong(
1242 src=main.params[ 'PING' ][ 'source4' ],
1243 target=main.params[ 'PING' ][ 'target4' ],
1244 pingTime=500 )
1245 main.Mininet2.pingLong(
1246 src=main.params[ 'PING' ][ 'source5' ],
1247 target=main.params[ 'PING' ][ 'target5' ],
1248 pingTime=500 )
1249 main.Mininet2.pingLong(
1250 src=main.params[ 'PING' ][ 'source6' ],
1251 target=main.params[ 'PING' ][ 'target6' ],
1252 pingTime=500 )
1253 main.Mininet2.pingLong(
1254 src=main.params[ 'PING' ][ 'source7' ],
1255 target=main.params[ 'PING' ][ 'target7' ],
1256 pingTime=500 )
1257 main.Mininet2.pingLong(
1258 src=main.params[ 'PING' ][ 'source8' ],
1259 target=main.params[ 'PING' ][ 'target8' ],
1260 pingTime=500 )
1261 main.Mininet2.pingLong(
1262 src=main.params[ 'PING' ][ 'source9' ],
1263 target=main.params[ 'PING' ][ 'target9' ],
1264 pingTime=500 )
1265 main.Mininet2.pingLong(
1266 src=main.params[ 'PING' ][ 'source10' ],
1267 target=main.params[ 'PING' ][ 'target10' ],
1268 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001269
Jon Hall6aec96b2015-01-19 14:49:31 -08001270 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001271 ctrls = []
Jon Hall65844a32015-03-09 19:09:37 -07001272 for node in nodes:
1273 temp = ( node, node.name, node.ip_address, 6633 )
Jon Hall65844a32015-03-09 19:09:37 -07001274 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001275 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001276
Jon Hall6aec96b2015-01-19 14:49:31 -08001277 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001278 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001279 threads = []
1280 for i in range( numControllers ):
1281 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001282 name="devices-" + str( i ),
1283 args=[ ] )
1284 threads.append( t )
1285 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001286
1287 for t in threads:
1288 t.join()
1289 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001290 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001291 threads = []
1292 for i in range( numControllers ):
1293 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001294 name="hosts-" + str( i ),
1295 args=[ ] )
1296 threads.append( t )
1297 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001298
1299 for t in threads:
1300 t.join()
1301 try:
1302 hosts.append( json.loads( t.result ) )
1303 except ( ValueError, TypeError ):
1304 # FIXME: better handling of this, print which node
1305 # Maybe use thread name?
1306 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001307 # FIXME: should this be an empty json object instead?
1308 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001309
Jon Hallb1290e82014-11-18 16:17:48 -05001310 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001311 threads = []
1312 for i in range( numControllers ):
1313 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001314 name="ports-" + str( i ),
1315 args=[ ] )
1316 threads.append( t )
1317 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001318
1319 for t in threads:
1320 t.join()
1321 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001322 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001323 threads = []
1324 for i in range( numControllers ):
1325 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001326 name="links-" + str( i ),
1327 args=[ ] )
1328 threads.append( t )
1329 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001330
1331 for t in threads:
1332 t.join()
1333 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001334 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001335 threads = []
1336 for i in range( numControllers ):
1337 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001338 name="clusters-" + str( i ),
1339 args=[ ] )
1340 threads.append( t )
1341 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001342
1343 for t in threads:
1344 t.join()
1345 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001346 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001347
Jon Hall6aec96b2015-01-19 14:49:31 -08001348 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001349 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001350 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001351 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001352 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001353 if "Error" not in hosts[ controller ]:
1354 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001355 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001356 else: # hosts not consistent
1357 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001358 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001359 " is inconsistent with ONOS1" )
1360 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001361 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001362
1363 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001364 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001365 controllerStr )
1366 consistentHostsResult = main.FALSE
1367 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001368 " hosts response: " +
1369 repr( hosts[ controller ] ) )
1370 utilities.assert_equals(
1371 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001372 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001373 onpass="Hosts view is consistent across all ONOS nodes",
1374 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001375
Jon Hall390696c2015-05-05 17:13:41 -07001376 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001377 ipResult = main.TRUE
1378 for controller in range( 0, len( hosts ) ):
1379 controllerStr = str( controller + 1 )
1380 for host in hosts[ controller ]:
Jon Hall65844a32015-03-09 19:09:37 -07001381 if not host.get( 'ips', [ ] ):
1382 main.log.error( "DEBUG:Error with host ips on controller" +
1383 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001384 ipResult = main.FALSE
1385 utilities.assert_equals(
1386 expect=main.TRUE,
1387 actual=ipResult,
1388 onpass="The ips of the hosts aren't empty",
1389 onfail="The ip of at least one host is missing" )
1390
Jon Hall6aec96b2015-01-19 14:49:31 -08001391 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001392 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001393 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001394 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001395 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001396 if "Error" not in clusters[ controller ]:
1397 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001398 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001399 else: # clusters not consistent
Jon Hall65844a32015-03-09 19:09:37 -07001400 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001401 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001402 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001403
1404 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001405 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001406 "from ONOS" + controllerStr )
1407 consistentClustersResult = main.FALSE
1408 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001409 " clusters response: " +
1410 repr( clusters[ controller ] ) )
1411 utilities.assert_equals(
1412 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001413 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001414 onpass="Clusters view is consistent across all ONOS nodes",
1415 onfail="ONOS nodes have different views of clusters" )
1416 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001417 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001418 try:
1419 numClusters = len( json.loads( clusters[ 0 ] ) )
1420 except ( ValueError, TypeError ):
1421 main.log.exception( "Error parsing clusters[0]: " +
1422 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001423 clusterResults = main.FALSE
1424 if numClusters == 1:
1425 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001426 utilities.assert_equals(
1427 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001428 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001429 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001430 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001431
Jon Hall6aec96b2015-01-19 14:49:31 -08001432 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001433 devicesResults = main.TRUE
1434 portsResults = main.TRUE
1435 linksResults = main.TRUE
1436 for controller in range( numControllers ):
1437 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001438 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001439 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001440 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001441 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001442 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001443 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001444 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001445 actual=currentDevicesResult,
1446 onpass="ONOS" + controllerStr +
1447 " Switches view is correct",
1448 onfail="ONOS" + controllerStr +
1449 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001450
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001452 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001453 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001454 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001455 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001456 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001457 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001458 actual=currentPortsResult,
1459 onpass="ONOS" + controllerStr +
1460 " ports view is correct",
1461 onfail="ONOS" + controllerStr +
1462 " ports view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001463
Jon Hall6aec96b2015-01-19 14:49:31 -08001464 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001465 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001466 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001467 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001468 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001469 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001470 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001471 actual=currentLinksResult,
1472 onpass="ONOS" + controllerStr +
1473 " links view is correct",
1474 onfail="ONOS" + controllerStr +
1475 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001476
Jon Hall8f89dda2015-01-22 16:03:33 -08001477 devicesResults = devicesResults and currentDevicesResult
1478 portsResults = portsResults and currentPortsResult
1479 linksResults = linksResults and currentLinksResult
Jon Hallb1290e82014-11-18 16:17:48 -05001480
Jon Hall65844a32015-03-09 19:09:37 -07001481 topoResult = ( devicesResults and portsResults and linksResults
1482 and consistentHostsResult and consistentClustersResult
1483 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001484 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001485 onpass="Topology Check Test successful",
1486 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001487
Jon Hall6aec96b2015-01-19 14:49:31 -08001488 def CASE6( self, main ):
1489 """
Jon Hallb1290e82014-11-18 16:17:48 -05001490 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001491 """
Jon Hall368769f2014-11-19 15:43:35 -08001492 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001493 assert numControllers, "numControllers not defined"
1494 assert main, "main not defined"
1495 assert utilities.assert_equals, "utilities.assert_equals not defined"
1496 assert CLIs, "CLIs not defined"
1497 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001498 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001499 time.sleep( 60 )
1500 utilities.assert_equals(
1501 expect=main.TRUE,
1502 actual=main.TRUE,
1503 onpass="Sleeping 60 seconds",
1504 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001505
Jon Hall6aec96b2015-01-19 14:49:31 -08001506 def CASE7( self, main ):
1507 """
Jon Hall368769f2014-11-19 15:43:35 -08001508 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001509 """
Jon Hallb1290e82014-11-18 16:17:48 -05001510 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001511 assert numControllers, "numControllers not defined"
1512 assert main, "main not defined"
1513 assert utilities.assert_equals, "utilities.assert_equals not defined"
1514 assert CLIs, "CLIs not defined"
1515 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001516 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001517
Jon Hall65844a32015-03-09 19:09:37 -07001518 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001519 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001520 rolesNotNull = main.TRUE
1521 threads = []
1522 for i in range( numControllers ):
1523 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001524 name="rolesNotNull-" + str( i ),
1525 args=[ ] )
1526 threads.append( t )
1527 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001528
1529 for t in threads:
1530 t.join()
1531 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001532 utilities.assert_equals(
1533 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001534 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001535 onpass="Each device has a master",
1536 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001537
Jon Hall390696c2015-05-05 17:13:41 -07001538 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001539 ONOSMastership = []
1540 mastershipCheck = main.FALSE
1541 consistentMastership = True
1542 rolesResults = True
1543 threads = []
1544 for i in range( numControllers ):
1545 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001546 name="roles-" + str( i ),
1547 args=[] )
1548 threads.append( t )
1549 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001550
1551 for t in threads:
1552 t.join()
1553 ONOSMastership.append( t.result )
1554
1555 for i in range( numControllers ):
1556 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1557 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1558 " roles" )
1559 main.log.warn(
1560 "ONOS" + str( i + 1 ) + " mastership response: " +
1561 repr( ONOSMastership[i] ) )
1562 rolesResults = False
1563 utilities.assert_equals(
1564 expect=True,
1565 actual=rolesResults,
1566 onpass="No error in reading roles output",
1567 onfail="Error in reading roles from ONOS" )
1568
1569 main.step( "Check for consistency in roles from each controller" )
1570 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001571 main.log.report(
1572 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001573 else:
Jon Hall65844a32015-03-09 19:09:37 -07001574 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001575 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001576 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001577 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001578 onpass="Switch roles are consistent across all ONOS nodes",
1579 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001580
Jon Hall65844a32015-03-09 19:09:37 -07001581 if rolesResults and not consistentMastership:
1582 for i in range( numControllers ):
1583 main.log.warn(
1584 "ONOS" + str( i + 1 ) + " roles: ",
1585 json.dumps(
1586 json.loads( ONOSMastership[ i ] ),
1587 sort_keys=True,
1588 indent=4,
1589 separators=( ',', ': ' ) ) )
1590 elif rolesResults and not consistentMastership:
1591 mastershipCheck = main.TRUE
1592
Jon Hallb1290e82014-11-18 16:17:48 -05001593 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001594 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001595 try:
1596 currentJson = json.loads( ONOSMastership[0] )
1597 oldJson = json.loads( mastershipState )
1598 except ( ValueError, TypeError ):
1599 main.log.exception( "Something is wrong with parsing " +
1600 "ONOSMastership[0] or mastershipState" )
1601 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1602 main.log.error( "mastershipState" + repr( mastershipState ) )
1603 main.cleanup()
1604 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001605 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001606 for i in range( 1, 29 ):
1607 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001608 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001609 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001610 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001611 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001612 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001613 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001614 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001615 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001616 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001617 mastershipCheck = main.FALSE
1618 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001619 main.log.report( "Mastership of Switches was not changed" )
1620 utilities.assert_equals(
1621 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001622 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001623 onpass="Mastership of Switches was not changed",
1624 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001625 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001626
Jon Hall6aec96b2015-01-19 14:49:31 -08001627 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001628 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001629 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001630 consistentIntents = True
1631 intentsResults = True
1632 threads = []
1633 for i in range( numControllers ):
1634 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001635 name="intents-" + str( i ),
1636 args=[],
1637 kwargs={ 'jsonFormat': True } )
1638 threads.append( t )
1639 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001640
1641 for t in threads:
1642 t.join()
1643 ONOSIntents.append( t.result )
1644
1645 for i in range( numControllers ):
1646 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1647 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1648 " intents" )
1649 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1650 repr( ONOSIntents[ i ] ) )
1651 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001652 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001653 expect=True,
1654 actual=intentsResults,
1655 onpass="No error in reading intents output",
1656 onfail="Error in reading intents from ONOS" )
1657
1658 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001659 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001660 main.log.report( "Intents are consistent across all ONOS " +
1661 "nodes" )
1662 else:
1663 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001664
1665 # Try to make it easy to figure out what is happening
1666 #
1667 # Intent ONOS1 ONOS2 ...
1668 # 0x01 INSTALLED INSTALLING
1669 # ... ... ...
1670 # ... ... ...
1671 title = " ID"
1672 for n in range( numControllers ):
1673 title += " " * 10 + "ONOS" + str( n + 1 )
1674 main.log.warn( title )
1675 # get all intent keys in the cluster
1676 keys = []
1677 for nodeStr in ONOSIntents:
1678 node = json.loads( nodeStr )
1679 for intent in node:
1680 keys.append( intent.get( 'id' ) )
1681 keys = set( keys )
1682 for key in keys:
1683 row = "%-13s" % key
1684 for nodeStr in ONOSIntents:
1685 node = json.loads( nodeStr )
1686 for intent in node:
1687 if intent.get( 'id' ) == key:
1688 row += "%-15s" % intent.get( 'state' )
1689 main.log.warn( row )
1690 # End table view
1691
Jon Hall65844a32015-03-09 19:09:37 -07001692 utilities.assert_equals(
1693 expect=True,
1694 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001695 onpass="Intents are consistent across all ONOS nodes",
1696 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001697 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001698 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001699 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001700 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001701 try:
1702 for intent in json.loads( node ):
1703 nodeStates.append( intent[ 'state' ] )
1704 except ( ValueError, TypeError ):
1705 main.log.exception( "Error in parsing intents" )
1706 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001707 intentStates.append( nodeStates )
1708 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1709 main.log.info( dict( out ) )
1710
Jon Hall65844a32015-03-09 19:09:37 -07001711 if intentsResults and not consistentIntents:
1712 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001713 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1714 main.log.warn( json.dumps(
1715 json.loads( ONOSIntents[ i ] ),
1716 sort_keys=True,
1717 indent=4,
1718 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001719 elif intentsResults and consistentIntents:
1720 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001721
Jon Hall58c76b72015-02-23 11:09:24 -08001722 # NOTE: Store has no durability, so intents are lost across system
1723 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001724 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001725 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001726 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001727 sameIntents = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001728 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001729 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001730 main.log.report( "Intents are consistent with before failure" )
1731 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001732 # what the acceptable states are
Jon Hallb1290e82014-11-18 16:17:48 -05001733 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001734 try:
Jon Hall65844a32015-03-09 19:09:37 -07001735 main.log.warn( "ONOS intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001736 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1737 sort_keys=True, indent=4,
1738 separators=( ',', ': ' ) ) )
1739 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001740 main.log.exception( "Exception printing intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001741 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001742 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001743 utilities.assert_equals(
1744 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001745 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001746 onpass="Intents are consistent with before failure",
1747 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001748 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001749
Jon Hall6aec96b2015-01-19 14:49:31 -08001750 main.step( "Get the OF Table entries and compare to before " +
1751 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001752 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001753 flows2 = []
1754 for i in range( 28 ):
1755 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001756 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1757 flows2.append( tmpFlows )
1758 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001759 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001760 flow2=tmpFlows )
1761 FlowTables = FlowTables and tempResult
1762 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001763 main.log.info( "Differences in flow table for switch: s" +
1764 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001765 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001766 main.log.report( "No changes were found in the flow tables" )
1767 utilities.assert_equals(
1768 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001769 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001770 onpass="No changes were found in the flow tables",
1771 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001772
Jon Hall6aec96b2015-01-19 14:49:31 -08001773 main.step( "Check the continuous pings to ensure that no packets " +
1774 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001775 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1776 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001777 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001778 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1779 for i in range( 8, 18 ):
1780 main.log.info(
1781 "Checking for a loss in pings along flow from s" +
1782 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001783 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001784 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001785 str( i ) ) or LossInPings
1786 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001787 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001788 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001789 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001790 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001791 main.log.info( "No Loss in the pings" )
1792 main.log.report( "No loss of dataplane connectivity" )
1793 utilities.assert_equals(
1794 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001795 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001796 onpass="No Loss of connectivity",
1797 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001798
Jon Hall390696c2015-05-05 17:13:41 -07001799 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001800 # Test of LeadershipElection
1801 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001802 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001803 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001804 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001805 for cli in CLIs:
1806 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001807 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001808 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001809 # all is well
1810 # NOTE: In failure scenario, this could be a new node, maybe
1811 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001812 pass
1813 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001814 # error in response
Jon Hall6aec96b2015-01-19 14:49:31 -08001815 main.log.report( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001816 "electionTestLeader function, check the" +
1817 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001818 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001819 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001820 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001821 main.log.report( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001822 " as the leader of the election app. " +
1823 "Leader should be " + str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001824 if leaderResult:
1825 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001826 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001827 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001828 utilities.assert_equals(
1829 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001830 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001831 onpass="Leadership election passed",
1832 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001833
Jon Hall6aec96b2015-01-19 14:49:31 -08001834 def CASE8( self, main ):
1835 """
Jon Hallb1290e82014-11-18 16:17:48 -05001836 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001837 """
Jon Hallb1290e82014-11-18 16:17:48 -05001838 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001839 # FIXME add this path to params
1840 sys.path.append( "/home/admin/sts" )
1841 # assumes that sts is already in you PYTHONPATH
1842 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001843 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001844 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001845 assert numControllers, "numControllers not defined"
1846 assert main, "main not defined"
1847 assert utilities.assert_equals, "utilities.assert_equals not defined"
1848 assert CLIs, "CLIs not defined"
1849 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05001850
Jon Hall6aec96b2015-01-19 14:49:31 -08001851 description = "Compare ONOS Topology view to Mininet topology"
1852 main.case( description )
1853 main.log.report( description )
1854 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001855 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001856 for node in nodes:
1857 temp = ( node, node.name, node.ip_address, 6633 )
1858 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001859 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001860
Jon Hall8f89dda2015-01-22 16:03:33 -08001861 devicesResults = main.TRUE
1862 portsResults = main.TRUE
1863 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001864 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001865 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001866 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001867 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001868 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001869 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001870 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001871 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07001872 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001873 if count > 1:
Jon Hall65844a32015-03-09 19:09:37 -07001874 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001875 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001876 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001877 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001878 threads = []
1879 for i in range( numControllers ):
1880 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001881 name="devices-" + str( i ),
1882 args=[ ] )
1883 threads.append( t )
1884 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001885
1886 for t in threads:
1887 t.join()
1888 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001889 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001890 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001891 threads = []
1892 for i in range( numControllers ):
1893 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001894 name="hosts-" + str( i ),
1895 args=[ ] )
1896 threads.append( t )
1897 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001898
1899 for t in threads:
1900 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001901 try:
1902 hosts.append( json.loads( t.result ) )
1903 except ( ValueError, TypeError ):
1904 main.log.exception( "Error parsing hosts results" )
1905 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08001906 for controller in range( 0, len( hosts ) ):
1907 controllerStr = str( controller + 1 )
1908 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001909 if host is None or host.get( 'ips', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08001910 main.log.error(
1911 "DEBUG:Error with host ips on controller" +
1912 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001913 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001914 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001915 threads = []
1916 for i in range( numControllers ):
1917 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001918 name="ports-" + str( i ),
1919 args=[ ] )
1920 threads.append( t )
1921 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001922
1923 for t in threads:
1924 t.join()
1925 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001926 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001927 threads = []
1928 for i in range( numControllers ):
1929 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001930 name="links-" + str( i ),
1931 args=[ ] )
1932 threads.append( t )
1933 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001934
1935 for t in threads:
1936 t.join()
1937 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001938 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001939 threads = []
1940 for i in range( numControllers ):
1941 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001942 name="clusters-" + str( i ),
1943 args=[ ] )
1944 threads.append( t )
1945 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001946
1947 for t in threads:
1948 t.join()
1949 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001950
Jon Hall8f89dda2015-01-22 16:03:33 -08001951 elapsed = time.time() - startTime
1952 cliTime = time.time() - cliStart
1953 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05001954
Jon Hall21270ac2015-02-16 17:59:55 -08001955 for controller in range( numControllers ):
1956 controllerStr = str( controller + 1 )
1957 if devices[ controller ] or "Error" not in devices[
1958 controller ]:
1959 currentDevicesResult = main.Mininet1.compareSwitches(
1960 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001961 json.loads( devices[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08001962 else:
1963 currentDevicesResult = main.FALSE
1964 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001965 actual=currentDevicesResult,
1966 onpass="ONOS" + controllerStr +
1967 " Switches view is correct",
1968 onfail="ONOS" + controllerStr +
1969 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001970
Jon Hall21270ac2015-02-16 17:59:55 -08001971 if ports[ controller ] or "Error" not in ports[ controller ]:
1972 currentPortsResult = main.Mininet1.comparePorts(
1973 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001974 json.loads( ports[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08001975 else:
1976 currentPortsResult = main.FALSE
1977 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001978 actual=currentPortsResult,
1979 onpass="ONOS" + controllerStr +
1980 " ports view is correct",
1981 onfail="ONOS" + controllerStr +
1982 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001983
Jon Hall21270ac2015-02-16 17:59:55 -08001984 if links[ controller ] or "Error" not in links[ controller ]:
1985 currentLinksResult = main.Mininet1.compareLinks(
1986 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001987 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08001988 else:
1989 currentLinksResult = main.FALSE
1990 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001991 actual=currentLinksResult,
1992 onpass="ONOS" + controllerStr +
1993 " links view is correct",
1994 onfail="ONOS" + controllerStr +
1995 " links view is incorrect" )
1996
1997 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1998 currentHostsResult = main.Mininet1.compareHosts(
1999 MNTopo, hosts[ controller ] )
2000 else:
2001 currentHostsResult = main.FALSE
2002 utilities.assert_equals( expect=main.TRUE,
2003 actual=currentHostsResult,
2004 onpass="ONOS" + controllerStr +
2005 " hosts exist in Mininet",
2006 onfail="ONOS" + controllerStr +
2007 " hosts don't match Mininet" )
2008
2009 devicesResults = devicesResults and currentDevicesResult
2010 portsResults = portsResults and currentPortsResult
2011 linksResults = linksResults and currentLinksResult
2012 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002013
Jon Hall21270ac2015-02-16 17:59:55 -08002014 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002015
Jon Hall21270ac2015-02-16 17:59:55 -08002016 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002017 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall21270ac2015-02-16 17:59:55 -08002018 consistentHostsResult = main.TRUE
2019 for controller in range( len( hosts ) ):
2020 controllerStr = str( controller + 1 )
2021 if "Error" not in hosts[ controller ]:
2022 if hosts[ controller ] == hosts[ 0 ]:
2023 continue
2024 else: # hosts not consistent
2025 main.log.report( "hosts from ONOS" + controllerStr +
2026 " is inconsistent with ONOS1" )
2027 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002028 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002029
Jon Hall21270ac2015-02-16 17:59:55 -08002030 else:
2031 main.log.report( "Error in getting ONOS hosts from ONOS" +
2032 controllerStr )
2033 consistentHostsResult = main.FALSE
2034 main.log.warn( "ONOS" + controllerStr +
2035 " hosts response: " +
2036 repr( hosts[ controller ] ) )
2037 utilities.assert_equals(
2038 expect=main.TRUE,
2039 actual=consistentHostsResult,
2040 onpass="Hosts view is consistent across all ONOS nodes",
2041 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002042
Jon Hall21270ac2015-02-16 17:59:55 -08002043 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002044 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall21270ac2015-02-16 17:59:55 -08002045 consistentClustersResult = main.TRUE
2046 for controller in range( len( clusters ) ):
2047 controllerStr = str( controller + 1 )
2048 if "Error" not in clusters[ controller ]:
2049 if clusters[ controller ] == clusters[ 0 ]:
2050 continue
2051 else: # clusters not consistent
2052 main.log.report( "clusters from ONOS" +
2053 controllerStr +
2054 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002055 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002056
Jon Hall21270ac2015-02-16 17:59:55 -08002057 else:
2058 main.log.report( "Error in getting dataplane clusters " +
2059 "from ONOS" + controllerStr )
2060 consistentClustersResult = main.FALSE
2061 main.log.warn( "ONOS" + controllerStr +
2062 " clusters response: " +
2063 repr( clusters[ controller ] ) )
2064 utilities.assert_equals(
2065 expect=main.TRUE,
2066 actual=consistentClustersResult,
2067 onpass="Clusters view is consistent across all ONOS nodes",
2068 onfail="ONOS nodes have different views of clusters" )
2069 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002070 main.step( "Topology view is correct and consistent across all " +
2071 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002072 try:
2073 numClusters = len( json.loads( clusters[ 0 ] ) )
2074 except ( ValueError, TypeError ):
2075 main.log.exception( "Error parsing clusters[0]: " +
2076 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002077 clusterResults = main.FALSE
2078 if numClusters == 1:
2079 clusterResults = main.TRUE
Jon Hall21270ac2015-02-16 17:59:55 -08002080 utilities.assert_equals(
2081 expect=1,
2082 actual=numClusters,
2083 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002084 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002085
Jon Hall21270ac2015-02-16 17:59:55 -08002086 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002087 and hostsResults and consistentHostsResult
2088 and consistentClustersResult and clusterResults
2089 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002090
Jon Hall21270ac2015-02-16 17:59:55 -08002091 topoResult = topoResult and int( count <= 2 )
2092 note = "note it takes about " + str( int( cliTime ) ) + \
2093 " seconds for the test to make all the cli calls to fetch " +\
2094 "the topology from each ONOS instance"
2095 main.log.info(
2096 "Very crass estimate for topology discovery/convergence( " +
2097 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2098 str( count ) + " tries" )
2099 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002100 onpass="Topology Check Test successful",
2101 onfail="Topology Check Test NOT successful" )
Jon Hall21270ac2015-02-16 17:59:55 -08002102 if topoResult == main.TRUE:
2103 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hallb1290e82014-11-18 16:17:48 -05002104
Jon Halla9d26da2015-03-30 16:45:32 -07002105 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002106 main.step( "Checking ONOS nodes" )
2107 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002108 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002109 threads = []
2110 for i in range( numControllers ):
2111 t = main.Thread( target=CLIs[i].nodes,
2112 name="nodes-" + str( i ),
2113 args=[ ] )
2114 threads.append( t )
2115 t.start()
2116
2117 for t in threads:
2118 t.join()
2119 nodesOutput.append( t.result )
2120 ips = [ node.ip_address for node in nodes ]
2121 for i in nodesOutput:
2122 try:
2123 current = json.loads( i )
2124 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002125 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002126 if node['ip'] in ips: # node in nodes() output is in cell
2127 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002128 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002129 else:
2130 main.log.error( "Error in ONOS node availability" )
2131 main.log.error(
2132 json.dumps( current,
2133 sort_keys=True,
2134 indent=4,
2135 separators=( ',', ': ' ) ) )
2136 break
Jon Hall390696c2015-05-05 17:13:41 -07002137 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002138 except ( ValueError, TypeError ):
2139 main.log.error( "Error parsing nodes output" )
2140 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002141 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2142 onpass="Nodes check successful",
2143 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002144
Jon Hall6aec96b2015-01-19 14:49:31 -08002145 def CASE9( self, main ):
2146 """
Jon Hallb1290e82014-11-18 16:17:48 -05002147 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002148 """
2149 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002150 assert numControllers, "numControllers not defined"
2151 assert main, "main not defined"
2152 assert utilities.assert_equals, "utilities.assert_equals not defined"
2153 assert CLIs, "CLIs not defined"
2154 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002155 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002156
Jon Hall8f89dda2015-01-22 16:03:33 -08002157 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002158
Jon Hall6aec96b2015-01-19 14:49:31 -08002159 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002160 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002161 main.log.report( description )
2162 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002163
Jon Hall6aec96b2015-01-19 14:49:31 -08002164 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002165 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002166 main.log.info( "Waiting " + str( linkSleep ) +
2167 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002168 time.sleep( linkSleep )
2169 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002170 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002171 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002172 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002173
Jon Hall6aec96b2015-01-19 14:49:31 -08002174 def CASE10( self, main ):
2175 """
Jon Hallb1290e82014-11-18 16:17:48 -05002176 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002177 """
2178 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002179 assert numControllers, "numControllers not defined"
2180 assert main, "main not defined"
2181 assert utilities.assert_equals, "utilities.assert_equals not defined"
2182 assert CLIs, "CLIs not defined"
2183 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002184 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002185
Jon Hall8f89dda2015-01-22 16:03:33 -08002186 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002187
Jon Hall6aec96b2015-01-19 14:49:31 -08002188 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002189 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002190 main.log.report( description )
2191 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002192
Jon Hall6aec96b2015-01-19 14:49:31 -08002193 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002194 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002195 main.log.info( "Waiting " + str( linkSleep ) +
2196 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002197 time.sleep( linkSleep )
2198 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002199 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002200 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002201 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002202
Jon Hall6aec96b2015-01-19 14:49:31 -08002203 def CASE11( self, main ):
2204 """
Jon Hallb1290e82014-11-18 16:17:48 -05002205 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002206 """
2207 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002208 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002209 assert numControllers, "numControllers not defined"
2210 assert main, "main not defined"
2211 assert utilities.assert_equals, "utilities.assert_equals not defined"
2212 assert CLIs, "CLIs not defined"
2213 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002214
Jon Hall8f89dda2015-01-22 16:03:33 -08002215 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002216
2217 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002218 main.log.report( description )
2219 main.case( description )
2220 switch = main.params[ 'kill' ][ 'switch' ]
2221 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002222
Jon Hall6aec96b2015-01-19 14:49:31 -08002223 # TODO: Make this switch parameterizable
2224 main.step( "Kill " + switch )
2225 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002226 main.Mininet1.delSwitch( switch )
2227 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002228 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002229 time.sleep( switchSleep )
2230 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002231 # Peek at the deleted switch
2232 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002233 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002234 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002235 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002236 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002237 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002238 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002239
Jon Hall6aec96b2015-01-19 14:49:31 -08002240 def CASE12( self, main ):
2241 """
Jon Hallb1290e82014-11-18 16:17:48 -05002242 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002243 """
2244 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002245 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002246 assert numControllers, "numControllers not defined"
2247 assert main, "main not defined"
2248 assert utilities.assert_equals, "utilities.assert_equals not defined"
2249 assert CLIs, "CLIs not defined"
2250 assert nodes, "nodes not defined"
2251 assert ONOS1Port, "ONOS1Port not defined"
2252 assert ONOS2Port, "ONOS2Port not defined"
2253 assert ONOS3Port, "ONOS3Port not defined"
2254 assert ONOS4Port, "ONOS4Port not defined"
2255 assert ONOS5Port, "ONOS5Port not defined"
2256 assert ONOS6Port, "ONOS6Port not defined"
2257 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002258
Jon Hall8f89dda2015-01-22 16:03:33 -08002259 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002260 switch = main.params[ 'kill' ][ 'switch' ]
2261 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2262 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002263 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002264 main.log.report( description )
2265 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002266
Jon Hall6aec96b2015-01-19 14:49:31 -08002267 main.step( "Add back " + switch )
2268 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002269 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002270 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002271 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002272 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2273 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -07002274 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002275 port1=ONOS1Port,
Jon Hall65844a32015-03-09 19:09:37 -07002276 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002277 port2=ONOS2Port,
Jon Hall65844a32015-03-09 19:09:37 -07002278 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002279 port3=ONOS3Port,
Jon Hall65844a32015-03-09 19:09:37 -07002280 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002281 port4=ONOS4Port,
Jon Hall65844a32015-03-09 19:09:37 -07002282 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002283 port5=ONOS5Port,
Jon Hall65844a32015-03-09 19:09:37 -07002284 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002285 port6=ONOS6Port,
Jon Hall65844a32015-03-09 19:09:37 -07002286 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002287 port7=ONOS7Port )
2288 main.log.info( "Waiting " + str( switchSleep ) +
2289 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002290 time.sleep( switchSleep )
2291 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002292 # Peek at the deleted switch
2293 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002294 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002295 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002296 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002297 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002298 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002299 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002300
Jon Hall6aec96b2015-01-19 14:49:31 -08002301 def CASE13( self, main ):
2302 """
Jon Hallb1290e82014-11-18 16:17:48 -05002303 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002304 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002305 import os
2306 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002307 assert numControllers, "numControllers not defined"
2308 assert main, "main not defined"
2309 assert utilities.assert_equals, "utilities.assert_equals not defined"
2310 assert CLIs, "CLIs not defined"
2311 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002312
2313 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002314 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2315 'blue': '\033[94m', 'green': '\033[92m',
2316 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall368769f2014-11-19 15:43:35 -08002317 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002318 main.log.report( description )
2319 main.case( description )
2320 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002321 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002322
Jon Hall6aec96b2015-01-19 14:49:31 -08002323 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002324 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002325 teststationUser = main.params[ 'TESTONUSER' ]
2326 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002327 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002328 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002329 # FIXME: scp
2330 # mn files
2331 # TODO: Load these from params
2332 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002333 logFolder = "/opt/onos/log/"
2334 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002335 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002336 dstDir = "~/packet_captures/"
2337 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002338 for node in nodes:
2339 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2340 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002341 teststationUser + "@" +
2342 teststationIP + ":" +
2343 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002344 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002345 main.ONOSbench.handle.expect( "\$" )
2346
Jon Hall6aec96b2015-01-19 14:49:31 -08002347 # std*.log's
2348 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002349 logFolder = "/opt/onos/var/"
2350 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002351 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002352 dstDir = "~/packet_captures/"
2353 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002354 for node in nodes:
2355 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2356 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002357 teststationUser + "@" +
2358 teststationIP + ":" +
2359 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002360 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002361 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002362 # sleep so scp can finish
2363 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002364
2365 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002366 mnResult = main.Mininet1.stopNet()
2367 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2368 onpass="Mininet stopped",
2369 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002370
2371 main.step( "Checking ONOS Logs for errors" )
2372 for node in nodes:
2373 print colors[ 'purple' ] + "Checking logs for errors on " + \
2374 node.name + ":" + colors[ 'end' ]
2375 print main.ONOSbench.checkLogs( node.ip_address )
2376
Jon Hall6aec96b2015-01-19 14:49:31 -08002377 main.step( "Packing and rotating pcap archives" )
2378 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002379
Jon Hall390696c2015-05-05 17:13:41 -07002380 try:
2381 gossipIntentLog = open( main.logdir + "/Timers.csv", 'w')
2382 # Overwrite with empty line and close
2383 gossipIntentLog.write( "Gossip Intents\n" )
2384 gossipIntentLog.write( str( gossipTime ) )
2385 gossipIntentLog.close()
2386 except NameError, e:
2387 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002388
Jon Hall6aec96b2015-01-19 14:49:31 -08002389 def CASE14( self, main ):
2390 """
Jon Hall94fd0472014-12-08 11:52:42 -08002391 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002392 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002393 assert numControllers, "numControllers not defined"
2394 assert main, "main not defined"
2395 assert utilities.assert_equals, "utilities.assert_equals not defined"
2396 assert CLIs, "CLIs not defined"
2397 assert nodes, "nodes not defined"
2398
Jon Hall8f89dda2015-01-22 16:03:33 -08002399 leaderResult = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -07002400 main.case("Start Leadership Election app")
2401 main.step( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002402 main.ONOScli1.activateApp( "org.onosproject.election" )
2403 leaders = []
2404 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002405 cli.electionTestRun()
2406 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002407 leader = cli.electionTestLeader()
2408 if leader is None or leader == main.FALSE:
2409 main.log.report( cli.name + ": Leader for the election app " +
2410 "should be an ONOS node, instead got '" +
2411 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002412 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002413 leaders.append( leader )
2414 if len( set( leaders ) ) != 1:
2415 leaderResult = main.FALSE
2416 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2417 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002418 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 main.log.report( "Leadership election tests passed( consistent " +
2420 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002421 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002422 utilities.assert_equals(
2423 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002424 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002425 onpass="Leadership election passed",
2426 onfail="Something went wrong with Leadership election" )
Jon Hall94fd0472014-12-08 11:52:42 -08002427
Jon Hall6aec96b2015-01-19 14:49:31 -08002428 def CASE15( self, main ):
2429 """
Jon Hall669173b2014-12-17 11:36:30 -08002430 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002431 """
Jon Hall390696c2015-05-05 17:13:41 -07002432 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002433 assert numControllers, "numControllers not defined"
2434 assert main, "main not defined"
2435 assert utilities.assert_equals, "utilities.assert_equals not defined"
2436 assert CLIs, "CLIs not defined"
2437 assert nodes, "nodes not defined"
2438
Jon Hall8f89dda2015-01-22 16:03:33 -08002439 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002440 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002441 main.log.report( description )
2442 main.case( description )
2443 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002444 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002445 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002446 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002447 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002448 main.log.report(
2449 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002450 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002451 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002452 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002453 for i in range( len( CLIs ) ):
2454 if leader == nodes[ i ].ip_address:
2455 oldLeader = CLIs[ i ]
2456 break
Jon Halla9d26da2015-03-30 16:45:32 -07002457 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002458 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002459 if oldLeader:
2460 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002461 utilities.assert_equals(
2462 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002463 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002464 onpass="App was withdrawn from election",
2465 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002466
Jon Hall6aec96b2015-01-19 14:49:31 -08002467 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002468 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002469 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002470 for cli in CLIs:
2471 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002472 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002473 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002474 main.log.report( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002475 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002476 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002477 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002478 # error in response
2479 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002480 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002481 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002482 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002483 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002484 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002485 elif leaderN is None:
2486 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002487 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002488 leaderN = cli.electionTestLeader()
2489 leaderList.pop()
2490 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002491 consistentLeader = main.FALSE
2492 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002493 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002494 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002496 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002497 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 main.log.report(
2499 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002500 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002501 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002502 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002503 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002504 if leaderResult:
2505 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002506 "view of leader across listeners and a new " +
2507 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002508 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002509 utilities.assert_equals(
2510 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002511 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002512 onpass="Leadership election passed",
2513 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002514
Jon Hall58c76b72015-02-23 11:09:24 -08002515 main.step( "Run for election on old leader( just so everyone " +
2516 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002517 if oldLeader:
2518 runResult = oldLeader.electionTestRun()
2519 else:
2520 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002521 utilities.assert_equals(
2522 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002523 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002524 onpass="App re-ran for election",
2525 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002526
2527 afterRun = main.ONOScli1.electionTestLeader()
2528 # verify leader didn't just change
2529 if afterRun == leaderList[ 0 ]:
2530 afterResult = main.TRUE
2531 else:
2532 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002533
Jon Hall6aec96b2015-01-19 14:49:31 -08002534 utilities.assert_equals(
2535 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002536 actual=afterResult,
2537 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002538 onfail="Something went wrong with Leadership election after " +
2539 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002540
2541 case15Result = withdrawResult and leaderResult and runResult and\
2542 afterResult
2543 utilities.assert_equals(
2544 expect=main.TRUE,
2545 actual=case15Result,
2546 onpass="Leadership election is still functional",
2547 onfail="Leadership Election is no longer functional" )
2548
2549 def CASE16( self, main ):
2550 """
2551 Install Distributed Primitives app
2552 """
2553 assert numControllers, "numControllers not defined"
2554 assert main, "main not defined"
2555 assert utilities.assert_equals, "utilities.assert_equals not defined"
2556 assert CLIs, "CLIs not defined"
2557 assert nodes, "nodes not defined"
2558
2559 # Variables for the distributed primitives tests
2560 global pCounterName
2561 global iCounterName
2562 global pCounterValue
2563 global iCounterValue
2564 global onosSet
2565 global onosSetName
2566 pCounterName = "TestON-Partitions"
2567 iCounterName = "TestON-inMemory"
2568 pCounterValue = 0
2569 iCounterValue = 0
2570 onosSet = set([])
2571 onosSetName = "TestON-set"
2572
2573 description = "Install Primitives app"
2574 main.case( description )
2575 main.step( "Install Primitives app" )
2576 appName = "org.onosproject.distributedprimitives"
2577 appResults = CLIs[0].activateApp( appName )
2578 utilities.assert_equals( expect=main.TRUE,
2579 actual=appResults,
2580 onpass="Primitives app activated",
2581 onfail="Primitives app not activated" )
2582
2583 def CASE17( self, main ):
2584 """
2585 Check for basic functionality with distributed primitives
2586 """
2587 # Make sure variables are defined/set
2588 assert numControllers, "numControllers not defined"
2589 assert main, "main not defined"
2590 assert utilities.assert_equals, "utilities.assert_equals not defined"
2591 assert CLIs, "CLIs not defined"
2592 assert nodes, "nodes not defined"
2593 assert pCounterName, "pCounterName not defined"
2594 assert iCounterName, "iCounterName not defined"
2595 assert onosSetName, "onosSetName not defined"
2596 # NOTE: assert fails if value is 0/None/Empty/False
2597 try:
2598 pCounterValue
2599 except NameError:
2600 main.log.error( "pCounterValue not defined, setting to 0" )
2601 pCounterValue = 0
2602 try:
2603 iCounterValue
2604 except NameError:
2605 main.log.error( "iCounterValue not defined, setting to 0" )
2606 iCounterValue = 0
2607 try:
2608 onosSet
2609 except NameError:
2610 main.log.error( "onosSet not defined, setting to empty Set" )
2611 onosSet = set([])
2612 # Variables for the distributed primitives tests. These are local only
2613 addValue = "a"
2614 addAllValue = "a b c d e f"
2615 retainValue = "c d e f"
2616
2617 description = "Check for basic functionality with distributed " +\
2618 "primitives"
2619 main.case( description )
2620 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2621 # DISTRIBUTED ATOMIC COUNTERS
2622 main.step( "Increment and get a default counter on each node" )
2623 pCounters = []
2624 threads = []
2625 for i in range( numControllers ):
2626 t = main.Thread( target=CLIs[i].counterTestIncrement,
2627 name="counterIncrement-" + str( i ),
2628 args=[ pCounterName ] )
2629 pCounterValue += 1
2630 threads.append( t )
2631 t.start()
2632
2633 for t in threads:
2634 t.join()
2635 pCounters.append( t.result )
2636 # Check that counter incremented numController times
2637 pCounterResults = True
2638 for i in range( numControllers ):
2639 pCounterResults and ( i + 1 ) in pCounters
2640 utilities.assert_equals( expect=True,
2641 actual=pCounterResults,
2642 onpass="Default counter incremented",
2643 onfail="Error incrementing default" +
2644 " counter" )
2645
2646 main.step( "Increment and get an in memory counter on each node" )
2647 iCounters = []
2648 threads = []
2649 for i in range( numControllers ):
2650 t = main.Thread( target=CLIs[i].counterTestIncrement,
2651 name="icounterIncrement-" + str( i ),
2652 args=[ iCounterName ],
2653 kwargs={ "inMemory": True } )
2654 iCounterValue += 1
2655 threads.append( t )
2656 t.start()
2657
2658 for t in threads:
2659 t.join()
2660 iCounters.append( t.result )
2661 # Check that counter incremented numController times
2662 iCounterResults = True
2663 for i in range( numControllers ):
2664 iCounterResults and ( i + 1 ) in iCounters
2665 utilities.assert_equals( expect=True,
2666 actual=iCounterResults,
2667 onpass="In memory counter incremented",
2668 onfail="Error incrementing in memory" +
2669 " counter" )
2670
2671 main.step( "Check counters are consistant across nodes" )
2672 onosCounters = []
2673 threads = []
2674 for i in range( numControllers ):
2675 t = main.Thread( target=CLIs[i].counters,
2676 name="counters-" + str( i ) )
2677 threads.append( t )
2678 t.start()
2679 for t in threads:
2680 t.join()
2681 onosCounters.append( t.result )
2682 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2683 if all( tmp ):
2684 main.log.info( "Counters are consistent across all nodes" )
2685 consistentCounterResults = main.TRUE
2686 else:
2687 main.log.error( "Counters are not consistent across all nodes" )
2688 consistentCounterResults = main.FALSE
2689 utilities.assert_equals( expect=main.TRUE,
2690 actual=consistentCounterResults,
2691 onpass="ONOS counters are consistent " +
2692 "across nodes",
2693 onfail="ONOS Counters are inconsistent " +
2694 "across nodes" )
2695
2696 main.step( "Counters we added have the correct values" )
2697 correctResults = main.TRUE
2698 for i in range( numControllers ):
2699 current = onosCounters[i]
2700 try:
2701 pValue = current.get( pCounterName )
2702 iValue = current.get( iCounterName )
2703 if pValue == pCounterValue:
2704 main.log.info( "Partitioned counter value is correct" )
2705 else:
2706 main.log.error( "Partitioned counter value is incorrect," +
2707 " expected value: " + str( pCounterValue )
2708 + " current value: " + str( pValue ) )
2709 correctResults = main.FALSE
2710 if iValue == iCounterValue:
2711 main.log.info( "In memory counter value is correct" )
2712 else:
2713 main.log.error( "In memory counter value is incorrect, " +
2714 "expected value: " + str( iCounterValue ) +
2715 " current value: " + str( iValue ) )
2716 correctResults = main.FALSE
2717 except AttributeError, e:
2718 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2719 "is not as expected" )
2720 correctResults = main.FALSE
2721 utilities.assert_equals( expect=main.TRUE,
2722 actual=correctResults,
2723 onpass="Added counters are correct",
2724 onfail="Added counters are incorrect" )
2725 # DISTRIBUTED SETS
2726 main.step( "Distributed Set get" )
2727 size = len( onosSet )
2728 getResponses = []
2729 threads = []
2730 for i in range( numControllers ):
2731 t = main.Thread( target=CLIs[i].setTestGet,
2732 name="setTestGet-" + str( i ),
2733 args=[ onosSetName ] )
2734 threads.append( t )
2735 t.start()
2736 for t in threads:
2737 t.join()
2738 getResponses.append( t.result )
2739
2740 getResults = main.TRUE
2741 for i in range( numControllers ):
2742 if isinstance( getResponses[ i ], list):
2743 current = set( getResponses[ i ] )
2744 if len( current ) == len( getResponses[ i ] ):
2745 # no repeats
2746 if onosSet != current:
2747 main.log.error( "ONOS" + str( i + 1 ) +
2748 " has incorrect view" +
2749 " of set " + onosSetName + ":\n" +
2750 str( getResponses[ i ] ) )
2751 main.log.debug( "Expected: " + str( onosSet ) )
2752 main.log.debug( "Actual: " + str( current ) )
2753 getResults = main.FALSE
2754 else:
2755 # error, set is not a set
2756 main.log.error( "ONOS" + str( i + 1 ) +
2757 " has repeat elements in" +
2758 " set " + onosSetName + ":\n" +
2759 str( getResponses[ i ] ) )
2760 getResults = main.FALSE
2761 elif getResponses[ i ] == main.ERROR:
2762 getResults = main.FALSE
2763 utilities.assert_equals( expect=main.TRUE,
2764 actual=getResults,
2765 onpass="Set elements are correct",
2766 onfail="Set elements are incorrect" )
2767
2768 main.step( "Distributed Set size" )
2769 sizeResponses = []
2770 threads = []
2771 for i in range( numControllers ):
2772 t = main.Thread( target=CLIs[i].setTestSize,
2773 name="setTestSize-" + str( i ),
2774 args=[ onosSetName ] )
2775 threads.append( t )
2776 t.start()
2777 for t in threads:
2778 t.join()
2779 sizeResponses.append( t.result )
2780
2781 sizeResults = main.TRUE
2782 for i in range( numControllers ):
2783 if size != sizeResponses[ i ]:
2784 sizeResults = main.FALSE
2785 main.log.error( "ONOS" + str( i + 1 ) +
2786 " expected a size of " + str( size ) +
2787 " for set " + onosSetName +
2788 " but got " + str( sizeResponses[ i ] ) )
2789 utilities.assert_equals( expect=main.TRUE,
2790 actual=sizeResults,
2791 onpass="Set sizes are correct",
2792 onfail="Set sizes are incorrect" )
2793
2794 main.step( "Distributed Set add()" )
2795 onosSet.add( addValue )
2796 addResponses = []
2797 threads = []
2798 for i in range( numControllers ):
2799 t = main.Thread( target=CLIs[i].setTestAdd,
2800 name="setTestAdd-" + str( i ),
2801 args=[ onosSetName, addValue ] )
2802 threads.append( t )
2803 t.start()
2804 for t in threads:
2805 t.join()
2806 addResponses.append( t.result )
2807
2808 # main.TRUE = successfully changed the set
2809 # main.FALSE = action resulted in no change in set
2810 # main.ERROR - Some error in executing the function
2811 addResults = main.TRUE
2812 for i in range( numControllers ):
2813 if addResponses[ i ] == main.TRUE:
2814 # All is well
2815 pass
2816 elif addResponses[ i ] == main.FALSE:
2817 # Already in set, probably fine
2818 pass
2819 elif addResponses[ i ] == main.ERROR:
2820 # Error in execution
2821 addResults = main.FALSE
2822 else:
2823 # unexpected result
2824 addResults = main.FALSE
2825 if addResults != main.TRUE:
2826 main.log.error( "Error executing set add" )
2827
2828 # Check if set is still correct
2829 size = len( onosSet )
2830 getResponses = []
2831 threads = []
2832 for i in range( numControllers ):
2833 t = main.Thread( target=CLIs[i].setTestGet,
2834 name="setTestGet-" + str( i ),
2835 args=[ onosSetName ] )
2836 threads.append( t )
2837 t.start()
2838 for t in threads:
2839 t.join()
2840 getResponses.append( t.result )
2841 getResults = main.TRUE
2842 for i in range( numControllers ):
2843 if isinstance( getResponses[ i ], list):
2844 current = set( getResponses[ i ] )
2845 if len( current ) == len( getResponses[ i ] ):
2846 # no repeats
2847 if onosSet != current:
2848 main.log.error( "ONOS" + str( i + 1 ) +
2849 " has incorrect view" +
2850 " of set " + onosSetName + ":\n" +
2851 str( getResponses[ i ] ) )
2852 main.log.debug( "Expected: " + str( onosSet ) )
2853 main.log.debug( "Actual: " + str( current ) )
2854 getResults = main.FALSE
2855 else:
2856 # error, set is not a set
2857 main.log.error( "ONOS" + str( i + 1 ) +
2858 " has repeat elements in" +
2859 " set " + onosSetName + ":\n" +
2860 str( getResponses[ i ] ) )
2861 getResults = main.FALSE
2862 elif getResponses[ i ] == main.ERROR:
2863 getResults = main.FALSE
2864 sizeResponses = []
2865 threads = []
2866 for i in range( numControllers ):
2867 t = main.Thread( target=CLIs[i].setTestSize,
2868 name="setTestSize-" + str( i ),
2869 args=[ onosSetName ] )
2870 threads.append( t )
2871 t.start()
2872 for t in threads:
2873 t.join()
2874 sizeResponses.append( t.result )
2875 sizeResults = main.TRUE
2876 for i in range( numControllers ):
2877 if size != sizeResponses[ i ]:
2878 sizeResults = main.FALSE
2879 main.log.error( "ONOS" + str( i + 1 ) +
2880 " expected a size of " + str( size ) +
2881 " for set " + onosSetName +
2882 " but got " + str( sizeResponses[ i ] ) )
2883 addResults = addResults and getResults and sizeResults
2884 utilities.assert_equals( expect=main.TRUE,
2885 actual=addResults,
2886 onpass="Set add correct",
2887 onfail="Set add was incorrect" )
2888
2889 main.step( "Distributed Set addAll()" )
2890 onosSet.update( addAllValue.split() )
2891 addResponses = []
2892 threads = []
2893 for i in range( numControllers ):
2894 t = main.Thread( target=CLIs[i].setTestAdd,
2895 name="setTestAddAll-" + str( i ),
2896 args=[ onosSetName, addAllValue ] )
2897 threads.append( t )
2898 t.start()
2899 for t in threads:
2900 t.join()
2901 addResponses.append( t.result )
2902
2903 # main.TRUE = successfully changed the set
2904 # main.FALSE = action resulted in no change in set
2905 # main.ERROR - Some error in executing the function
2906 addAllResults = main.TRUE
2907 for i in range( numControllers ):
2908 if addResponses[ i ] == main.TRUE:
2909 # All is well
2910 pass
2911 elif addResponses[ i ] == main.FALSE:
2912 # Already in set, probably fine
2913 pass
2914 elif addResponses[ i ] == main.ERROR:
2915 # Error in execution
2916 addAllResults = main.FALSE
2917 else:
2918 # unexpected result
2919 addAllResults = main.FALSE
2920 if addAllResults != main.TRUE:
2921 main.log.error( "Error executing set addAll" )
2922
2923 # Check if set is still correct
2924 size = len( onosSet )
2925 getResponses = []
2926 threads = []
2927 for i in range( numControllers ):
2928 t = main.Thread( target=CLIs[i].setTestGet,
2929 name="setTestGet-" + str( i ),
2930 args=[ onosSetName ] )
2931 threads.append( t )
2932 t.start()
2933 for t in threads:
2934 t.join()
2935 getResponses.append( t.result )
2936 getResults = main.TRUE
2937 for i in range( numControllers ):
2938 if isinstance( getResponses[ i ], list):
2939 current = set( getResponses[ i ] )
2940 if len( current ) == len( getResponses[ i ] ):
2941 # no repeats
2942 if onosSet != current:
2943 main.log.error( "ONOS" + str( i + 1 ) +
2944 " has incorrect view" +
2945 " of set " + onosSetName + ":\n" +
2946 str( getResponses[ i ] ) )
2947 main.log.debug( "Expected: " + str( onosSet ) )
2948 main.log.debug( "Actual: " + str( current ) )
2949 getResults = main.FALSE
2950 else:
2951 # error, set is not a set
2952 main.log.error( "ONOS" + str( i + 1 ) +
2953 " has repeat elements in" +
2954 " set " + onosSetName + ":\n" +
2955 str( getResponses[ i ] ) )
2956 getResults = main.FALSE
2957 elif getResponses[ i ] == main.ERROR:
2958 getResults = main.FALSE
2959 sizeResponses = []
2960 threads = []
2961 for i in range( numControllers ):
2962 t = main.Thread( target=CLIs[i].setTestSize,
2963 name="setTestSize-" + str( i ),
2964 args=[ onosSetName ] )
2965 threads.append( t )
2966 t.start()
2967 for t in threads:
2968 t.join()
2969 sizeResponses.append( t.result )
2970 sizeResults = main.TRUE
2971 for i in range( numControllers ):
2972 if size != sizeResponses[ i ]:
2973 sizeResults = main.FALSE
2974 main.log.error( "ONOS" + str( i + 1 ) +
2975 " expected a size of " + str( size ) +
2976 " for set " + onosSetName +
2977 " but got " + str( sizeResponses[ i ] ) )
2978 addAllResults = addAllResults and getResults and sizeResults
2979 utilities.assert_equals( expect=main.TRUE,
2980 actual=addAllResults,
2981 onpass="Set addAll correct",
2982 onfail="Set addAll was incorrect" )
2983
2984 main.step( "Distributed Set contains()" )
2985 containsResponses = []
2986 threads = []
2987 for i in range( numControllers ):
2988 t = main.Thread( target=CLIs[i].setTestGet,
2989 name="setContains-" + str( i ),
2990 args=[ onosSetName ],
2991 kwargs={ "values": addValue } )
2992 threads.append( t )
2993 t.start()
2994 for t in threads:
2995 t.join()
2996 # NOTE: This is the tuple
2997 containsResponses.append( t.result )
2998
2999 containsResults = main.TRUE
3000 for i in range( numControllers ):
3001 if containsResponses[ i ] == main.ERROR:
3002 containsResults = main.FALSE
3003 else:
3004 containsResults = containsResults and\
3005 containsResponses[ i ][ 1 ]
3006 utilities.assert_equals( expect=main.TRUE,
3007 actual=containsResults,
3008 onpass="Set contains is functional",
3009 onfail="Set contains failed" )
3010
3011 main.step( "Distributed Set containsAll()" )
3012 containsAllResponses = []
3013 threads = []
3014 for i in range( numControllers ):
3015 t = main.Thread( target=CLIs[i].setTestGet,
3016 name="setContainsAll-" + str( i ),
3017 args=[ onosSetName ],
3018 kwargs={ "values": addAllValue } )
3019 threads.append( t )
3020 t.start()
3021 for t in threads:
3022 t.join()
3023 # NOTE: This is the tuple
3024 containsAllResponses.append( t.result )
3025
3026 containsAllResults = main.TRUE
3027 for i in range( numControllers ):
3028 if containsResponses[ i ] == main.ERROR:
3029 containsResults = main.FALSE
3030 else:
3031 containsResults = containsResults and\
3032 containsResponses[ i ][ 1 ]
3033 utilities.assert_equals( expect=main.TRUE,
3034 actual=containsAllResults,
3035 onpass="Set containsAll is functional",
3036 onfail="Set containsAll failed" )
3037
3038 main.step( "Distributed Set remove()" )
3039 onosSet.remove( addValue )
3040 removeResponses = []
3041 threads = []
3042 for i in range( numControllers ):
3043 t = main.Thread( target=CLIs[i].setTestRemove,
3044 name="setTestRemove-" + str( i ),
3045 args=[ onosSetName, addValue ] )
3046 threads.append( t )
3047 t.start()
3048 for t in threads:
3049 t.join()
3050 removeResponses.append( t.result )
3051
3052 # main.TRUE = successfully changed the set
3053 # main.FALSE = action resulted in no change in set
3054 # main.ERROR - Some error in executing the function
3055 removeResults = main.TRUE
3056 for i in range( numControllers ):
3057 if removeResponses[ i ] == main.TRUE:
3058 # All is well
3059 pass
3060 elif removeResponses[ i ] == main.FALSE:
3061 # not in set, probably fine
3062 pass
3063 elif removeResponses[ i ] == main.ERROR:
3064 # Error in execution
3065 removeResults = main.FALSE
3066 else:
3067 # unexpected result
3068 removeResults = main.FALSE
3069 if removeResults != main.TRUE:
3070 main.log.error( "Error executing set remove" )
3071
3072 # Check if set is still correct
3073 size = len( onosSet )
3074 getResponses = []
3075 threads = []
3076 for i in range( numControllers ):
3077 t = main.Thread( target=CLIs[i].setTestGet,
3078 name="setTestGet-" + str( i ),
3079 args=[ onosSetName ] )
3080 threads.append( t )
3081 t.start()
3082 for t in threads:
3083 t.join()
3084 getResponses.append( t.result )
3085 getResults = main.TRUE
3086 for i in range( numControllers ):
3087 if isinstance( getResponses[ i ], list):
3088 current = set( getResponses[ i ] )
3089 if len( current ) == len( getResponses[ i ] ):
3090 # no repeats
3091 if onosSet != current:
3092 main.log.error( "ONOS" + str( i + 1 ) +
3093 " has incorrect view" +
3094 " of set " + onosSetName + ":\n" +
3095 str( getResponses[ i ] ) )
3096 main.log.debug( "Expected: " + str( onosSet ) )
3097 main.log.debug( "Actual: " + str( current ) )
3098 getResults = main.FALSE
3099 else:
3100 # error, set is not a set
3101 main.log.error( "ONOS" + str( i + 1 ) +
3102 " has repeat elements in" +
3103 " set " + onosSetName + ":\n" +
3104 str( getResponses[ i ] ) )
3105 getResults = main.FALSE
3106 elif getResponses[ i ] == main.ERROR:
3107 getResults = main.FALSE
3108 sizeResponses = []
3109 threads = []
3110 for i in range( numControllers ):
3111 t = main.Thread( target=CLIs[i].setTestSize,
3112 name="setTestSize-" + str( i ),
3113 args=[ onosSetName ] )
3114 threads.append( t )
3115 t.start()
3116 for t in threads:
3117 t.join()
3118 sizeResponses.append( t.result )
3119 sizeResults = main.TRUE
3120 for i in range( numControllers ):
3121 if size != sizeResponses[ i ]:
3122 sizeResults = main.FALSE
3123 main.log.error( "ONOS" + str( i + 1 ) +
3124 " expected a size of " + str( size ) +
3125 " for set " + onosSetName +
3126 " but got " + str( sizeResponses[ i ] ) )
3127 removeResults = removeResults and getResults and sizeResults
3128 utilities.assert_equals( expect=main.TRUE,
3129 actual=removeResults,
3130 onpass="Set remove correct",
3131 onfail="Set remove was incorrect" )
3132
3133 main.step( "Distributed Set removeAll()" )
3134 onosSet.difference_update( addAllValue.split() )
3135 removeAllResponses = []
3136 threads = []
3137 try:
3138 for i in range( numControllers ):
3139 t = main.Thread( target=CLIs[i].setTestRemove,
3140 name="setTestRemoveAll-" + str( i ),
3141 args=[ onosSetName, addAllValue ] )
3142 threads.append( t )
3143 t.start()
3144 for t in threads:
3145 t.join()
3146 removeAllResponses.append( t.result )
3147 except Exception, e:
3148 main.log.exception(e)
3149
3150 # main.TRUE = successfully changed the set
3151 # main.FALSE = action resulted in no change in set
3152 # main.ERROR - Some error in executing the function
3153 removeAllResults = main.TRUE
3154 for i in range( numControllers ):
3155 if removeAllResponses[ i ] == main.TRUE:
3156 # All is well
3157 pass
3158 elif removeAllResponses[ i ] == main.FALSE:
3159 # not in set, probably fine
3160 pass
3161 elif removeAllResponses[ i ] == main.ERROR:
3162 # Error in execution
3163 removeAllResults = main.FALSE
3164 else:
3165 # unexpected result
3166 removeAllResults = main.FALSE
3167 if removeAllResults != main.TRUE:
3168 main.log.error( "Error executing set removeAll" )
3169
3170 # Check if set is still correct
3171 size = len( onosSet )
3172 getResponses = []
3173 threads = []
3174 for i in range( numControllers ):
3175 t = main.Thread( target=CLIs[i].setTestGet,
3176 name="setTestGet-" + str( i ),
3177 args=[ onosSetName ] )
3178 threads.append( t )
3179 t.start()
3180 for t in threads:
3181 t.join()
3182 getResponses.append( t.result )
3183 getResults = main.TRUE
3184 for i in range( numControllers ):
3185 if isinstance( getResponses[ i ], list):
3186 current = set( getResponses[ i ] )
3187 if len( current ) == len( getResponses[ i ] ):
3188 # no repeats
3189 if onosSet != current:
3190 main.log.error( "ONOS" + str( i + 1 ) +
3191 " has incorrect view" +
3192 " of set " + onosSetName + ":\n" +
3193 str( getResponses[ i ] ) )
3194 main.log.debug( "Expected: " + str( onosSet ) )
3195 main.log.debug( "Actual: " + str( current ) )
3196 getResults = main.FALSE
3197 else:
3198 # error, set is not a set
3199 main.log.error( "ONOS" + str( i + 1 ) +
3200 " has repeat elements in" +
3201 " set " + onosSetName + ":\n" +
3202 str( getResponses[ i ] ) )
3203 getResults = main.FALSE
3204 elif getResponses[ i ] == main.ERROR:
3205 getResults = main.FALSE
3206 sizeResponses = []
3207 threads = []
3208 for i in range( numControllers ):
3209 t = main.Thread( target=CLIs[i].setTestSize,
3210 name="setTestSize-" + str( i ),
3211 args=[ onosSetName ] )
3212 threads.append( t )
3213 t.start()
3214 for t in threads:
3215 t.join()
3216 sizeResponses.append( t.result )
3217 sizeResults = main.TRUE
3218 for i in range( numControllers ):
3219 if size != sizeResponses[ i ]:
3220 sizeResults = main.FALSE
3221 main.log.error( "ONOS" + str( i + 1 ) +
3222 " expected a size of " + str( size ) +
3223 " for set " + onosSetName +
3224 " but got " + str( sizeResponses[ i ] ) )
3225 removeAllResults = removeAllResults and getResults and sizeResults
3226 utilities.assert_equals( expect=main.TRUE,
3227 actual=removeAllResults,
3228 onpass="Set removeAll correct",
3229 onfail="Set removeAll was incorrect" )
3230
3231 main.step( "Distributed Set addAll()" )
3232 onosSet.update( addAllValue.split() )
3233 addResponses = []
3234 threads = []
3235 for i in range( numControllers ):
3236 t = main.Thread( target=CLIs[i].setTestAdd,
3237 name="setTestAddAll-" + str( i ),
3238 args=[ onosSetName, addAllValue ] )
3239 threads.append( t )
3240 t.start()
3241 for t in threads:
3242 t.join()
3243 addResponses.append( t.result )
3244
3245 # main.TRUE = successfully changed the set
3246 # main.FALSE = action resulted in no change in set
3247 # main.ERROR - Some error in executing the function
3248 addAllResults = main.TRUE
3249 for i in range( numControllers ):
3250 if addResponses[ i ] == main.TRUE:
3251 # All is well
3252 pass
3253 elif addResponses[ i ] == main.FALSE:
3254 # Already in set, probably fine
3255 pass
3256 elif addResponses[ i ] == main.ERROR:
3257 # Error in execution
3258 addAllResults = main.FALSE
3259 else:
3260 # unexpected result
3261 addAllResults = main.FALSE
3262 if addAllResults != main.TRUE:
3263 main.log.error( "Error executing set addAll" )
3264
3265 # Check if set is still correct
3266 size = len( onosSet )
3267 getResponses = []
3268 threads = []
3269 for i in range( numControllers ):
3270 t = main.Thread( target=CLIs[i].setTestGet,
3271 name="setTestGet-" + str( i ),
3272 args=[ onosSetName ] )
3273 threads.append( t )
3274 t.start()
3275 for t in threads:
3276 t.join()
3277 getResponses.append( t.result )
3278 getResults = main.TRUE
3279 for i in range( numControllers ):
3280 if isinstance( getResponses[ i ], list):
3281 current = set( getResponses[ i ] )
3282 if len( current ) == len( getResponses[ i ] ):
3283 # no repeats
3284 if onosSet != current:
3285 main.log.error( "ONOS" + str( i + 1 ) +
3286 " has incorrect view" +
3287 " of set " + onosSetName + ":\n" +
3288 str( getResponses[ i ] ) )
3289 main.log.debug( "Expected: " + str( onosSet ) )
3290 main.log.debug( "Actual: " + str( current ) )
3291 getResults = main.FALSE
3292 else:
3293 # error, set is not a set
3294 main.log.error( "ONOS" + str( i + 1 ) +
3295 " has repeat elements in" +
3296 " set " + onosSetName + ":\n" +
3297 str( getResponses[ i ] ) )
3298 getResults = main.FALSE
3299 elif getResponses[ i ] == main.ERROR:
3300 getResults = main.FALSE
3301 sizeResponses = []
3302 threads = []
3303 for i in range( numControllers ):
3304 t = main.Thread( target=CLIs[i].setTestSize,
3305 name="setTestSize-" + str( i ),
3306 args=[ onosSetName ] )
3307 threads.append( t )
3308 t.start()
3309 for t in threads:
3310 t.join()
3311 sizeResponses.append( t.result )
3312 sizeResults = main.TRUE
3313 for i in range( numControllers ):
3314 if size != sizeResponses[ i ]:
3315 sizeResults = main.FALSE
3316 main.log.error( "ONOS" + str( i + 1 ) +
3317 " expected a size of " + str( size ) +
3318 " for set " + onosSetName +
3319 " but got " + str( sizeResponses[ i ] ) )
3320 addAllResults = addAllResults and getResults and sizeResults
3321 utilities.assert_equals( expect=main.TRUE,
3322 actual=addAllResults,
3323 onpass="Set addAll correct",
3324 onfail="Set addAll was incorrect" )
3325
3326 main.step( "Distributed Set clear()" )
3327 onosSet.clear()
3328 clearResponses = []
3329 threads = []
3330 for i in range( numControllers ):
3331 t = main.Thread( target=CLIs[i].setTestRemove,
3332 name="setTestClear-" + str( i ),
3333 args=[ onosSetName, " "], # Values doesn't matter
3334 kwargs={ "clear": True } )
3335 threads.append( t )
3336 t.start()
3337 for t in threads:
3338 t.join()
3339 clearResponses.append( t.result )
3340
3341 # main.TRUE = successfully changed the set
3342 # main.FALSE = action resulted in no change in set
3343 # main.ERROR - Some error in executing the function
3344 clearResults = main.TRUE
3345 for i in range( numControllers ):
3346 if clearResponses[ i ] == main.TRUE:
3347 # All is well
3348 pass
3349 elif clearResponses[ i ] == main.FALSE:
3350 # Nothing set, probably fine
3351 pass
3352 elif clearResponses[ i ] == main.ERROR:
3353 # Error in execution
3354 clearResults = main.FALSE
3355 else:
3356 # unexpected result
3357 clearResults = main.FALSE
3358 if clearResults != main.TRUE:
3359 main.log.error( "Error executing set clear" )
3360
3361 # Check if set is still correct
3362 size = len( onosSet )
3363 getResponses = []
3364 threads = []
3365 for i in range( numControllers ):
3366 t = main.Thread( target=CLIs[i].setTestGet,
3367 name="setTestGet-" + str( i ),
3368 args=[ onosSetName ] )
3369 threads.append( t )
3370 t.start()
3371 for t in threads:
3372 t.join()
3373 getResponses.append( t.result )
3374 getResults = main.TRUE
3375 for i in range( numControllers ):
3376 if isinstance( getResponses[ i ], list):
3377 current = set( getResponses[ i ] )
3378 if len( current ) == len( getResponses[ i ] ):
3379 # no repeats
3380 if onosSet != current:
3381 main.log.error( "ONOS" + str( i + 1 ) +
3382 " has incorrect view" +
3383 " of set " + onosSetName + ":\n" +
3384 str( getResponses[ i ] ) )
3385 main.log.debug( "Expected: " + str( onosSet ) )
3386 main.log.debug( "Actual: " + str( current ) )
3387 getResults = main.FALSE
3388 else:
3389 # error, set is not a set
3390 main.log.error( "ONOS" + str( i + 1 ) +
3391 " has repeat elements in" +
3392 " set " + onosSetName + ":\n" +
3393 str( getResponses[ i ] ) )
3394 getResults = main.FALSE
3395 elif getResponses[ i ] == main.ERROR:
3396 getResults = main.FALSE
3397 sizeResponses = []
3398 threads = []
3399 for i in range( numControllers ):
3400 t = main.Thread( target=CLIs[i].setTestSize,
3401 name="setTestSize-" + str( i ),
3402 args=[ onosSetName ] )
3403 threads.append( t )
3404 t.start()
3405 for t in threads:
3406 t.join()
3407 sizeResponses.append( t.result )
3408 sizeResults = main.TRUE
3409 for i in range( numControllers ):
3410 if size != sizeResponses[ i ]:
3411 sizeResults = main.FALSE
3412 main.log.error( "ONOS" + str( i + 1 ) +
3413 " expected a size of " + str( size ) +
3414 " for set " + onosSetName +
3415 " but got " + str( sizeResponses[ i ] ) )
3416 clearResults = clearResults and getResults and sizeResults
3417 utilities.assert_equals( expect=main.TRUE,
3418 actual=clearResults,
3419 onpass="Set clear correct",
3420 onfail="Set clear was incorrect" )
3421
3422 main.step( "Distributed Set addAll()" )
3423 onosSet.update( addAllValue.split() )
3424 addResponses = []
3425 threads = []
3426 for i in range( numControllers ):
3427 t = main.Thread( target=CLIs[i].setTestAdd,
3428 name="setTestAddAll-" + str( i ),
3429 args=[ onosSetName, addAllValue ] )
3430 threads.append( t )
3431 t.start()
3432 for t in threads:
3433 t.join()
3434 addResponses.append( t.result )
3435
3436 # main.TRUE = successfully changed the set
3437 # main.FALSE = action resulted in no change in set
3438 # main.ERROR - Some error in executing the function
3439 addAllResults = main.TRUE
3440 for i in range( numControllers ):
3441 if addResponses[ i ] == main.TRUE:
3442 # All is well
3443 pass
3444 elif addResponses[ i ] == main.FALSE:
3445 # Already in set, probably fine
3446 pass
3447 elif addResponses[ i ] == main.ERROR:
3448 # Error in execution
3449 addAllResults = main.FALSE
3450 else:
3451 # unexpected result
3452 addAllResults = main.FALSE
3453 if addAllResults != main.TRUE:
3454 main.log.error( "Error executing set addAll" )
3455
3456 # Check if set is still correct
3457 size = len( onosSet )
3458 getResponses = []
3459 threads = []
3460 for i in range( numControllers ):
3461 t = main.Thread( target=CLIs[i].setTestGet,
3462 name="setTestGet-" + str( i ),
3463 args=[ onosSetName ] )
3464 threads.append( t )
3465 t.start()
3466 for t in threads:
3467 t.join()
3468 getResponses.append( t.result )
3469 getResults = main.TRUE
3470 for i in range( numControllers ):
3471 if isinstance( getResponses[ i ], list):
3472 current = set( getResponses[ i ] )
3473 if len( current ) == len( getResponses[ i ] ):
3474 # no repeats
3475 if onosSet != current:
3476 main.log.error( "ONOS" + str( i + 1 ) +
3477 " has incorrect view" +
3478 " of set " + onosSetName + ":\n" +
3479 str( getResponses[ i ] ) )
3480 main.log.debug( "Expected: " + str( onosSet ) )
3481 main.log.debug( "Actual: " + str( current ) )
3482 getResults = main.FALSE
3483 else:
3484 # error, set is not a set
3485 main.log.error( "ONOS" + str( i + 1 ) +
3486 " has repeat elements in" +
3487 " set " + onosSetName + ":\n" +
3488 str( getResponses[ i ] ) )
3489 getResults = main.FALSE
3490 elif getResponses[ i ] == main.ERROR:
3491 getResults = main.FALSE
3492 sizeResponses = []
3493 threads = []
3494 for i in range( numControllers ):
3495 t = main.Thread( target=CLIs[i].setTestSize,
3496 name="setTestSize-" + str( i ),
3497 args=[ onosSetName ] )
3498 threads.append( t )
3499 t.start()
3500 for t in threads:
3501 t.join()
3502 sizeResponses.append( t.result )
3503 sizeResults = main.TRUE
3504 for i in range( numControllers ):
3505 if size != sizeResponses[ i ]:
3506 sizeResults = main.FALSE
3507 main.log.error( "ONOS" + str( i + 1 ) +
3508 " expected a size of " + str( size ) +
3509 " for set " + onosSetName +
3510 " but got " + str( sizeResponses[ i ] ) )
3511 addAllResults = addAllResults and getResults and sizeResults
3512 utilities.assert_equals( expect=main.TRUE,
3513 actual=addAllResults,
3514 onpass="Set addAll correct",
3515 onfail="Set addAll was incorrect" )
3516
3517 main.step( "Distributed Set retain()" )
3518 onosSet.intersection_update( retainValue.split() )
3519 retainResponses = []
3520 threads = []
3521 for i in range( numControllers ):
3522 t = main.Thread( target=CLIs[i].setTestRemove,
3523 name="setTestRetain-" + str( i ),
3524 args=[ onosSetName, retainValue ],
3525 kwargs={ "retain": True } )
3526 threads.append( t )
3527 t.start()
3528 for t in threads:
3529 t.join()
3530 retainResponses.append( t.result )
3531
3532 # main.TRUE = successfully changed the set
3533 # main.FALSE = action resulted in no change in set
3534 # main.ERROR - Some error in executing the function
3535 retainResults = main.TRUE
3536 for i in range( numControllers ):
3537 if retainResponses[ i ] == main.TRUE:
3538 # All is well
3539 pass
3540 elif retainResponses[ i ] == main.FALSE:
3541 # Already in set, probably fine
3542 pass
3543 elif retainResponses[ i ] == main.ERROR:
3544 # Error in execution
3545 retainResults = main.FALSE
3546 else:
3547 # unexpected result
3548 retainResults = main.FALSE
3549 if retainResults != main.TRUE:
3550 main.log.error( "Error executing set retain" )
3551
3552 # Check if set is still correct
3553 size = len( onosSet )
3554 getResponses = []
3555 threads = []
3556 for i in range( numControllers ):
3557 t = main.Thread( target=CLIs[i].setTestGet,
3558 name="setTestGet-" + str( i ),
3559 args=[ onosSetName ] )
3560 threads.append( t )
3561 t.start()
3562 for t in threads:
3563 t.join()
3564 getResponses.append( t.result )
3565 getResults = main.TRUE
3566 for i in range( numControllers ):
3567 if isinstance( getResponses[ i ], list):
3568 current = set( getResponses[ i ] )
3569 if len( current ) == len( getResponses[ i ] ):
3570 # no repeats
3571 if onosSet != current:
3572 main.log.error( "ONOS" + str( i + 1 ) +
3573 " has incorrect view" +
3574 " of set " + onosSetName + ":\n" +
3575 str( getResponses[ i ] ) )
3576 main.log.debug( "Expected: " + str( onosSet ) )
3577 main.log.debug( "Actual: " + str( current ) )
3578 getResults = main.FALSE
3579 else:
3580 # error, set is not a set
3581 main.log.error( "ONOS" + str( i + 1 ) +
3582 " has repeat elements in" +
3583 " set " + onosSetName + ":\n" +
3584 str( getResponses[ i ] ) )
3585 getResults = main.FALSE
3586 elif getResponses[ i ] == main.ERROR:
3587 getResults = main.FALSE
3588 sizeResponses = []
3589 threads = []
3590 for i in range( numControllers ):
3591 t = main.Thread( target=CLIs[i].setTestSize,
3592 name="setTestSize-" + str( i ),
3593 args=[ onosSetName ] )
3594 threads.append( t )
3595 t.start()
3596 for t in threads:
3597 t.join()
3598 sizeResponses.append( t.result )
3599 sizeResults = main.TRUE
3600 for i in range( numControllers ):
3601 if size != sizeResponses[ i ]:
3602 sizeResults = main.FALSE
3603 main.log.error( "ONOS" + str( i + 1 ) +
3604 " expected a size of " +
3605 str( size ) + " for set " + onosSetName +
3606 " but got " + str( sizeResponses[ i ] ) )
3607 retainResults = retainResults and getResults and sizeResults
3608 utilities.assert_equals( expect=main.TRUE,
3609 actual=retainResults,
3610 onpass="Set retain correct",
3611 onfail="Set retain was incorrect" )
3612