blob: fe513ac6a0e242047a3b0d69838f51347953b2de [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" )
Jon Hallfeff3082015-05-19 10:23:26 -070052 main.caseExplaination = "Setup the test environment including " +\
53 "installing ONOS, starting Mininet and ONOS" +\
54 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080055 # TODO: save all the timers and output them for plotting
Jon Hallb1290e82014-11-18 16:17:48 -050056
Jon Hall65844a32015-03-09 19:09:37 -070057 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080058 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080059 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080060 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080061 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080062 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080063
64 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS7Port
72 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080073 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall5cfd23c2015-03-19 11:40:57 -070074
Jon Hall65844a32015-03-09 19:09:37 -070075 # FIXME: just get controller port from params?
76 # TODO: do we really need all these?
77 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
78 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
79 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
80 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
81 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
82 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
83 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
84
85 global CLIs
86 CLIs = []
87 global nodes
88 nodes = []
89 for i in range( 1, numControllers + 1 ):
90 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
91 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -050092
Jon Hall6aec96b2015-01-19 14:49:31 -080093 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080094 cellResult = main.ONOSbench.setCell( cellName )
95 verifyResult = main.ONOSbench.verifyCell()
Jon Hall368769f2014-11-19 15:43:35 -080096
Jon Hall6aec96b2015-01-19 14:49:31 -080097 # FIXME:this is short term fix
98 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080099 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall65844a32015-03-09 19:09:37 -0700100
Jon Hall6aec96b2015-01-19 14:49:31 -0800101 main.log.report( "Uninstalling ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -0700102 for node in nodes:
103 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hallb1290e82014-11-18 16:17:48 -0500104
Jon Hall390696c2015-05-05 17:13:41 -0700105 # Make sure ONOS is DEAD
106 main.log.report( "Killing any ONOS processes" )
107 killResults = main.TRUE
108 for node in nodes:
109 killed = main.ONOSbench.onosKill( node.ip_address )
110 killResults = killResults and killed
111
Jon Hall8f89dda2015-01-22 16:03:33 -0800112 cleanInstallResult = main.TRUE
113 gitPullResult = main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -0500114
Jon Hall97f31752015-02-04 12:01:04 -0800115 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700116 mnResult = main.Mininet1.startNet( )
117 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
118 onpass="Mininet Started",
119 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800120
Jon Hallfeff3082015-05-19 10:23:26 -0700121 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800123 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800124 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700125 # values of 1 or 3 are good
126 utilities.assert_lesser( expect=0, actual=gitPullResult,
127 onpass="Git pull successful",
128 onfail="Git pull failed" )
Jon Hall529a37f2015-01-28 10:02:00 -0800129 else:
130 main.log.warn( "Did not pull new code so skipping mvn " +
131 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800132 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700133
134 main.step( "Using mvn clean install" )
135 cleanInstallResult = main.TRUE
136 if gitPullResult == main.TRUE:
137 cleanInstallResult = main.ONOSbench.cleanInstall()
138 utilities.assert_equals( expect=main.TRUE,
139 actual=cleanInstallResult,
140 onpass="MCI successful",
141 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700142 # GRAPHS
143 # NOTE: important params here:
144 # job = name of Jenkins job
145 # Plot Name = Plot-HA, only can be used if multiple plots
146 # index = The number of the graph under plot name
147 job = "HASanity"
148 plotName = "Plot-HA"
149 graphs = '<ac:structured-macro ac:name="html">\n'
150 graphs += '<ac:plain-text-body><![CDATA[\n'
151 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
152 '/plot/' + plotName + '/getPlot?index=0' +\
153 '&width=500&height=300"' +\
154 'noborder="0" width="500" height="300" scrolling="yes" ' +\
155 'seamless="seamless"></iframe>\n'
156 graphs += ']]></ac:plain-text-body>\n'
157 graphs += '</ac:structured-macro>\n'
158 main.log.wiki(graphs)
Jon Hallb1290e82014-11-18 16:17:48 -0500159
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800161 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700162 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
163 onpass="ONOS package successful",
164 onfail="ONOS package failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500165
Jon Hall6aec96b2015-01-19 14:49:31 -0800166 main.step( "Installing ONOS package" )
Jon Hall65844a32015-03-09 19:09:37 -0700167 onosInstallResult = main.TRUE
168 for node in nodes:
169 tmpResult = main.ONOSbench.onosInstall( options="-f",
170 node=node.ip_address )
171 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700172 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
173 onpass="ONOS install successful",
174 onfail="ONOS install failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500175
Jon Hall6aec96b2015-01-19 14:49:31 -0800176 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 for i in range( 2 ):
Jon Hall65844a32015-03-09 19:09:37 -0700178 onosIsupResult = main.TRUE
179 for node in nodes:
180 started = main.ONOSbench.isup( node.ip_address )
181 if not started:
182 main.log.report( node.name + " didn't start!" )
183 main.ONOSbench.onosStop( node.ip_address )
184 main.ONOSbench.onosStart( node.ip_address )
185 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800186 if onosIsupResult == main.TRUE:
Jon Hallffb386d2014-11-21 13:43:38 -0800187 break
Jon Hall390696c2015-05-05 17:13:41 -0700188 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
189 onpass="ONOS startup successful",
190 onfail="ONOS startup failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500191
Jon Hall65844a32015-03-09 19:09:37 -0700192 main.log.step( "Starting ONOS CLI sessions" )
193 cliResults = main.TRUE
194 threads = []
195 for i in range( numControllers ):
196 t = main.Thread( target=CLIs[i].startOnosCli,
Jon Hall65844a32015-03-09 19:09:37 -0700197 name="startOnosCli-" + str( i ),
198 args=[nodes[i].ip_address] )
199 threads.append( t )
200 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700201
202 for t in threads:
203 t.join()
204 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700205 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
206 onpass="ONOS cli startup successful",
207 onfail="ONOS cli startup failed" )
Jon Hallb1290e82014-11-18 16:17:48 -0500208
Jon Hall6aec96b2015-01-19 14:49:31 -0800209 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800210 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800211 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
212 + "-MN.pcap",
213 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
214 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hallb1290e82014-11-18 16:17:48 -0500215
Jon Hall390696c2015-05-05 17:13:41 -0700216 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700217 appCheck = main.TRUE
218 threads = []
219 for i in range( numControllers ):
220 t = main.Thread( target=CLIs[i].appToIDCheck,
221 name="appToIDCheck-" + str( i ),
222 args=[] )
223 threads.append( t )
224 t.start()
225
226 for t in threads:
227 t.join()
228 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700229 if appCheck != main.TRUE:
230 main.log.warn( CLIs[0].apps() )
231 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700232 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
233 onpass="App Ids seem to be correct",
234 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700235
Jon Hallfeff3082015-05-19 10:23:26 -0700236 if cliResults == main.FALSE:
237 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hallffb386d2014-11-21 13:43:38 -0800238 main.cleanup()
239 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -0500240
Jon Hall6aec96b2015-01-19 14:49:31 -0800241 def CASE2( self, main ):
242 """
Jon Hallb1290e82014-11-18 16:17:48 -0500243 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800244 """
Jon Hallb1290e82014-11-18 16:17:48 -0500245 import re
Jon Hall390696c2015-05-05 17:13:41 -0700246 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700247 assert numControllers, "numControllers not defined"
248 assert main, "main not defined"
249 assert utilities.assert_equals, "utilities.assert_equals not defined"
250 assert CLIs, "CLIs not defined"
251 assert nodes, "nodes not defined"
252 assert ONOS1Port, "ONOS1Port not defined"
253 assert ONOS2Port, "ONOS2Port not defined"
254 assert ONOS3Port, "ONOS3Port not defined"
255 assert ONOS4Port, "ONOS4Port not defined"
256 assert ONOS5Port, "ONOS5Port not defined"
257 assert ONOS6Port, "ONOS6Port not defined"
258 assert ONOS7Port, "ONOS7Port not defined"
Jon Hallb1290e82014-11-18 16:17:48 -0500259
Jon Hall6aec96b2015-01-19 14:49:31 -0800260 main.case( "Assigning Controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700261 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
262 "and check that an ONOS node becomes the " +\
263 "master of the device. Then manually assign" +\
264 " mastership to specific ONOS nodes using" +\
265 " 'device-role'"
Jon Hall6aec96b2015-01-19 14:49:31 -0800266 main.step( "Assign switches to controllers" )
Jon Hallb1290e82014-11-18 16:17:48 -0500267
Jon Hall65844a32015-03-09 19:09:37 -0700268 # TODO: rewrite this function to take lists of ips and ports?
269 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800270 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800271 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800273 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -0700274 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
275 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
276 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
277 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
278 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
279 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
280 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hallb1290e82014-11-18 16:17:48 -0500281
Jon Hall8f89dda2015-01-22 16:03:33 -0800282 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800283 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800284 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800285 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800286 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800287 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800288 main.log.info( repr( response ) )
Jon Hall65844a32015-03-09 19:09:37 -0700289 for node in nodes:
290 if re.search( "tcp:" + node.ip_address, response ):
291 mastershipCheck = mastershipCheck and main.TRUE
292 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700293 main.log.error( "Error, node " + node.ip_address + " is " +
294 "not in the list of controllers s" +
295 str( i ) + " is connecting to." )
Jon Hall65844a32015-03-09 19:09:37 -0700296 mastershipCheck = main.FALSE
Jon Hall8f89dda2015-01-22 16:03:33 -0800297 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800298 main.log.report( "Switch mastership assigned correctly" )
299 utilities.assert_equals(
300 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800301 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800302 onpass="Switch mastership assigned correctly",
303 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700304
305 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800306 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800307 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700308
309 ipList = [ ]
310 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800311 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700312 for i in range( 1, 29 ): # switches 1 through 28
313 # set up correct variables:
314 if i == 1:
315 ip = nodes[ 0 ].ip_address # ONOS1
316 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
317 elif i == 2:
318 ip = nodes[ 1 ].ip_address # ONOS2
319 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
320 elif i == 3:
321 ip = nodes[ 1 ].ip_address # ONOS2
322 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
323 elif i == 4:
324 ip = nodes[ 3 ].ip_address # ONOS4
325 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
326 elif i == 5:
327 ip = nodes[ 2 ].ip_address # ONOS3
328 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
329 elif i == 6:
330 ip = nodes[ 2 ].ip_address # ONOS3
331 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
332 elif i == 7:
333 ip = nodes[ 5 ].ip_address # ONOS6
334 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
335 elif i >= 8 and i <= 17:
336 ip = nodes[ 4 ].ip_address # ONOS5
337 dpid = '3' + str( i ).zfill( 3 )
338 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
339 elif i >= 18 and i <= 27:
340 ip = nodes[ 6 ].ip_address # ONOS7
341 dpid = '6' + str( i ).zfill( 3 )
342 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
343 elif i == 28:
344 ip = nodes[ 0 ].ip_address # ONOS1
345 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
346 else:
347 main.log.error( "You didn't write an else statement for " +
348 "switch s" + str( i ) )
349 # Assign switch
350 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
351 # TODO: make this controller dynamic
352 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
353 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700354 ipList.append( ip )
355 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800356 except ( AttributeError, AssertionError ):
357 main.log.exception( "Something is wrong with ONOS device view" )
358 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800359 utilities.assert_equals(
360 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800361 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800362 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800363 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800364
Jon Hall390696c2015-05-05 17:13:41 -0700365 main.step( "Check mastership was correctly assigned" )
366 roleCheck = main.TRUE
367 # NOTE: This is due to the fact that device mastership change is not
368 # atomic and is actually a multi step process
369 time.sleep( 5 )
370 for i in range( len( ipList ) ):
371 ip = ipList[i]
372 deviceId = deviceList[i]
373 # Check assignment
374 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
375 if ip in master:
376 roleCheck = roleCheck and main.TRUE
377 else:
378 roleCheck = roleCheck and main.FALSE
379 main.log.error( "Error, controller " + ip + " is not" +
380 " master " + "of device " +
381 str( deviceId ) + ". Master is " +
382 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800383 utilities.assert_equals(
384 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800385 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800386 onpass="Switches were successfully reassigned to designated " +
387 "controller",
388 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800389 mastershipCheck = mastershipCheck and roleCall and roleCheck
390 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800391 onpass="Switch mastership correctly assigned",
392 onfail="Error in (re)assigning switch" +
Jon Hall8f89dda2015-01-22 16:03:33 -0800393 " mastership" )
Jon Hallb1290e82014-11-18 16:17:48 -0500394
Jon Hall6aec96b2015-01-19 14:49:31 -0800395 def CASE3( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500396 """
397 Assign intents
Jon Hallb1290e82014-11-18 16:17:48 -0500398 """
399 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800400 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700401 assert numControllers, "numControllers not defined"
402 assert main, "main not defined"
403 assert utilities.assert_equals, "utilities.assert_equals not defined"
404 assert CLIs, "CLIs not defined"
405 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800406 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700407 main.caseExplaination = "Discover hosts by using pingall then " +\
408 "assign predetermined host-to-host intents." +\
409 " After installation, check that the intent" +\
410 " is distributed to all nodes and the state" +\
411 " is INSTALLED"
Jon Hallb1290e82014-11-18 16:17:48 -0500412
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700414 main.step( "Install reactive forwarding app" )
415 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
416 utilities.assert_equals( expect=main.TRUE, actual=installResults,
417 onpass="Install fwd successful",
418 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700419
Jon Hallfeff3082015-05-19 10:23:26 -0700420 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700421 appCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700422 threads = []
423 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700424 t = main.Thread( target=CLIs[i].appToIDCheck,
425 name="appToIDCheck-" + str( i ),
426 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700427 threads.append( t )
428 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700429
430 for t in threads:
431 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700432 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700433 if appCheck != main.TRUE:
434 main.log.warn( CLIs[0].apps() )
435 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700436 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
437 onpass="App Ids seem to be correct",
438 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800439
Jon Hallfeff3082015-05-19 10:23:26 -0700440 main.step( "Discovering Hosts( Via pingall for now )" )
441 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800442 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800443 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700444 for i in range(2): # Retry if pingall fails first time
445 time1 = time.time()
446 pingResult = main.Mininet1.pingall()
447 utilities.assert_equals(
448 expect=main.TRUE,
449 actual=pingResult,
450 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700451 onfail="Reactive Pingall failed, " +
452 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700453 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700454 main.log.info( "Time for pingall: %2f seconds" %
455 ( time2 - time1 ) )
456 # timeout for fwd flows
457 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800458 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700459 main.step( "Uninstall reactive forwarding app" )
460 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
461 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
462 onpass="Uninstall fwd successful",
463 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700464 '''
465 main.Mininet1.handle.sendline( "py [ h.cmd( \"arping -c 1 10.1.1.1 \" ) for h in net.hosts ] ")
466 import time
467 time.sleep(60)
468 '''
469
470 main.step( "Check app ids" )
Jon Hall65844a32015-03-09 19:09:37 -0700471 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700472 appCheck2 = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -0700473 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700474 t = main.Thread( target=CLIs[i].appToIDCheck,
475 name="appToIDCheck-" + str( i ),
476 args=[] )
Jon Hall65844a32015-03-09 19:09:37 -0700477 threads.append( t )
478 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700479
480 for t in threads:
481 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700482 appCheck2 = appCheck2 and t.result
483 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700484 main.log.warn( CLIs[0].apps() )
485 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700486 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700487 onpass="App Ids seem to be correct",
488 onfail="Something is wrong with app Ids" )
Jon Hallb1290e82014-11-18 16:17:48 -0500489
Jon Hallfeff3082015-05-19 10:23:26 -0700490 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800491 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800492 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800493 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800494 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800495 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800496 for i in range( 8, 18 ):
497 main.log.info( "Adding host intent between h" + str( i ) +
498 " and h" + str( i + 10 ) )
499 host1 = "00:00:00:00:00:" + \
500 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
501 host2 = "00:00:00:00:00:" + \
502 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800503 # NOTE: getHost can return None
Jon Hall5cfd23c2015-03-19 11:40:57 -0700504 host1Dict = main.ONOScli1.getHost( host1 )
505 host2Dict = main.ONOScli1.getHost( host2 )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800506 host1Id = None
507 host2Id = None
508 if host1Dict and host2Dict:
509 host1Id = host1Dict.get( 'id', None )
510 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800511 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700512 nodeNum = ( i % 7 )
513 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800514 if tmpId:
515 main.log.info( "Added intent with id: " + tmpId )
516 intentIds.append( tmpId )
517 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700518 main.log.error( "addHostIntent returned: " +
519 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800520 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700521 main.log.error( "Error, getHost() failed for h" + str( i ) +
522 " and/or h" + str( i + 10 ) )
523 hosts = CLIs[ 0 ].hosts()
524 main.log.warn( "Hosts output: " )
525 try:
526 main.log.warn( json.dumps( json.loads( hosts ),
527 sort_keys=True,
528 indent=4,
529 separators=( ',', ': ' ) ) )
530 except ( ValueError, TypeError ):
531 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800532 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700533 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
534 onpass="Found a host id for each host",
535 onfail="Error looking up host ids" )
536
Jon Hall5cfd23c2015-03-19 11:40:57 -0700537 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800538 onosIds = main.ONOScli1.getAllIntentsId()
539 main.log.info( "Submitted intents: " + str( intentIds ) )
540 main.log.info( "Intents in ONOS: " + str( onosIds ) )
541 for intent in intentIds:
542 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700543 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800544 else:
545 intentAddResult = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700546 # FIXME: DEBUG
547 if intentAddResult:
548 intentStop = time.time()
549 else:
550 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800551 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800552 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800553 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -0700554 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800555 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
556 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700557 try:
558 for intent in json.loads( intents ):
559 state = intent.get( 'state', None )
560 if "INSTALLED" not in state:
561 installedCheck = False
562 intentId = intent.get( 'id', None )
563 intentStates.append( ( intentId, state ) )
564 except ( ValueError, TypeError ):
565 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800566 # add submitted intents not in the store
567 tmplist = [ i for i, s in intentStates ]
568 missingIntents = False
569 for i in intentIds:
570 if i not in tmplist:
571 intentStates.append( ( i, " - " ) )
572 missingIntents = True
573 intentStates.sort()
574 for i, s in intentStates:
575 count += 1
576 main.log.info( "%-6s%-15s%-15s" %
577 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700578 leaders = main.ONOScli1.leaders()
579 try:
580 if leaders:
581 parsedLeaders = json.loads( leaders )
582 main.log.warn( json.dumps( parsedLeaders,
583 sort_keys=True,
584 indent=4,
585 separators=( ',', ': ' ) ) )
586 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700587 topics = []
588 for i in range( 14 ):
589 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700590 main.log.debug( topics )
591 ONOStopics = [ j['topic'] for j in parsedLeaders ]
592 for topic in topics:
593 if topic not in ONOStopics:
594 main.log.error( "Error: " + topic +
595 " not in leaders" )
596 else:
597 main.log.error( "leaders() returned None" )
598 except ( ValueError, TypeError ):
599 main.log.exception( "Error parsing leaders" )
600 main.log.error( repr( leaders ) )
601 partitions = main.ONOScli1.partitions()
602 try:
603 if partitions :
604 parsedPartitions = json.loads( partitions )
605 main.log.warn( json.dumps( parsedPartitions,
606 sort_keys=True,
607 indent=4,
608 separators=( ',', ': ' ) ) )
609 # TODO check for a leader in all paritions
610 # TODO check for consistency among nodes
611 else:
612 main.log.error( "partitions() returned None" )
613 except ( ValueError, TypeError ):
614 main.log.exception( "Error parsing partitions" )
615 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800616 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700617 try:
618 if pendingMap :
619 parsedPending = json.loads( pendingMap )
620 main.log.warn( json.dumps( parsedPending,
621 sort_keys=True,
622 indent=4,
623 separators=( ',', ': ' ) ) )
624 # TODO check something here?
625 else:
626 main.log.error( "pendingMap() returned None" )
627 except ( ValueError, TypeError ):
628 main.log.exception( "Error parsing pending map" )
629 main.log.error( repr( pendingMap ) )
630
Jon Hallfeff3082015-05-19 10:23:26 -0700631 intentAddResult = bool( intentAddResult and not missingIntents and
632 installedCheck )
633 if not intentAddResult:
634 main.log.error( "Error in pushing host intents to ONOS" )
635
Jon Hall390696c2015-05-05 17:13:41 -0700636 main.step( "Intent Anti-Entropy dispersion" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700637 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700638 correct = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700639 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700640 for cli in CLIs:
641 onosIds = []
642 ids = cli.getAllIntentsId()
643 onosIds.append( ids )
644 main.log.debug( "Intents in " + cli.name + ": " +
645 str( sorted( onosIds ) ) )
646 if sorted( ids ) != sorted( intentIds ):
647 correct = False
648 if correct:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700649 break
650 else:
651 time.sleep(1)
Jon Hall5cfd23c2015-03-19 11:40:57 -0700652 if not intentStop:
653 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700654 global gossipTime
Jon Hall5cfd23c2015-03-19 11:40:57 -0700655 gossipTime = intentStop - intentStart
656 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700657 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700658 # FIXME: make this time configurable/calculate based off of number of
659 # nodes and gossip rounds
Jon Hall5cfd23c2015-03-19 11:40:57 -0700660 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700661 expect=40, actual=gossipTime,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700662 onpass="ECM anti-entropy for intents worked within " +
663 "expected time",
664 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700665 if gossipTime <= 40:
Jon Halla9d26da2015-03-30 16:45:32 -0700666 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800667
Jon Hall63604932015-02-26 17:09:50 -0800668 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800669 import time
Jon Hall63604932015-02-26 17:09:50 -0800670 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800671 main.log.info( "Sleeping 60 seconds to see if intents are found" )
672 time.sleep( 60 )
673 onosIds = main.ONOScli1.getAllIntentsId()
674 main.log.info( "Submitted intents: " + str( intentIds ) )
675 main.log.info( "Intents in ONOS: " + str( onosIds ) )
676 # Print the intent states
677 intents = main.ONOScli1.intents()
678 intentStates = []
679 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
680 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700681 try:
682 for intent in json.loads( intents ):
683 # Iter through intents of a node
684 state = intent.get( 'state', None )
685 if "INSTALLED" not in state:
686 installedCheck = False
687 intentId = intent.get( 'id', None )
688 intentStates.append( ( intentId, state ) )
689 except ( ValueError, TypeError ):
690 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800691 # add submitted intents not in the store
692 tmplist = [ i for i, s in intentStates ]
693 for i in intentIds:
694 if i not in tmplist:
695 intentStates.append( ( i, " - " ) )
696 intentStates.sort()
697 for i, s in intentStates:
698 count += 1
699 main.log.info( "%-6s%-15s%-15s" %
700 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700701 leaders = main.ONOScli1.leaders()
702 try:
703 if leaders:
704 parsedLeaders = json.loads( leaders )
705 main.log.warn( json.dumps( parsedLeaders,
706 sort_keys=True,
707 indent=4,
708 separators=( ',', ': ' ) ) )
709 # check for all intent partitions
710 # check for election
711 topics = []
712 for i in range( 14 ):
713 topics.append( "intent-partition-" + str( i ) )
714 # FIXME: this should only be after we start the app
715 topics.append( "org.onosproject.election" )
716 main.log.debug( topics )
717 ONOStopics = [ j['topic'] for j in parsedLeaders ]
718 for topic in topics:
719 if topic not in ONOStopics:
720 main.log.error( "Error: " + topic +
721 " not in leaders" )
722 else:
723 main.log.error( "leaders() returned None" )
724 except ( ValueError, TypeError ):
725 main.log.exception( "Error parsing leaders" )
726 main.log.error( repr( leaders ) )
727 partitions = main.ONOScli1.partitions()
728 try:
729 if partitions :
730 parsedPartitions = json.loads( partitions )
731 main.log.warn( json.dumps( parsedPartitions,
732 sort_keys=True,
733 indent=4,
734 separators=( ',', ': ' ) ) )
735 # TODO check for a leader in all paritions
736 # TODO check for consistency among nodes
737 else:
738 main.log.error( "partitions() returned None" )
739 except ( ValueError, TypeError ):
740 main.log.exception( "Error parsing partitions" )
741 main.log.error( repr( partitions ) )
742 pendingMap = main.ONOScli1.pendingMap()
743 try:
744 if pendingMap :
745 parsedPending = json.loads( pendingMap )
746 main.log.warn( json.dumps( parsedPending,
747 sort_keys=True,
748 indent=4,
749 separators=( ',', ': ' ) ) )
750 # TODO check something here?
751 else:
752 main.log.error( "pendingMap() returned None" )
753 except ( ValueError, TypeError ):
754 main.log.exception( "Error parsing pending map" )
755 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500756
Jon Hall6aec96b2015-01-19 14:49:31 -0800757 def CASE4( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500758 """
759 Ping across added host intents
760 """
Jon Hall58c76b72015-02-23 11:09:24 -0800761 import json
Jon Hall65844a32015-03-09 19:09:37 -0700762 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700763 assert numControllers, "numControllers not defined"
764 assert main, "main not defined"
765 assert utilities.assert_equals, "utilities.assert_equals not defined"
766 assert CLIs, "CLIs not defined"
767 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700768 main.case( "Verify connectivity by sendind traffic across Intents" )
769 main.caseExplaination = "Ping across added host intents to check " +\
770 "functionality and check the state of " +\
771 "the intent"
772 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800773 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800774 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800775 ping = main.Mininet1.pingHost( src="h" + str( i ),
776 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800777 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800778 if ping == main.FALSE:
779 main.log.warn( "Ping failed between h" + str( i ) +
780 " and h" + str( i + 10 ) )
781 elif ping == main.TRUE:
782 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800783 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800784 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800785 main.log.report(
786 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800787 # TODO: pretty print
Jon Hall65844a32015-03-09 19:09:37 -0700788 main.log.warn( "ONOS1 intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700789 try:
790 tmpIntents = main.ONOScli1.intents()
791 main.log.warn( json.dumps( json.loads( tmpIntents ),
792 sort_keys=True,
793 indent=4,
794 separators=( ',', ': ' ) ) )
795 except ( ValueError, TypeError ):
796 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800797 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800798 main.log.report(
799 "Intents have been installed correctly and verified by pings" )
800 utilities.assert_equals(
801 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800802 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800803 onpass="Intents have been installed correctly and pings work",
804 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallb1290e82014-11-18 16:17:48 -0500805
Jon Hallfeff3082015-05-19 10:23:26 -0700806 main.step( "Check Intent state" )
Jon Hall63604932015-02-26 17:09:50 -0800807 installedCheck = True
Jon Hallfeff3082015-05-19 10:23:26 -0700808 # Print the intent states
809 intents = main.ONOScli1.intents()
810 intentStates = []
811 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
812 count = 0
813 # Iter through intents of a node
814 try:
815 for intent in json.loads( intents ):
816 state = intent.get( 'state', None )
817 if "INSTALLED" not in state:
818 installedCheck = False
819 intentId = intent.get( 'id', None )
820 intentStates.append( ( intentId, state ) )
821 except ( ValueError, TypeError ):
822 main.log.exception( "Error parsing intents." )
823 # Print states
824 intentStates.sort()
825 for i, s in intentStates:
826 count += 1
827 main.log.info( "%-6s%-15s%-15s" %
828 ( str( count ), str( i ), str( s ) ) )
829 utilities.assert_equals( expect=True, actual=installedCheck,
830 onpass="Intents are all INSTALLED",
831 onfail="Intents are not all in " +\
832 "INSTALLED state" )
833
834 main.step( "Check leadership of topics" )
835 leaders = main.ONOScli1.leaders()
836 topicCheck = main.TRUE
837 try:
838 if leaders:
839 parsedLeaders = json.loads( leaders )
840 main.log.warn( json.dumps( parsedLeaders,
841 sort_keys=True,
842 indent=4,
843 separators=( ',', ': ' ) ) )
844 # check for all intent partitions
845 # check for election
846 # TODO: Look at Devices as topics now that it uses this system
847 topics = []
848 for i in range( 14 ):
849 topics.append( "intent-partition-" + str( i ) )
850 # FIXME: this should only be after we start the app
851 # FIXME: topics.append( "org.onosproject.election" )
852 # Print leaders output
853 main.log.debug( topics )
854 ONOStopics = [ j['topic'] for j in parsedLeaders ]
855 for topic in topics:
856 if topic not in ONOStopics:
857 main.log.error( "Error: " + topic +
858 " not in leaders" )
859 topicCheck = main.FALSE
860 else:
861 main.log.error( "leaders() returned None" )
862 topicCheck = main.FALSE
863 except ( ValueError, TypeError ):
864 topicCheck = main.FALSE
865 main.log.exception( "Error parsing leaders" )
866 main.log.error( repr( leaders ) )
867 # TODO: Check for a leader of these topics
868 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
869 onpass="intent Partitions is in leaders",
870 onfail="Some topics were lost " )
871 # Print partitions
872 partitions = main.ONOScli1.partitions()
873 try:
874 if partitions :
875 parsedPartitions = json.loads( partitions )
876 main.log.warn( json.dumps( parsedPartitions,
877 sort_keys=True,
878 indent=4,
879 separators=( ',', ': ' ) ) )
880 # TODO check for a leader in all paritions
881 # TODO check for consistency among nodes
882 else:
883 main.log.error( "partitions() returned None" )
884 except ( ValueError, TypeError ):
885 main.log.exception( "Error parsing partitions" )
886 main.log.error( repr( partitions ) )
887 # Print Pending Map
888 pendingMap = main.ONOScli1.pendingMap()
889 try:
890 if pendingMap :
891 parsedPending = json.loads( pendingMap )
892 main.log.warn( json.dumps( parsedPending,
893 sort_keys=True,
894 indent=4,
895 separators=( ',', ': ' ) ) )
896 # TODO check something here?
897 else:
898 main.log.error( "pendingMap() returned None" )
899 except ( ValueError, TypeError ):
900 main.log.exception( "Error parsing pending map" )
901 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700902
Jon Hall63604932015-02-26 17:09:50 -0800903 if not installedCheck:
Jon Hall65844a32015-03-09 19:09:37 -0700904 main.log.info( "Waiting 60 seconds to see if the state of " +
905 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800906 time.sleep( 60 )
907 # Print the intent states
908 intents = main.ONOScli1.intents()
909 intentStates = []
910 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
911 count = 0
912 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700913 try:
914 for intent in json.loads( intents ):
915 state = intent.get( 'state', None )
916 if "INSTALLED" not in state:
917 installedCheck = False
918 intentId = intent.get( 'id', None )
919 intentStates.append( ( intentId, state ) )
920 except ( ValueError, TypeError ):
921 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800922 intentStates.sort()
923 for i, s in intentStates:
924 count += 1
925 main.log.info( "%-6s%-15s%-15s" %
926 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700927 leaders = main.ONOScli1.leaders()
928 try:
929 if leaders:
930 parsedLeaders = json.loads( leaders )
931 main.log.warn( json.dumps( parsedLeaders,
932 sort_keys=True,
933 indent=4,
934 separators=( ',', ': ' ) ) )
935 # check for all intent partitions
936 # check for election
937 topics = []
938 for i in range( 14 ):
939 topics.append( "intent-partition-" + str( i ) )
940 # FIXME: this should only be after we start the app
941 topics.append( "org.onosproject.election" )
942 main.log.debug( topics )
943 ONOStopics = [ j['topic'] for j in parsedLeaders ]
944 for topic in topics:
945 if topic not in ONOStopics:
946 main.log.error( "Error: " + topic +
947 " not in leaders" )
948 else:
949 main.log.error( "leaders() returned None" )
950 except ( ValueError, TypeError ):
951 main.log.exception( "Error parsing leaders" )
952 main.log.error( repr( leaders ) )
953 partitions = main.ONOScli1.partitions()
954 try:
955 if partitions :
956 parsedPartitions = json.loads( partitions )
957 main.log.warn( json.dumps( parsedPartitions,
958 sort_keys=True,
959 indent=4,
960 separators=( ',', ': ' ) ) )
961 # TODO check for a leader in all paritions
962 # TODO check for consistency among nodes
963 else:
964 main.log.error( "partitions() returned None" )
965 except ( ValueError, TypeError ):
966 main.log.exception( "Error parsing partitions" )
967 main.log.error( repr( partitions ) )
968 pendingMap = main.ONOScli1.pendingMap()
969 try:
970 if pendingMap :
971 parsedPending = json.loads( pendingMap )
972 main.log.warn( json.dumps( parsedPending,
973 sort_keys=True,
974 indent=4,
975 separators=( ',', ': ' ) ) )
976 # TODO check something here?
977 else:
978 main.log.error( "pendingMap() returned None" )
979 except ( ValueError, TypeError ):
980 main.log.exception( "Error parsing pending map" )
981 main.log.error( repr( pendingMap ) )
Jon Hall390696c2015-05-05 17:13:41 -0700982 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500983
Jon Hallfeff3082015-05-19 10:23:26 -0700984 main.step( "Wait a minute then ping again" )
985 PingResult = main.TRUE
986 for i in range( 8, 18 ):
987 ping = main.Mininet1.pingHost( src="h" + str( i ),
988 target="h" + str( i + 10 ) )
989 PingResult = PingResult and ping
990 if ping == main.FALSE:
991 main.log.warn( "Ping failed between h" + str( i ) +
992 " and h" + str( i + 10 ) )
993 elif ping == main.TRUE:
994 main.log.info( "Ping test passed!" )
995 # Don't set PingResult or you'd override failures
996 if PingResult == main.FALSE:
997 main.log.report(
998 "Intents have not been installed correctly, pings failed." )
999 # TODO: pretty print
1000 main.log.warn( "ONOS1 intents: " )
1001 try:
1002 tmpIntents = main.ONOScli1.intents()
1003 main.log.warn( json.dumps( json.loads( tmpIntents ),
1004 sort_keys=True,
1005 indent=4,
1006 separators=( ',', ': ' ) ) )
1007 except ( ValueError, TypeError ):
1008 main.log.warn( repr( tmpIntents ) )
1009 utilities.assert_equals(
1010 expect=main.TRUE,
1011 actual=PingResult,
1012 onpass="Intents have been installed correctly and pings work",
1013 onfail="Intents have not been installed correctly, pings failed." )
1014
1015
1016
1017 '''
1018 #DEBUG
1019 if PingResult == main.FALSE:
1020 import time
1021 time.sleep( 100000 )
1022 '''
1023
Jon Hall6aec96b2015-01-19 14:49:31 -08001024 def CASE5( self, main ):
1025 """
Jon Hallb1290e82014-11-18 16:17:48 -05001026 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001027 """
Jon Hallb1290e82014-11-18 16:17:48 -05001028 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001029 import time
1030 assert numControllers, "numControllers not defined"
1031 assert main, "main not defined"
1032 assert utilities.assert_equals, "utilities.assert_equals not defined"
1033 assert CLIs, "CLIs not defined"
1034 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001035 # assumes that sts is already in you PYTHONPATH
1036 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001037
Jon Hall6aec96b2015-01-19 14:49:31 -08001038 main.case( "Setting up and gathering data for current state" )
1039 # The general idea for this test case is to pull the state of
1040 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -07001041 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -05001042
Jon Hall65844a32015-03-09 19:09:37 -07001043 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001044 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001045 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001046
Jon Hall6aec96b2015-01-19 14:49:31 -08001047 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001048 rolesNotNull = main.TRUE
1049 threads = []
1050 for i in range( numControllers ):
1051 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001052 name="rolesNotNull-" + str( i ),
1053 args=[] )
1054 threads.append( t )
1055 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001056
1057 for t in threads:
1058 t.join()
1059 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001060 utilities.assert_equals(
1061 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001062 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001063 onpass="Each device has a master",
1064 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001065
Jon Hall65844a32015-03-09 19:09:37 -07001066 main.step( "Get the Mastership of each switch from each controller" )
1067 ONOSMastership = []
1068 mastershipCheck = main.FALSE
1069 consistentMastership = True
1070 rolesResults = True
1071 threads = []
1072 for i in range( numControllers ):
1073 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001074 name="roles-" + str( i ),
1075 args=[] )
1076 threads.append( t )
1077 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001078
1079 for t in threads:
1080 t.join()
1081 ONOSMastership.append( t.result )
1082
1083 for i in range( numControllers ):
1084 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1085 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1086 " roles" )
1087 main.log.warn(
1088 "ONOS" + str( i + 1 ) + " mastership response: " +
1089 repr( ONOSMastership[i] ) )
1090 rolesResults = False
1091 utilities.assert_equals(
1092 expect=True,
1093 actual=rolesResults,
1094 onpass="No error in reading roles output",
1095 onfail="Error in reading roles from ONOS" )
1096
1097 main.step( "Check for consistency in roles from each controller" )
1098 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001099 main.log.report(
1100 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001101 else:
Jon Hall65844a32015-03-09 19:09:37 -07001102 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001103 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001104 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001105 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001106 onpass="Switch roles are consistent across all ONOS nodes",
1107 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001108
Jon Hall65844a32015-03-09 19:09:37 -07001109 if rolesResults and not consistentMastership:
1110 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001111 try:
1112 main.log.warn(
1113 "ONOS" + str( i + 1 ) + " roles: ",
1114 json.dumps(
1115 json.loads( ONOSMastership[ i ] ),
1116 sort_keys=True,
1117 indent=4,
1118 separators=( ',', ': ' ) ) )
1119 except ( ValueError, TypeError ):
1120 main.log.warn( repr( ONOSMastership[ i ] ) )
1121 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001122 mastershipCheck = main.TRUE
1123 mastershipState = ONOSMastership[ 0 ]
1124
Jon Hall6aec96b2015-01-19 14:49:31 -08001125 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001126 global intentState
1127 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001128 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001129 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001130 consistentIntents = True
1131 intentsResults = True
1132 threads = []
1133 for i in range( numControllers ):
1134 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001135 name="intents-" + str( i ),
1136 args=[],
1137 kwargs={ 'jsonFormat': True } )
1138 threads.append( t )
1139 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001140
1141 for t in threads:
1142 t.join()
1143 ONOSIntents.append( t.result )
1144
1145 for i in range( numControllers ):
1146 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1147 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1148 " intents" )
1149 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1150 repr( ONOSIntents[ i ] ) )
1151 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001152 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001153 expect=True,
1154 actual=intentsResults,
1155 onpass="No error in reading intents output",
1156 onfail="Error in reading intents from ONOS" )
1157
1158 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001159 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001160 main.log.report( "Intents are consistent across all ONOS " +
1161 "nodes" )
1162 else:
1163 consistentIntents = False
Jon Hall5cfd23c2015-03-19 11:40:57 -07001164 main.log.report( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001165 utilities.assert_equals(
1166 expect=True,
1167 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001168 onpass="Intents are consistent across all ONOS nodes",
1169 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001170
Jon Hall390696c2015-05-05 17:13:41 -07001171 if intentsResults:
1172 # Try to make it easy to figure out what is happening
1173 #
1174 # Intent ONOS1 ONOS2 ...
1175 # 0x01 INSTALLED INSTALLING
1176 # ... ... ...
1177 # ... ... ...
1178 title = " Id"
1179 for n in range( numControllers ):
1180 title += " " * 10 + "ONOS" + str( n + 1 )
1181 main.log.warn( title )
1182 # get all intent keys in the cluster
1183 keys = []
1184 for nodeStr in ONOSIntents:
1185 node = json.loads( nodeStr )
1186 for intent in node:
1187 keys.append( intent.get( 'id' ) )
1188 keys = set( keys )
1189 for key in keys:
1190 row = "%-13s" % key
1191 for nodeStr in ONOSIntents:
1192 node = json.loads( nodeStr )
1193 for intent in node:
1194 if intent.get( 'id', "Error" ) == key:
1195 row += "%-15s" % intent.get( 'state' )
1196 main.log.warn( row )
1197 # End table view
1198
Jon Hall65844a32015-03-09 19:09:37 -07001199 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001200 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001201 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001202 main.log.debug( "ONOS" + str( n ) + " intents: " )
1203 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1204 sort_keys=True,
1205 indent=4,
1206 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001207 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001208 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001209 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1210 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1211 sort_keys=True,
1212 indent=4,
1213 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001214 else:
Jon Hall390696c2015-05-05 17:13:41 -07001215 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1216 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001217 elif intentsResults and consistentIntents:
1218 intentCheck = main.TRUE
1219 intentState = ONOSIntents[ 0 ]
1220
Jon Hall6aec96b2015-01-19 14:49:31 -08001221 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001222 global flowState
1223 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001224 ONOSFlows = []
1225 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001226 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001227 consistentFlows = True
1228 flowsResults = True
1229 threads = []
1230 for i in range( numControllers ):
1231 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001232 name="flows-" + str( i ),
1233 args=[],
1234 kwargs={ 'jsonFormat': True } )
1235 threads.append( t )
1236 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001237
Jon Halla9d26da2015-03-30 16:45:32 -07001238 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001239 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001240 for t in threads:
1241 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001242 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001243 ONOSFlows.append( result )
1244
1245 for i in range( numControllers ):
1246 num = str( i + 1 )
1247 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1248 main.log.report( "Error in getting ONOS" + num + " flows" )
1249 main.log.warn( "ONOS" + num + " flows response: " +
1250 repr( ONOSFlows[ i ] ) )
1251 flowsResults = False
1252 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001253 else:
Jon Hall65844a32015-03-09 19:09:37 -07001254 try:
1255 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1256 except ( ValueError, TypeError ):
1257 # FIXME: change this to log.error?
1258 main.log.exception( "Error in parsing ONOS" + num +
1259 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001260 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001261 ONOSFlowsJson.append( None )
1262 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001263 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001264 expect=True,
1265 actual=flowsResults,
1266 onpass="No error in reading flows output",
1267 onfail="Error in reading flows from ONOS" )
1268
1269 main.step( "Check for consistency in Flows from each controller" )
1270 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1271 if all( tmp ):
1272 main.log.report( "Flow count is consistent across all ONOS nodes" )
1273 else:
1274 consistentFlows = False
1275 utilities.assert_equals(
1276 expect=True,
1277 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001278 onpass="The flow count is consistent across all ONOS nodes",
1279 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001280
Jon Hall65844a32015-03-09 19:09:37 -07001281 if flowsResults and not consistentFlows:
1282 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001283 try:
1284 main.log.warn(
1285 "ONOS" + str( i + 1 ) + " flows: " +
1286 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1287 indent=4, separators=( ',', ': ' ) ) )
1288 except ( ValueError, TypeError ):
1289 main.log.warn(
1290 "ONOS" + str( i + 1 ) + " flows: " +
1291 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001292 elif flowsResults and consistentFlows:
1293 flowCheck = main.TRUE
1294 flowState = ONOSFlows[ 0 ]
1295
Jon Hall6aec96b2015-01-19 14:49:31 -08001296 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001297 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001298 flows = []
1299 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001300 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001301 if flowCheck == main.FALSE:
1302 for table in flows:
1303 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001304 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001305
Jon Hall6aec96b2015-01-19 14:49:31 -08001306 main.step( "Start continuous pings" )
1307 main.Mininet2.pingLong(
1308 src=main.params[ 'PING' ][ 'source1' ],
1309 target=main.params[ 'PING' ][ 'target1' ],
1310 pingTime=500 )
1311 main.Mininet2.pingLong(
1312 src=main.params[ 'PING' ][ 'source2' ],
1313 target=main.params[ 'PING' ][ 'target2' ],
1314 pingTime=500 )
1315 main.Mininet2.pingLong(
1316 src=main.params[ 'PING' ][ 'source3' ],
1317 target=main.params[ 'PING' ][ 'target3' ],
1318 pingTime=500 )
1319 main.Mininet2.pingLong(
1320 src=main.params[ 'PING' ][ 'source4' ],
1321 target=main.params[ 'PING' ][ 'target4' ],
1322 pingTime=500 )
1323 main.Mininet2.pingLong(
1324 src=main.params[ 'PING' ][ 'source5' ],
1325 target=main.params[ 'PING' ][ 'target5' ],
1326 pingTime=500 )
1327 main.Mininet2.pingLong(
1328 src=main.params[ 'PING' ][ 'source6' ],
1329 target=main.params[ 'PING' ][ 'target6' ],
1330 pingTime=500 )
1331 main.Mininet2.pingLong(
1332 src=main.params[ 'PING' ][ 'source7' ],
1333 target=main.params[ 'PING' ][ 'target7' ],
1334 pingTime=500 )
1335 main.Mininet2.pingLong(
1336 src=main.params[ 'PING' ][ 'source8' ],
1337 target=main.params[ 'PING' ][ 'target8' ],
1338 pingTime=500 )
1339 main.Mininet2.pingLong(
1340 src=main.params[ 'PING' ][ 'source9' ],
1341 target=main.params[ 'PING' ][ 'target9' ],
1342 pingTime=500 )
1343 main.Mininet2.pingLong(
1344 src=main.params[ 'PING' ][ 'source10' ],
1345 target=main.params[ 'PING' ][ 'target10' ],
1346 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001347
Jon Hall6aec96b2015-01-19 14:49:31 -08001348 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001349 ctrls = []
Jon Hall65844a32015-03-09 19:09:37 -07001350 for node in nodes:
1351 temp = ( node, node.name, node.ip_address, 6633 )
Jon Hall65844a32015-03-09 19:09:37 -07001352 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001353 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001354
Jon Hall6aec96b2015-01-19 14:49:31 -08001355 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001356 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001357 threads = []
1358 for i in range( numControllers ):
1359 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001360 name="devices-" + str( i ),
1361 args=[ ] )
1362 threads.append( t )
1363 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001364
1365 for t in threads:
1366 t.join()
1367 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001368 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001369 threads = []
1370 for i in range( numControllers ):
1371 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001372 name="hosts-" + str( i ),
1373 args=[ ] )
1374 threads.append( t )
1375 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001376
1377 for t in threads:
1378 t.join()
1379 try:
1380 hosts.append( json.loads( t.result ) )
1381 except ( ValueError, TypeError ):
1382 # FIXME: better handling of this, print which node
1383 # Maybe use thread name?
1384 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001385 # FIXME: should this be an empty json object instead?
1386 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001387
Jon Hallb1290e82014-11-18 16:17:48 -05001388 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001389 threads = []
1390 for i in range( numControllers ):
1391 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001392 name="ports-" + str( i ),
1393 args=[ ] )
1394 threads.append( t )
1395 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001396
1397 for t in threads:
1398 t.join()
1399 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001400 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001401 threads = []
1402 for i in range( numControllers ):
1403 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001404 name="links-" + str( i ),
1405 args=[ ] )
1406 threads.append( t )
1407 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001408
1409 for t in threads:
1410 t.join()
1411 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001412 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001413 threads = []
1414 for i in range( numControllers ):
1415 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001416 name="clusters-" + str( i ),
1417 args=[ ] )
1418 threads.append( t )
1419 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001420
1421 for t in threads:
1422 t.join()
1423 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001424 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001425
Jon Hall6aec96b2015-01-19 14:49:31 -08001426 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001427 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001428 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001429 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001430 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001431 if "Error" not in hosts[ controller ]:
1432 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001433 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001434 else: # hosts not consistent
1435 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001436 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001437 " is inconsistent with ONOS1" )
1438 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001439 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001440
1441 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001442 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001443 controllerStr )
1444 consistentHostsResult = main.FALSE
1445 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001446 " hosts response: " +
1447 repr( hosts[ controller ] ) )
1448 utilities.assert_equals(
1449 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001450 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 onpass="Hosts view is consistent across all ONOS nodes",
1452 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001453
Jon Hall390696c2015-05-05 17:13:41 -07001454 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001455 ipResult = main.TRUE
1456 for controller in range( 0, len( hosts ) ):
1457 controllerStr = str( controller + 1 )
1458 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001459 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001460 main.log.error( "DEBUG:Error with host ips on controller" +
1461 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001462 ipResult = main.FALSE
1463 utilities.assert_equals(
1464 expect=main.TRUE,
1465 actual=ipResult,
1466 onpass="The ips of the hosts aren't empty",
1467 onfail="The ip of at least one host is missing" )
1468
Jon Hall6aec96b2015-01-19 14:49:31 -08001469 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001470 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001471 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001472 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001473 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001474 if "Error" not in clusters[ controller ]:
1475 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001476 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001477 else: # clusters not consistent
Jon Hall65844a32015-03-09 19:09:37 -07001478 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001479 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001480 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001481
1482 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001483 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001484 "from ONOS" + controllerStr )
1485 consistentClustersResult = main.FALSE
1486 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001487 " clusters response: " +
1488 repr( clusters[ controller ] ) )
1489 utilities.assert_equals(
1490 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001491 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001492 onpass="Clusters view is consistent across all ONOS nodes",
1493 onfail="ONOS nodes have different views of clusters" )
1494 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001495 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001496 try:
1497 numClusters = len( json.loads( clusters[ 0 ] ) )
1498 except ( ValueError, TypeError ):
1499 main.log.exception( "Error parsing clusters[0]: " +
1500 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001501 clusterResults = main.FALSE
1502 if numClusters == 1:
1503 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001504 utilities.assert_equals(
1505 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001506 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001507 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001508 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001509
Jon Hall6aec96b2015-01-19 14:49:31 -08001510 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001511 devicesResults = main.TRUE
1512 portsResults = main.TRUE
1513 linksResults = main.TRUE
1514 for controller in range( numControllers ):
1515 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001516 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001517 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001518 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001519 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001520 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001521 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001522 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001523 actual=currentDevicesResult,
1524 onpass="ONOS" + controllerStr +
1525 " Switches view is correct",
1526 onfail="ONOS" + controllerStr +
1527 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001528
Jon Hall6aec96b2015-01-19 14:49:31 -08001529 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001530 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001531 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001532 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001533 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001534 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001535 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001536 actual=currentPortsResult,
1537 onpass="ONOS" + controllerStr +
1538 " ports view is correct",
1539 onfail="ONOS" + controllerStr +
1540 " ports view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001541
Jon Hall6aec96b2015-01-19 14:49:31 -08001542 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001543 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001544 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001545 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001546 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001547 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001548 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001549 actual=currentLinksResult,
1550 onpass="ONOS" + controllerStr +
1551 " links view is correct",
1552 onfail="ONOS" + controllerStr +
1553 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001554
Jon Hall8f89dda2015-01-22 16:03:33 -08001555 devicesResults = devicesResults and currentDevicesResult
1556 portsResults = portsResults and currentPortsResult
1557 linksResults = linksResults and currentLinksResult
Jon Hallb1290e82014-11-18 16:17:48 -05001558
Jon Hall65844a32015-03-09 19:09:37 -07001559 topoResult = ( devicesResults and portsResults and linksResults
1560 and consistentHostsResult and consistentClustersResult
1561 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001562 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001563 onpass="Topology Check Test successful",
1564 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001565
Jon Hall6aec96b2015-01-19 14:49:31 -08001566 def CASE6( self, main ):
1567 """
Jon Hallb1290e82014-11-18 16:17:48 -05001568 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001569 """
Jon Hall368769f2014-11-19 15:43:35 -08001570 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001571 assert numControllers, "numControllers not defined"
1572 assert main, "main not defined"
1573 assert utilities.assert_equals, "utilities.assert_equals not defined"
1574 assert CLIs, "CLIs not defined"
1575 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001576 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001577 time.sleep( 60 )
1578 utilities.assert_equals(
1579 expect=main.TRUE,
1580 actual=main.TRUE,
1581 onpass="Sleeping 60 seconds",
1582 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001583
Jon Hall6aec96b2015-01-19 14:49:31 -08001584 def CASE7( self, main ):
1585 """
Jon Hall368769f2014-11-19 15:43:35 -08001586 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001587 """
Jon Hallb1290e82014-11-18 16:17:48 -05001588 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001589 assert numControllers, "numControllers not defined"
1590 assert main, "main not defined"
1591 assert utilities.assert_equals, "utilities.assert_equals not defined"
1592 assert CLIs, "CLIs not defined"
1593 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001594 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001595
Jon Hall65844a32015-03-09 19:09:37 -07001596 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001597 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001598 rolesNotNull = main.TRUE
1599 threads = []
1600 for i in range( numControllers ):
1601 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001602 name="rolesNotNull-" + str( i ),
1603 args=[ ] )
1604 threads.append( t )
1605 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001606
1607 for t in threads:
1608 t.join()
1609 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001610 utilities.assert_equals(
1611 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001612 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001613 onpass="Each device has a master",
1614 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001615
Jon Hall390696c2015-05-05 17:13:41 -07001616 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001617 ONOSMastership = []
1618 mastershipCheck = main.FALSE
1619 consistentMastership = True
1620 rolesResults = True
1621 threads = []
1622 for i in range( numControllers ):
1623 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001624 name="roles-" + str( i ),
1625 args=[] )
1626 threads.append( t )
1627 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001628
1629 for t in threads:
1630 t.join()
1631 ONOSMastership.append( t.result )
1632
1633 for i in range( numControllers ):
1634 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1635 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1636 " roles" )
1637 main.log.warn(
1638 "ONOS" + str( i + 1 ) + " mastership response: " +
1639 repr( ONOSMastership[i] ) )
1640 rolesResults = False
1641 utilities.assert_equals(
1642 expect=True,
1643 actual=rolesResults,
1644 onpass="No error in reading roles output",
1645 onfail="Error in reading roles from ONOS" )
1646
1647 main.step( "Check for consistency in roles from each controller" )
1648 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001649 main.log.report(
1650 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001651 else:
Jon Hall65844a32015-03-09 19:09:37 -07001652 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001653 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001654 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001655 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001656 onpass="Switch roles are consistent across all ONOS nodes",
1657 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001658
Jon Hall65844a32015-03-09 19:09:37 -07001659 if rolesResults and not consistentMastership:
1660 for i in range( numControllers ):
1661 main.log.warn(
1662 "ONOS" + str( i + 1 ) + " roles: ",
1663 json.dumps(
1664 json.loads( ONOSMastership[ i ] ),
1665 sort_keys=True,
1666 indent=4,
1667 separators=( ',', ': ' ) ) )
1668 elif rolesResults and not consistentMastership:
1669 mastershipCheck = main.TRUE
1670
Jon Hallb1290e82014-11-18 16:17:48 -05001671 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001672 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001673 try:
1674 currentJson = json.loads( ONOSMastership[0] )
1675 oldJson = json.loads( mastershipState )
1676 except ( ValueError, TypeError ):
1677 main.log.exception( "Something is wrong with parsing " +
1678 "ONOSMastership[0] or mastershipState" )
1679 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1680 main.log.error( "mastershipState" + repr( mastershipState ) )
1681 main.cleanup()
1682 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001683 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001684 for i in range( 1, 29 ):
1685 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001686 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001687 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001688 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001689 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001690 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001691 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001692 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001693 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001694 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001695 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001696 utilities.assert_equals(
1697 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001698 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001699 onpass="Mastership of Switches was not changed",
1700 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001701 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001702
Jon Hall6aec96b2015-01-19 14:49:31 -08001703 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001704 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001705 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001706 consistentIntents = True
1707 intentsResults = True
1708 threads = []
1709 for i in range( numControllers ):
1710 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001711 name="intents-" + str( i ),
1712 args=[],
1713 kwargs={ 'jsonFormat': True } )
1714 threads.append( t )
1715 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001716
1717 for t in threads:
1718 t.join()
1719 ONOSIntents.append( t.result )
1720
1721 for i in range( numControllers ):
1722 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1723 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1724 " intents" )
1725 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1726 repr( ONOSIntents[ i ] ) )
1727 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001728 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001729 expect=True,
1730 actual=intentsResults,
1731 onpass="No error in reading intents output",
1732 onfail="Error in reading intents from ONOS" )
1733
1734 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001735 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001736 main.log.report( "Intents are consistent across all ONOS " +
1737 "nodes" )
1738 else:
1739 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001740
1741 # Try to make it easy to figure out what is happening
1742 #
1743 # Intent ONOS1 ONOS2 ...
1744 # 0x01 INSTALLED INSTALLING
1745 # ... ... ...
1746 # ... ... ...
1747 title = " ID"
1748 for n in range( numControllers ):
1749 title += " " * 10 + "ONOS" + str( n + 1 )
1750 main.log.warn( title )
1751 # get all intent keys in the cluster
1752 keys = []
1753 for nodeStr in ONOSIntents:
1754 node = json.loads( nodeStr )
1755 for intent in node:
1756 keys.append( intent.get( 'id' ) )
1757 keys = set( keys )
1758 for key in keys:
1759 row = "%-13s" % key
1760 for nodeStr in ONOSIntents:
1761 node = json.loads( nodeStr )
1762 for intent in node:
1763 if intent.get( 'id' ) == key:
1764 row += "%-15s" % intent.get( 'state' )
1765 main.log.warn( row )
1766 # End table view
1767
Jon Hall65844a32015-03-09 19:09:37 -07001768 utilities.assert_equals(
1769 expect=True,
1770 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001771 onpass="Intents are consistent across all ONOS nodes",
1772 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001773 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001774 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001775 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001776 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001777 try:
1778 for intent in json.loads( node ):
1779 nodeStates.append( intent[ 'state' ] )
1780 except ( ValueError, TypeError ):
1781 main.log.exception( "Error in parsing intents" )
1782 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001783 intentStates.append( nodeStates )
1784 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1785 main.log.info( dict( out ) )
1786
Jon Hall65844a32015-03-09 19:09:37 -07001787 if intentsResults and not consistentIntents:
1788 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001789 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1790 main.log.warn( json.dumps(
1791 json.loads( ONOSIntents[ i ] ),
1792 sort_keys=True,
1793 indent=4,
1794 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001795 elif intentsResults and consistentIntents:
1796 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001797
Jon Hall58c76b72015-02-23 11:09:24 -08001798 # NOTE: Store has no durability, so intents are lost across system
1799 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001800 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001801 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001802 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001803 sameIntents = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001804 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001805 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001806 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001807 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001808 # what the acceptable states are
Jon Hallb1290e82014-11-18 16:17:48 -05001809 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001810 try:
Jon Hall65844a32015-03-09 19:09:37 -07001811 main.log.warn( "ONOS intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001812 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1813 sort_keys=True, indent=4,
1814 separators=( ',', ': ' ) ) )
1815 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001816 main.log.exception( "Exception printing intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001817 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001818 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001819 utilities.assert_equals(
1820 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001821 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001822 onpass="Intents are consistent with before failure",
1823 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001824 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001825
Jon Hall6aec96b2015-01-19 14:49:31 -08001826 main.step( "Get the OF Table entries and compare to before " +
1827 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001828 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001829 flows2 = []
1830 for i in range( 28 ):
1831 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001832 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1833 flows2.append( tmpFlows )
1834 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001835 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001836 flow2=tmpFlows )
1837 FlowTables = FlowTables and tempResult
1838 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001839 main.log.info( "Differences in flow table for switch: s" +
1840 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001841 utilities.assert_equals(
1842 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001843 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001844 onpass="No changes were found in the flow tables",
1845 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001846
Jon Hall6aec96b2015-01-19 14:49:31 -08001847 main.step( "Check the continuous pings to ensure that no packets " +
1848 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001849 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1850 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001851 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001852 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1853 for i in range( 8, 18 ):
1854 main.log.info(
1855 "Checking for a loss in pings along flow from s" +
1856 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001857 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001858 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001859 str( i ) ) or LossInPings
1860 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001861 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001862 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001863 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001864 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001865 main.log.info( "No Loss in the pings" )
1866 main.log.report( "No loss of dataplane connectivity" )
1867 utilities.assert_equals(
1868 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001869 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001870 onpass="No Loss of connectivity",
1871 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001872
Jon Hall390696c2015-05-05 17:13:41 -07001873 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001874 # Test of LeadershipElection
1875 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001876 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001877 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001878 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001879 for cli in CLIs:
1880 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001881 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001882 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001883 # all is well
1884 # NOTE: In failure scenario, this could be a new node, maybe
1885 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001886 pass
1887 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001888 # error in response
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 main.log.report( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001890 "electionTestLeader function, check the" +
1891 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001892 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001893 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001894 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001895 main.log.report( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001896 " as the leader of the election app. " +
1897 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001898 utilities.assert_equals(
1899 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001900 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001901 onpass="Leadership election passed",
1902 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001903
Jon Hall6aec96b2015-01-19 14:49:31 -08001904 def CASE8( self, main ):
1905 """
Jon Hallb1290e82014-11-18 16:17:48 -05001906 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001907 """
Jon Hallb1290e82014-11-18 16:17:48 -05001908 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001909 # FIXME add this path to params
1910 sys.path.append( "/home/admin/sts" )
1911 # assumes that sts is already in you PYTHONPATH
1912 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001913 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001914 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001915 assert numControllers, "numControllers not defined"
1916 assert main, "main not defined"
1917 assert utilities.assert_equals, "utilities.assert_equals not defined"
1918 assert CLIs, "CLIs not defined"
1919 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05001920
Jon Hallfeff3082015-05-19 10:23:26 -07001921 main.case( "Compare ONOS Topology view to Mininet topology" )
1922 main.caseExplaination = "Compare topology objects between Mininet" +\
1923 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08001924 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07001925 try:
1926 ctrls = []
1927 for node in nodes:
1928 temp = ( node, node.name, node.ip_address, 6633 )
1929 ctrls.append( temp )
1930 MNTopo = TestONTopology( main.Mininet1, ctrls )
1931 except Exception:
1932 objResult = main.FALSE
1933 else:
1934 objResult = main.TRUE
1935 utilities.assert_equals( expect=main.TRUE, actual=objResult,
1936 onpass="Created TestONTopology object",
1937 onfail="Exception while creating " +
1938 "TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001939
Jon Hallfeff3082015-05-19 10:23:26 -07001940 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001941 devicesResults = main.TRUE
1942 portsResults = main.TRUE
1943 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001944 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001945 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001946 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001947 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001949 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001950 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001951 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07001952 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001953 if count > 1:
Jon Hall65844a32015-03-09 19:09:37 -07001954 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001955 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001956 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001957 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001958 threads = []
1959 for i in range( numControllers ):
1960 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001961 name="devices-" + str( i ),
1962 args=[ ] )
1963 threads.append( t )
1964 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001965
1966 for t in threads:
1967 t.join()
1968 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001969 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001970 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001971 threads = []
1972 for i in range( numControllers ):
1973 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001974 name="hosts-" + str( i ),
1975 args=[ ] )
1976 threads.append( t )
1977 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001978
1979 for t in threads:
1980 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001981 try:
1982 hosts.append( json.loads( t.result ) )
1983 except ( ValueError, TypeError ):
1984 main.log.exception( "Error parsing hosts results" )
1985 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08001986 for controller in range( 0, len( hosts ) ):
1987 controllerStr = str( controller + 1 )
1988 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001989 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08001990 main.log.error(
1991 "DEBUG:Error with host ips on controller" +
1992 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001993 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001994 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001995 threads = []
1996 for i in range( numControllers ):
1997 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001998 name="ports-" + str( i ),
1999 args=[ ] )
2000 threads.append( t )
2001 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002002
2003 for t in threads:
2004 t.join()
2005 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002006 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002007 threads = []
2008 for i in range( numControllers ):
2009 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002010 name="links-" + str( i ),
2011 args=[ ] )
2012 threads.append( t )
2013 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002014
2015 for t in threads:
2016 t.join()
2017 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002018 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002019 threads = []
2020 for i in range( numControllers ):
2021 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002022 name="clusters-" + str( i ),
2023 args=[ ] )
2024 threads.append( t )
2025 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002026
2027 for t in threads:
2028 t.join()
2029 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002030
Jon Hall8f89dda2015-01-22 16:03:33 -08002031 elapsed = time.time() - startTime
2032 cliTime = time.time() - cliStart
2033 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002034
Jon Hall21270ac2015-02-16 17:59:55 -08002035 for controller in range( numControllers ):
2036 controllerStr = str( controller + 1 )
2037 if devices[ controller ] or "Error" not in devices[
2038 controller ]:
2039 currentDevicesResult = main.Mininet1.compareSwitches(
2040 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002041 json.loads( devices[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002042 else:
2043 currentDevicesResult = main.FALSE
2044 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002045 actual=currentDevicesResult,
2046 onpass="ONOS" + controllerStr +
2047 " Switches view is correct",
2048 onfail="ONOS" + controllerStr +
2049 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002050
Jon Hall21270ac2015-02-16 17:59:55 -08002051 if ports[ controller ] or "Error" not in ports[ controller ]:
2052 currentPortsResult = main.Mininet1.comparePorts(
2053 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002054 json.loads( ports[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002055 else:
2056 currentPortsResult = main.FALSE
2057 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002058 actual=currentPortsResult,
2059 onpass="ONOS" + controllerStr +
2060 " ports view is correct",
2061 onfail="ONOS" + controllerStr +
2062 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002063
Jon Hall21270ac2015-02-16 17:59:55 -08002064 if links[ controller ] or "Error" not in links[ controller ]:
2065 currentLinksResult = main.Mininet1.compareLinks(
2066 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002067 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002068 else:
2069 currentLinksResult = main.FALSE
2070 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002071 actual=currentLinksResult,
2072 onpass="ONOS" + controllerStr +
2073 " links view is correct",
2074 onfail="ONOS" + controllerStr +
2075 " links view is incorrect" )
2076
2077 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2078 currentHostsResult = main.Mininet1.compareHosts(
2079 MNTopo, hosts[ controller ] )
2080 else:
2081 currentHostsResult = main.FALSE
2082 utilities.assert_equals( expect=main.TRUE,
2083 actual=currentHostsResult,
2084 onpass="ONOS" + controllerStr +
2085 " hosts exist in Mininet",
2086 onfail="ONOS" + controllerStr +
2087 " hosts don't match Mininet" )
2088
2089 devicesResults = devicesResults and currentDevicesResult
2090 portsResults = portsResults and currentPortsResult
2091 linksResults = linksResults and currentLinksResult
2092 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002093
Jon Hall21270ac2015-02-16 17:59:55 -08002094 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002095
Jon Hall21270ac2015-02-16 17:59:55 -08002096 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002097 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall21270ac2015-02-16 17:59:55 -08002098 consistentHostsResult = main.TRUE
2099 for controller in range( len( hosts ) ):
2100 controllerStr = str( controller + 1 )
2101 if "Error" not in hosts[ controller ]:
2102 if hosts[ controller ] == hosts[ 0 ]:
2103 continue
2104 else: # hosts not consistent
2105 main.log.report( "hosts from ONOS" + controllerStr +
2106 " is inconsistent with ONOS1" )
2107 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002108 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002109
Jon Hall21270ac2015-02-16 17:59:55 -08002110 else:
2111 main.log.report( "Error in getting ONOS hosts from ONOS" +
2112 controllerStr )
2113 consistentHostsResult = main.FALSE
2114 main.log.warn( "ONOS" + controllerStr +
2115 " hosts response: " +
2116 repr( hosts[ controller ] ) )
2117 utilities.assert_equals(
2118 expect=main.TRUE,
2119 actual=consistentHostsResult,
2120 onpass="Hosts view is consistent across all ONOS nodes",
2121 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002122
Jon Hall21270ac2015-02-16 17:59:55 -08002123 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002124 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall21270ac2015-02-16 17:59:55 -08002125 consistentClustersResult = main.TRUE
2126 for controller in range( len( clusters ) ):
2127 controllerStr = str( controller + 1 )
2128 if "Error" not in clusters[ controller ]:
2129 if clusters[ controller ] == clusters[ 0 ]:
2130 continue
2131 else: # clusters not consistent
2132 main.log.report( "clusters from ONOS" +
2133 controllerStr +
2134 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002135 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002136
Jon Hall21270ac2015-02-16 17:59:55 -08002137 else:
2138 main.log.report( "Error in getting dataplane clusters " +
2139 "from ONOS" + controllerStr )
2140 consistentClustersResult = main.FALSE
2141 main.log.warn( "ONOS" + controllerStr +
2142 " clusters response: " +
2143 repr( clusters[ controller ] ) )
2144 utilities.assert_equals(
2145 expect=main.TRUE,
2146 actual=consistentClustersResult,
2147 onpass="Clusters view is consistent across all ONOS nodes",
2148 onfail="ONOS nodes have different views of clusters" )
2149 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002150 main.step( "Topology view is correct and consistent across all " +
2151 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002152 try:
2153 numClusters = len( json.loads( clusters[ 0 ] ) )
2154 except ( ValueError, TypeError ):
2155 main.log.exception( "Error parsing clusters[0]: " +
2156 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002157 clusterResults = main.FALSE
2158 if numClusters == 1:
2159 clusterResults = main.TRUE
Jon Hall21270ac2015-02-16 17:59:55 -08002160 utilities.assert_equals(
2161 expect=1,
2162 actual=numClusters,
2163 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002164 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002165
Jon Hall21270ac2015-02-16 17:59:55 -08002166 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002167 and hostsResults and consistentHostsResult
2168 and consistentClustersResult and clusterResults
2169 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002170
Jon Hall21270ac2015-02-16 17:59:55 -08002171 topoResult = topoResult and int( count <= 2 )
2172 note = "note it takes about " + str( int( cliTime ) ) + \
2173 " seconds for the test to make all the cli calls to fetch " +\
2174 "the topology from each ONOS instance"
2175 main.log.info(
2176 "Very crass estimate for topology discovery/convergence( " +
2177 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2178 str( count ) + " tries" )
2179 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002180 onpass="Topology Check Test successful",
2181 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05002182
Jon Halla9d26da2015-03-30 16:45:32 -07002183 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002184 main.step( "Checking ONOS nodes" )
2185 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002186 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002187 threads = []
2188 for i in range( numControllers ):
2189 t = main.Thread( target=CLIs[i].nodes,
2190 name="nodes-" + str( i ),
2191 args=[ ] )
2192 threads.append( t )
2193 t.start()
2194
2195 for t in threads:
2196 t.join()
2197 nodesOutput.append( t.result )
2198 ips = [ node.ip_address for node in nodes ]
2199 for i in nodesOutput:
2200 try:
2201 current = json.loads( i )
2202 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002203 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002204 if node['ip'] in ips: # node in nodes() output is in cell
2205 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002206 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002207 else:
2208 main.log.error( "Error in ONOS node availability" )
2209 main.log.error(
2210 json.dumps( current,
2211 sort_keys=True,
2212 indent=4,
2213 separators=( ',', ': ' ) ) )
2214 break
Jon Hall390696c2015-05-05 17:13:41 -07002215 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002216 except ( ValueError, TypeError ):
2217 main.log.error( "Error parsing nodes output" )
2218 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002219 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2220 onpass="Nodes check successful",
2221 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002222
Jon Hall6aec96b2015-01-19 14:49:31 -08002223 def CASE9( self, main ):
2224 """
Jon Hallb1290e82014-11-18 16:17:48 -05002225 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002226 """
2227 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002228 assert numControllers, "numControllers not defined"
2229 assert main, "main not defined"
2230 assert utilities.assert_equals, "utilities.assert_equals not defined"
2231 assert CLIs, "CLIs not defined"
2232 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002234
Jon Hall8f89dda2015-01-22 16:03:33 -08002235 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002236
Jon Hall6aec96b2015-01-19 14:49:31 -08002237 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002238 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002239 main.log.report( description )
2240 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002241
Jon Hall6aec96b2015-01-19 14:49:31 -08002242 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002243 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002244 main.log.info( "Waiting " + str( linkSleep ) +
2245 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002246 time.sleep( linkSleep )
2247 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002248 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002249 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002250 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002251
Jon Hall6aec96b2015-01-19 14:49:31 -08002252 def CASE10( self, main ):
2253 """
Jon Hallb1290e82014-11-18 16:17:48 -05002254 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002255 """
2256 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002257 assert numControllers, "numControllers not defined"
2258 assert main, "main not defined"
2259 assert utilities.assert_equals, "utilities.assert_equals not defined"
2260 assert CLIs, "CLIs not defined"
2261 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002262 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002263
Jon Hall8f89dda2015-01-22 16:03:33 -08002264 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002265
Jon Hall6aec96b2015-01-19 14:49:31 -08002266 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002267 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002268 main.log.report( description )
2269 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002270
Jon Hall6aec96b2015-01-19 14:49:31 -08002271 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002272 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002273 main.log.info( "Waiting " + str( linkSleep ) +
2274 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002275 time.sleep( linkSleep )
2276 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002277 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002278 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002279 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002280
Jon Hall6aec96b2015-01-19 14:49:31 -08002281 def CASE11( self, main ):
2282 """
Jon Hallb1290e82014-11-18 16:17:48 -05002283 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002284 """
2285 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002286 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002287 assert numControllers, "numControllers not defined"
2288 assert main, "main not defined"
2289 assert utilities.assert_equals, "utilities.assert_equals not defined"
2290 assert CLIs, "CLIs not defined"
2291 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002292
Jon Hall8f89dda2015-01-22 16:03:33 -08002293 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002294
2295 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002296 main.log.report( description )
2297 main.case( description )
2298 switch = main.params[ 'kill' ][ 'switch' ]
2299 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002300
Jon Hall6aec96b2015-01-19 14:49:31 -08002301 # TODO: Make this switch parameterizable
2302 main.step( "Kill " + switch )
2303 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002304 main.Mininet1.delSwitch( switch )
2305 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002306 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002307 time.sleep( switchSleep )
2308 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002309 # Peek at the deleted switch
2310 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002311 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002312 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002313 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002314 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002315 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002316 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002317
Jon Hall6aec96b2015-01-19 14:49:31 -08002318 def CASE12( self, main ):
2319 """
Jon Hallb1290e82014-11-18 16:17:48 -05002320 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002321 """
2322 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002323 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002324 assert numControllers, "numControllers not defined"
2325 assert main, "main not defined"
2326 assert utilities.assert_equals, "utilities.assert_equals not defined"
2327 assert CLIs, "CLIs not defined"
2328 assert nodes, "nodes not defined"
2329 assert ONOS1Port, "ONOS1Port not defined"
2330 assert ONOS2Port, "ONOS2Port not defined"
2331 assert ONOS3Port, "ONOS3Port not defined"
2332 assert ONOS4Port, "ONOS4Port not defined"
2333 assert ONOS5Port, "ONOS5Port not defined"
2334 assert ONOS6Port, "ONOS6Port not defined"
2335 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002336
Jon Hall8f89dda2015-01-22 16:03:33 -08002337 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002338 switch = main.params[ 'kill' ][ 'switch' ]
2339 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2340 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002341 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002342 main.log.report( description )
2343 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002344
Jon Hall6aec96b2015-01-19 14:49:31 -08002345 main.step( "Add back " + switch )
2346 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002347 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002348 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002349 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002350 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2351 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -07002352 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002353 port1=ONOS1Port,
Jon Hall65844a32015-03-09 19:09:37 -07002354 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002355 port2=ONOS2Port,
Jon Hall65844a32015-03-09 19:09:37 -07002356 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002357 port3=ONOS3Port,
Jon Hall65844a32015-03-09 19:09:37 -07002358 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002359 port4=ONOS4Port,
Jon Hall65844a32015-03-09 19:09:37 -07002360 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002361 port5=ONOS5Port,
Jon Hall65844a32015-03-09 19:09:37 -07002362 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002363 port6=ONOS6Port,
Jon Hall65844a32015-03-09 19:09:37 -07002364 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002365 port7=ONOS7Port )
2366 main.log.info( "Waiting " + str( switchSleep ) +
2367 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002368 time.sleep( switchSleep )
2369 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002370 # Peek at the deleted switch
2371 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002372 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002373 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002374 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002375 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002376 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002377 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002378
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 def CASE13( self, main ):
2380 """
Jon Hallb1290e82014-11-18 16:17:48 -05002381 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002382 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002383 import os
2384 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002385 assert numControllers, "numControllers not defined"
2386 assert main, "main not defined"
2387 assert utilities.assert_equals, "utilities.assert_equals not defined"
2388 assert CLIs, "CLIs not defined"
2389 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002390
2391 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002392 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2393 'blue': '\033[94m', 'green': '\033[92m',
2394 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall368769f2014-11-19 15:43:35 -08002395 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002396 main.log.report( description )
2397 main.case( description )
2398 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002399 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002400
Jon Hall6aec96b2015-01-19 14:49:31 -08002401 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002402 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002403 teststationUser = main.params[ 'TESTONUSER' ]
2404 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002405 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002406 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002407 # FIXME: scp
2408 # mn files
2409 # TODO: Load these from params
2410 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002411 logFolder = "/opt/onos/log/"
2412 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002413 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002414 dstDir = "~/packet_captures/"
2415 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002416 for node in nodes:
2417 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2418 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002419 teststationUser + "@" +
2420 teststationIP + ":" +
2421 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002422 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002423 main.ONOSbench.handle.expect( "\$" )
2424
Jon Hall6aec96b2015-01-19 14:49:31 -08002425 # std*.log's
2426 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002427 logFolder = "/opt/onos/var/"
2428 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002430 dstDir = "~/packet_captures/"
2431 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002432 for node in nodes:
2433 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2434 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002435 teststationUser + "@" +
2436 teststationIP + ":" +
2437 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002438 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002439 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002440 # sleep so scp can finish
2441 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002442
2443 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002444 mnResult = main.Mininet1.stopNet()
2445 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2446 onpass="Mininet stopped",
2447 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002448
2449 main.step( "Checking ONOS Logs for errors" )
2450 for node in nodes:
2451 print colors[ 'purple' ] + "Checking logs for errors on " + \
2452 node.name + ":" + colors[ 'end' ]
2453 print main.ONOSbench.checkLogs( node.ip_address )
2454
Jon Hall6aec96b2015-01-19 14:49:31 -08002455 main.step( "Packing and rotating pcap archives" )
2456 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002457
Jon Hall390696c2015-05-05 17:13:41 -07002458 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002459 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002460 # Overwrite with empty line and close
Jon Hallfeff3082015-05-19 10:23:26 -07002461 timerLog.write( "Gossip Intents\n" )
2462 timerLog.write( str( gossipTime ) )
2463 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002464 except NameError, e:
2465 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002466
Jon Hall6aec96b2015-01-19 14:49:31 -08002467 def CASE14( self, main ):
2468 """
Jon Hall94fd0472014-12-08 11:52:42 -08002469 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002470 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002471 assert numControllers, "numControllers not defined"
2472 assert main, "main not defined"
2473 assert utilities.assert_equals, "utilities.assert_equals not defined"
2474 assert CLIs, "CLIs not defined"
2475 assert nodes, "nodes not defined"
2476
Jon Hall390696c2015-05-05 17:13:41 -07002477 main.case("Start Leadership Election app")
2478 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002479 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2480 utilities.assert_equals(
2481 expect=main.TRUE,
2482 actual=appResult,
2483 onpass="Election app installed",
2484 onfail="Something went wrong with installing Leadership election" )
2485
2486 main.step( "Run for election on each node" )
2487 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002488 leaders = []
2489 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002490 cli.electionTestRun()
2491 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002492 leader = cli.electionTestLeader()
2493 if leader is None or leader == main.FALSE:
2494 main.log.report( cli.name + ": Leader for the election app " +
2495 "should be an ONOS node, instead got '" +
2496 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002497 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002498 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002499 utilities.assert_equals(
2500 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002501 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002502 onpass="Successfully ran for leadership",
2503 onfail="Failed to run for leadership" )
2504
2505 main.step( "Check that each node shows the same leader" )
2506 sameLeader = main.TRUE
2507 if len( set( leaders ) ) != 1:
2508 sameLeader = main.FALSE
2509 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2510 str( leaders ) )
2511 utilities.assert_equals(
2512 expect=main.TRUE,
2513 actual=sameLeader,
2514 onpass="Leadership is consistent for the election topic",
2515 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002516
Jon Hall6aec96b2015-01-19 14:49:31 -08002517 def CASE15( self, main ):
2518 """
Jon Hall669173b2014-12-17 11:36:30 -08002519 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002520 """
Jon Hall390696c2015-05-05 17:13:41 -07002521 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002522 assert numControllers, "numControllers not defined"
2523 assert main, "main not defined"
2524 assert utilities.assert_equals, "utilities.assert_equals not defined"
2525 assert CLIs, "CLIs not defined"
2526 assert nodes, "nodes not defined"
2527
Jon Hall8f89dda2015-01-22 16:03:33 -08002528 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002529 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002530 main.log.report( description )
2531 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002532
2533 main.step( "Check that each node shows the same leader" )
2534 sameLeader = main.TRUE
2535 leaders = []
2536 for cli in CLIs:
2537 leader = cli.electionTestLeader()
2538 leaders.append( leader )
2539 if len( set( leaders ) ) != 1:
2540 sameLeader = main.FALSE
2541 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2542 str( leaders ) )
2543 utilities.assert_equals(
2544 expect=main.TRUE,
2545 actual=sameLeader,
2546 onpass="Leadership is consistent for the election topic",
2547 onfail="Nodes have different leaders" )
2548
Jon Hall6aec96b2015-01-19 14:49:31 -08002549 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002550 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002551 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002552 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002553 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002554 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002556 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002557 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002558 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002559 for i in range( len( CLIs ) ):
2560 if leader == nodes[ i ].ip_address:
2561 oldLeader = CLIs[ i ]
2562 break
Jon Halla9d26da2015-03-30 16:45:32 -07002563 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002564 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002565 if oldLeader:
2566 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002567 utilities.assert_equals(
2568 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002569 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002570 onpass="Node was withdrawn from election",
2571 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002572
Jon Hall6aec96b2015-01-19 14:49:31 -08002573 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002574 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002575 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002576 for cli in CLIs:
2577 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002578 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002579 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002580 main.log.report( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002581 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002582 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002583 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002584 # error in response
2585 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002586 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002587 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002588 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002589 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002590 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002591 elif leaderN is None:
2592 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002593 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002594 leaderN = cli.electionTestLeader()
2595 leaderList.pop()
2596 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002597 consistentLeader = main.FALSE
2598 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002599 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002600 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002601 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002602 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002603 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002604 main.log.report(
2605 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002606 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002607 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002608 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002609 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002610 utilities.assert_equals(
2611 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002612 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002613 onpass="Leadership election passed",
2614 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002615
Jon Hall58c76b72015-02-23 11:09:24 -08002616 main.step( "Run for election on old leader( just so everyone " +
2617 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002618 if oldLeader:
2619 runResult = oldLeader.electionTestRun()
2620 else:
2621 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002622 utilities.assert_equals(
2623 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002624 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002625 onpass="App re-ran for election",
2626 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002627
Jon Hallfeff3082015-05-19 10:23:26 -07002628 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002629 afterRun = main.ONOScli1.electionTestLeader()
2630 # verify leader didn't just change
2631 if afterRun == leaderList[ 0 ]:
2632 afterResult = main.TRUE
2633 else:
2634 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002635
Jon Hall6aec96b2015-01-19 14:49:31 -08002636 utilities.assert_equals(
2637 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002638 actual=afterResult,
2639 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002640 onfail="Something went wrong with Leadership election after " +
2641 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002642
Jon Hall390696c2015-05-05 17:13:41 -07002643 def CASE16( self, main ):
2644 """
2645 Install Distributed Primitives app
2646 """
2647 assert numControllers, "numControllers not defined"
2648 assert main, "main not defined"
2649 assert utilities.assert_equals, "utilities.assert_equals not defined"
2650 assert CLIs, "CLIs not defined"
2651 assert nodes, "nodes not defined"
2652
2653 # Variables for the distributed primitives tests
2654 global pCounterName
2655 global iCounterName
2656 global pCounterValue
2657 global iCounterValue
2658 global onosSet
2659 global onosSetName
2660 pCounterName = "TestON-Partitions"
2661 iCounterName = "TestON-inMemory"
2662 pCounterValue = 0
2663 iCounterValue = 0
2664 onosSet = set([])
2665 onosSetName = "TestON-set"
2666
2667 description = "Install Primitives app"
2668 main.case( description )
2669 main.step( "Install Primitives app" )
2670 appName = "org.onosproject.distributedprimitives"
2671 appResults = CLIs[0].activateApp( appName )
2672 utilities.assert_equals( expect=main.TRUE,
2673 actual=appResults,
2674 onpass="Primitives app activated",
2675 onfail="Primitives app not activated" )
Jon Hallfeff3082015-05-19 10:23:26 -07002676 time.sleep (5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002677
2678 def CASE17( self, main ):
2679 """
2680 Check for basic functionality with distributed primitives
2681 """
2682 # Make sure variables are defined/set
2683 assert numControllers, "numControllers not defined"
2684 assert main, "main not defined"
2685 assert utilities.assert_equals, "utilities.assert_equals not defined"
2686 assert CLIs, "CLIs not defined"
2687 assert nodes, "nodes not defined"
2688 assert pCounterName, "pCounterName not defined"
2689 assert iCounterName, "iCounterName not defined"
2690 assert onosSetName, "onosSetName not defined"
2691 # NOTE: assert fails if value is 0/None/Empty/False
2692 try:
2693 pCounterValue
2694 except NameError:
2695 main.log.error( "pCounterValue not defined, setting to 0" )
2696 pCounterValue = 0
2697 try:
2698 iCounterValue
2699 except NameError:
2700 main.log.error( "iCounterValue not defined, setting to 0" )
2701 iCounterValue = 0
2702 try:
2703 onosSet
2704 except NameError:
2705 main.log.error( "onosSet not defined, setting to empty Set" )
2706 onosSet = set([])
2707 # Variables for the distributed primitives tests. These are local only
2708 addValue = "a"
2709 addAllValue = "a b c d e f"
2710 retainValue = "c d e f"
2711
2712 description = "Check for basic functionality with distributed " +\
2713 "primitives"
2714 main.case( description )
2715 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2716 # DISTRIBUTED ATOMIC COUNTERS
2717 main.step( "Increment and get a default counter on each node" )
2718 pCounters = []
2719 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002720 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002721 for i in range( numControllers ):
2722 t = main.Thread( target=CLIs[i].counterTestIncrement,
2723 name="counterIncrement-" + str( i ),
2724 args=[ pCounterName ] )
2725 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002726 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002727 threads.append( t )
2728 t.start()
2729
2730 for t in threads:
2731 t.join()
2732 pCounters.append( t.result )
2733 # Check that counter incremented numController times
2734 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002735 for i in addedPValues:
2736 tmpResult = i in pCounters
2737 pCounterResults = pCounterResults and tmpResult
2738 if not tmpResult:
2739 main.log.error( str( i ) + " is not in partitioned "
2740 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002741 utilities.assert_equals( expect=True,
2742 actual=pCounterResults,
2743 onpass="Default counter incremented",
2744 onfail="Error incrementing default" +
2745 " counter" )
2746
2747 main.step( "Increment and get an in memory counter on each node" )
2748 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002749 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002750 threads = []
2751 for i in range( numControllers ):
2752 t = main.Thread( target=CLIs[i].counterTestIncrement,
2753 name="icounterIncrement-" + str( i ),
2754 args=[ iCounterName ],
2755 kwargs={ "inMemory": True } )
2756 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002757 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002758 threads.append( t )
2759 t.start()
2760
2761 for t in threads:
2762 t.join()
2763 iCounters.append( t.result )
2764 # Check that counter incremented numController times
2765 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002766 for i in addedIValues:
2767 tmpResult = i in iCounters
2768 iCounterResults = iCounterResults and tmpResult
2769 if not tmpResult:
2770 main.log.error( str( i ) + " is not in the in-memory "
2771 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002772 utilities.assert_equals( expect=True,
2773 actual=iCounterResults,
2774 onpass="In memory counter incremented",
2775 onfail="Error incrementing in memory" +
2776 " counter" )
2777
2778 main.step( "Check counters are consistant across nodes" )
2779 onosCounters = []
2780 threads = []
2781 for i in range( numControllers ):
2782 t = main.Thread( target=CLIs[i].counters,
2783 name="counters-" + str( i ) )
2784 threads.append( t )
2785 t.start()
2786 for t in threads:
2787 t.join()
2788 onosCounters.append( t.result )
2789 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2790 if all( tmp ):
2791 main.log.info( "Counters are consistent across all nodes" )
2792 consistentCounterResults = main.TRUE
2793 else:
2794 main.log.error( "Counters are not consistent across all nodes" )
2795 consistentCounterResults = main.FALSE
2796 utilities.assert_equals( expect=main.TRUE,
2797 actual=consistentCounterResults,
2798 onpass="ONOS counters are consistent " +
2799 "across nodes",
2800 onfail="ONOS Counters are inconsistent " +
2801 "across nodes" )
2802
2803 main.step( "Counters we added have the correct values" )
2804 correctResults = main.TRUE
2805 for i in range( numControllers ):
2806 current = onosCounters[i]
2807 try:
2808 pValue = current.get( pCounterName )
2809 iValue = current.get( iCounterName )
2810 if pValue == pCounterValue:
2811 main.log.info( "Partitioned counter value is correct" )
2812 else:
2813 main.log.error( "Partitioned counter value is incorrect," +
2814 " expected value: " + str( pCounterValue )
2815 + " current value: " + str( pValue ) )
2816 correctResults = main.FALSE
2817 if iValue == iCounterValue:
2818 main.log.info( "In memory counter value is correct" )
2819 else:
2820 main.log.error( "In memory counter value is incorrect, " +
2821 "expected value: " + str( iCounterValue ) +
2822 " current value: " + str( iValue ) )
2823 correctResults = main.FALSE
2824 except AttributeError, e:
2825 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2826 "is not as expected" )
2827 correctResults = main.FALSE
2828 utilities.assert_equals( expect=main.TRUE,
2829 actual=correctResults,
2830 onpass="Added counters are correct",
2831 onfail="Added counters are incorrect" )
2832 # DISTRIBUTED SETS
2833 main.step( "Distributed Set get" )
2834 size = len( onosSet )
2835 getResponses = []
2836 threads = []
2837 for i in range( numControllers ):
2838 t = main.Thread( target=CLIs[i].setTestGet,
2839 name="setTestGet-" + str( i ),
2840 args=[ onosSetName ] )
2841 threads.append( t )
2842 t.start()
2843 for t in threads:
2844 t.join()
2845 getResponses.append( t.result )
2846
2847 getResults = main.TRUE
2848 for i in range( numControllers ):
2849 if isinstance( getResponses[ i ], list):
2850 current = set( getResponses[ i ] )
2851 if len( current ) == len( getResponses[ i ] ):
2852 # no repeats
2853 if onosSet != current:
2854 main.log.error( "ONOS" + str( i + 1 ) +
2855 " has incorrect view" +
2856 " of set " + onosSetName + ":\n" +
2857 str( getResponses[ i ] ) )
2858 main.log.debug( "Expected: " + str( onosSet ) )
2859 main.log.debug( "Actual: " + str( current ) )
2860 getResults = main.FALSE
2861 else:
2862 # error, set is not a set
2863 main.log.error( "ONOS" + str( i + 1 ) +
2864 " has repeat elements in" +
2865 " set " + onosSetName + ":\n" +
2866 str( getResponses[ i ] ) )
2867 getResults = main.FALSE
2868 elif getResponses[ i ] == main.ERROR:
2869 getResults = main.FALSE
2870 utilities.assert_equals( expect=main.TRUE,
2871 actual=getResults,
2872 onpass="Set elements are correct",
2873 onfail="Set elements are incorrect" )
2874
2875 main.step( "Distributed Set size" )
2876 sizeResponses = []
2877 threads = []
2878 for i in range( numControllers ):
2879 t = main.Thread( target=CLIs[i].setTestSize,
2880 name="setTestSize-" + str( i ),
2881 args=[ onosSetName ] )
2882 threads.append( t )
2883 t.start()
2884 for t in threads:
2885 t.join()
2886 sizeResponses.append( t.result )
2887
2888 sizeResults = main.TRUE
2889 for i in range( numControllers ):
2890 if size != sizeResponses[ i ]:
2891 sizeResults = main.FALSE
2892 main.log.error( "ONOS" + str( i + 1 ) +
2893 " expected a size of " + str( size ) +
2894 " for set " + onosSetName +
2895 " but got " + str( sizeResponses[ i ] ) )
2896 utilities.assert_equals( expect=main.TRUE,
2897 actual=sizeResults,
2898 onpass="Set sizes are correct",
2899 onfail="Set sizes are incorrect" )
2900
2901 main.step( "Distributed Set add()" )
2902 onosSet.add( addValue )
2903 addResponses = []
2904 threads = []
2905 for i in range( numControllers ):
2906 t = main.Thread( target=CLIs[i].setTestAdd,
2907 name="setTestAdd-" + str( i ),
2908 args=[ onosSetName, addValue ] )
2909 threads.append( t )
2910 t.start()
2911 for t in threads:
2912 t.join()
2913 addResponses.append( t.result )
2914
2915 # main.TRUE = successfully changed the set
2916 # main.FALSE = action resulted in no change in set
2917 # main.ERROR - Some error in executing the function
2918 addResults = main.TRUE
2919 for i in range( numControllers ):
2920 if addResponses[ i ] == main.TRUE:
2921 # All is well
2922 pass
2923 elif addResponses[ i ] == main.FALSE:
2924 # Already in set, probably fine
2925 pass
2926 elif addResponses[ i ] == main.ERROR:
2927 # Error in execution
2928 addResults = main.FALSE
2929 else:
2930 # unexpected result
2931 addResults = main.FALSE
2932 if addResults != main.TRUE:
2933 main.log.error( "Error executing set add" )
2934
2935 # Check if set is still correct
2936 size = len( onosSet )
2937 getResponses = []
2938 threads = []
2939 for i in range( numControllers ):
2940 t = main.Thread( target=CLIs[i].setTestGet,
2941 name="setTestGet-" + str( i ),
2942 args=[ onosSetName ] )
2943 threads.append( t )
2944 t.start()
2945 for t in threads:
2946 t.join()
2947 getResponses.append( t.result )
2948 getResults = main.TRUE
2949 for i in range( numControllers ):
2950 if isinstance( getResponses[ i ], list):
2951 current = set( getResponses[ i ] )
2952 if len( current ) == len( getResponses[ i ] ):
2953 # no repeats
2954 if onosSet != current:
2955 main.log.error( "ONOS" + str( i + 1 ) +
2956 " has incorrect view" +
2957 " of set " + onosSetName + ":\n" +
2958 str( getResponses[ i ] ) )
2959 main.log.debug( "Expected: " + str( onosSet ) )
2960 main.log.debug( "Actual: " + str( current ) )
2961 getResults = main.FALSE
2962 else:
2963 # error, set is not a set
2964 main.log.error( "ONOS" + str( i + 1 ) +
2965 " has repeat elements in" +
2966 " set " + onosSetName + ":\n" +
2967 str( getResponses[ i ] ) )
2968 getResults = main.FALSE
2969 elif getResponses[ i ] == main.ERROR:
2970 getResults = main.FALSE
2971 sizeResponses = []
2972 threads = []
2973 for i in range( numControllers ):
2974 t = main.Thread( target=CLIs[i].setTestSize,
2975 name="setTestSize-" + str( i ),
2976 args=[ onosSetName ] )
2977 threads.append( t )
2978 t.start()
2979 for t in threads:
2980 t.join()
2981 sizeResponses.append( t.result )
2982 sizeResults = main.TRUE
2983 for i in range( numControllers ):
2984 if size != sizeResponses[ i ]:
2985 sizeResults = main.FALSE
2986 main.log.error( "ONOS" + str( i + 1 ) +
2987 " expected a size of " + str( size ) +
2988 " for set " + onosSetName +
2989 " but got " + str( sizeResponses[ i ] ) )
2990 addResults = addResults and getResults and sizeResults
2991 utilities.assert_equals( expect=main.TRUE,
2992 actual=addResults,
2993 onpass="Set add correct",
2994 onfail="Set add was incorrect" )
2995
2996 main.step( "Distributed Set addAll()" )
2997 onosSet.update( addAllValue.split() )
2998 addResponses = []
2999 threads = []
3000 for i in range( numControllers ):
3001 t = main.Thread( target=CLIs[i].setTestAdd,
3002 name="setTestAddAll-" + str( i ),
3003 args=[ onosSetName, addAllValue ] )
3004 threads.append( t )
3005 t.start()
3006 for t in threads:
3007 t.join()
3008 addResponses.append( t.result )
3009
3010 # main.TRUE = successfully changed the set
3011 # main.FALSE = action resulted in no change in set
3012 # main.ERROR - Some error in executing the function
3013 addAllResults = main.TRUE
3014 for i in range( numControllers ):
3015 if addResponses[ i ] == main.TRUE:
3016 # All is well
3017 pass
3018 elif addResponses[ i ] == main.FALSE:
3019 # Already in set, probably fine
3020 pass
3021 elif addResponses[ i ] == main.ERROR:
3022 # Error in execution
3023 addAllResults = main.FALSE
3024 else:
3025 # unexpected result
3026 addAllResults = main.FALSE
3027 if addAllResults != main.TRUE:
3028 main.log.error( "Error executing set addAll" )
3029
3030 # Check if set is still correct
3031 size = len( onosSet )
3032 getResponses = []
3033 threads = []
3034 for i in range( numControllers ):
3035 t = main.Thread( target=CLIs[i].setTestGet,
3036 name="setTestGet-" + str( i ),
3037 args=[ onosSetName ] )
3038 threads.append( t )
3039 t.start()
3040 for t in threads:
3041 t.join()
3042 getResponses.append( t.result )
3043 getResults = main.TRUE
3044 for i in range( numControllers ):
3045 if isinstance( getResponses[ i ], list):
3046 current = set( getResponses[ i ] )
3047 if len( current ) == len( getResponses[ i ] ):
3048 # no repeats
3049 if onosSet != current:
3050 main.log.error( "ONOS" + str( i + 1 ) +
3051 " has incorrect view" +
3052 " of set " + onosSetName + ":\n" +
3053 str( getResponses[ i ] ) )
3054 main.log.debug( "Expected: " + str( onosSet ) )
3055 main.log.debug( "Actual: " + str( current ) )
3056 getResults = main.FALSE
3057 else:
3058 # error, set is not a set
3059 main.log.error( "ONOS" + str( i + 1 ) +
3060 " has repeat elements in" +
3061 " set " + onosSetName + ":\n" +
3062 str( getResponses[ i ] ) )
3063 getResults = main.FALSE
3064 elif getResponses[ i ] == main.ERROR:
3065 getResults = main.FALSE
3066 sizeResponses = []
3067 threads = []
3068 for i in range( numControllers ):
3069 t = main.Thread( target=CLIs[i].setTestSize,
3070 name="setTestSize-" + str( i ),
3071 args=[ onosSetName ] )
3072 threads.append( t )
3073 t.start()
3074 for t in threads:
3075 t.join()
3076 sizeResponses.append( t.result )
3077 sizeResults = main.TRUE
3078 for i in range( numControllers ):
3079 if size != sizeResponses[ i ]:
3080 sizeResults = main.FALSE
3081 main.log.error( "ONOS" + str( i + 1 ) +
3082 " expected a size of " + str( size ) +
3083 " for set " + onosSetName +
3084 " but got " + str( sizeResponses[ i ] ) )
3085 addAllResults = addAllResults and getResults and sizeResults
3086 utilities.assert_equals( expect=main.TRUE,
3087 actual=addAllResults,
3088 onpass="Set addAll correct",
3089 onfail="Set addAll was incorrect" )
3090
3091 main.step( "Distributed Set contains()" )
3092 containsResponses = []
3093 threads = []
3094 for i in range( numControllers ):
3095 t = main.Thread( target=CLIs[i].setTestGet,
3096 name="setContains-" + str( i ),
3097 args=[ onosSetName ],
3098 kwargs={ "values": addValue } )
3099 threads.append( t )
3100 t.start()
3101 for t in threads:
3102 t.join()
3103 # NOTE: This is the tuple
3104 containsResponses.append( t.result )
3105
3106 containsResults = main.TRUE
3107 for i in range( numControllers ):
3108 if containsResponses[ i ] == main.ERROR:
3109 containsResults = main.FALSE
3110 else:
3111 containsResults = containsResults and\
3112 containsResponses[ i ][ 1 ]
3113 utilities.assert_equals( expect=main.TRUE,
3114 actual=containsResults,
3115 onpass="Set contains is functional",
3116 onfail="Set contains failed" )
3117
3118 main.step( "Distributed Set containsAll()" )
3119 containsAllResponses = []
3120 threads = []
3121 for i in range( numControllers ):
3122 t = main.Thread( target=CLIs[i].setTestGet,
3123 name="setContainsAll-" + str( i ),
3124 args=[ onosSetName ],
3125 kwargs={ "values": addAllValue } )
3126 threads.append( t )
3127 t.start()
3128 for t in threads:
3129 t.join()
3130 # NOTE: This is the tuple
3131 containsAllResponses.append( t.result )
3132
3133 containsAllResults = main.TRUE
3134 for i in range( numControllers ):
3135 if containsResponses[ i ] == main.ERROR:
3136 containsResults = main.FALSE
3137 else:
3138 containsResults = containsResults and\
3139 containsResponses[ i ][ 1 ]
3140 utilities.assert_equals( expect=main.TRUE,
3141 actual=containsAllResults,
3142 onpass="Set containsAll is functional",
3143 onfail="Set containsAll failed" )
3144
3145 main.step( "Distributed Set remove()" )
3146 onosSet.remove( addValue )
3147 removeResponses = []
3148 threads = []
3149 for i in range( numControllers ):
3150 t = main.Thread( target=CLIs[i].setTestRemove,
3151 name="setTestRemove-" + str( i ),
3152 args=[ onosSetName, addValue ] )
3153 threads.append( t )
3154 t.start()
3155 for t in threads:
3156 t.join()
3157 removeResponses.append( t.result )
3158
3159 # main.TRUE = successfully changed the set
3160 # main.FALSE = action resulted in no change in set
3161 # main.ERROR - Some error in executing the function
3162 removeResults = main.TRUE
3163 for i in range( numControllers ):
3164 if removeResponses[ i ] == main.TRUE:
3165 # All is well
3166 pass
3167 elif removeResponses[ i ] == main.FALSE:
3168 # not in set, probably fine
3169 pass
3170 elif removeResponses[ i ] == main.ERROR:
3171 # Error in execution
3172 removeResults = main.FALSE
3173 else:
3174 # unexpected result
3175 removeResults = main.FALSE
3176 if removeResults != main.TRUE:
3177 main.log.error( "Error executing set remove" )
3178
3179 # Check if set is still correct
3180 size = len( onosSet )
3181 getResponses = []
3182 threads = []
3183 for i in range( numControllers ):
3184 t = main.Thread( target=CLIs[i].setTestGet,
3185 name="setTestGet-" + str( i ),
3186 args=[ onosSetName ] )
3187 threads.append( t )
3188 t.start()
3189 for t in threads:
3190 t.join()
3191 getResponses.append( t.result )
3192 getResults = main.TRUE
3193 for i in range( numControllers ):
3194 if isinstance( getResponses[ i ], list):
3195 current = set( getResponses[ i ] )
3196 if len( current ) == len( getResponses[ i ] ):
3197 # no repeats
3198 if onosSet != current:
3199 main.log.error( "ONOS" + str( i + 1 ) +
3200 " has incorrect view" +
3201 " of set " + onosSetName + ":\n" +
3202 str( getResponses[ i ] ) )
3203 main.log.debug( "Expected: " + str( onosSet ) )
3204 main.log.debug( "Actual: " + str( current ) )
3205 getResults = main.FALSE
3206 else:
3207 # error, set is not a set
3208 main.log.error( "ONOS" + str( i + 1 ) +
3209 " has repeat elements in" +
3210 " set " + onosSetName + ":\n" +
3211 str( getResponses[ i ] ) )
3212 getResults = main.FALSE
3213 elif getResponses[ i ] == main.ERROR:
3214 getResults = main.FALSE
3215 sizeResponses = []
3216 threads = []
3217 for i in range( numControllers ):
3218 t = main.Thread( target=CLIs[i].setTestSize,
3219 name="setTestSize-" + str( i ),
3220 args=[ onosSetName ] )
3221 threads.append( t )
3222 t.start()
3223 for t in threads:
3224 t.join()
3225 sizeResponses.append( t.result )
3226 sizeResults = main.TRUE
3227 for i in range( numControllers ):
3228 if size != sizeResponses[ i ]:
3229 sizeResults = main.FALSE
3230 main.log.error( "ONOS" + str( i + 1 ) +
3231 " expected a size of " + str( size ) +
3232 " for set " + onosSetName +
3233 " but got " + str( sizeResponses[ i ] ) )
3234 removeResults = removeResults and getResults and sizeResults
3235 utilities.assert_equals( expect=main.TRUE,
3236 actual=removeResults,
3237 onpass="Set remove correct",
3238 onfail="Set remove was incorrect" )
3239
3240 main.step( "Distributed Set removeAll()" )
3241 onosSet.difference_update( addAllValue.split() )
3242 removeAllResponses = []
3243 threads = []
3244 try:
3245 for i in range( numControllers ):
3246 t = main.Thread( target=CLIs[i].setTestRemove,
3247 name="setTestRemoveAll-" + str( i ),
3248 args=[ onosSetName, addAllValue ] )
3249 threads.append( t )
3250 t.start()
3251 for t in threads:
3252 t.join()
3253 removeAllResponses.append( t.result )
3254 except Exception, e:
3255 main.log.exception(e)
3256
3257 # main.TRUE = successfully changed the set
3258 # main.FALSE = action resulted in no change in set
3259 # main.ERROR - Some error in executing the function
3260 removeAllResults = main.TRUE
3261 for i in range( numControllers ):
3262 if removeAllResponses[ i ] == main.TRUE:
3263 # All is well
3264 pass
3265 elif removeAllResponses[ i ] == main.FALSE:
3266 # not in set, probably fine
3267 pass
3268 elif removeAllResponses[ i ] == main.ERROR:
3269 # Error in execution
3270 removeAllResults = main.FALSE
3271 else:
3272 # unexpected result
3273 removeAllResults = main.FALSE
3274 if removeAllResults != main.TRUE:
3275 main.log.error( "Error executing set removeAll" )
3276
3277 # Check if set is still correct
3278 size = len( onosSet )
3279 getResponses = []
3280 threads = []
3281 for i in range( numControllers ):
3282 t = main.Thread( target=CLIs[i].setTestGet,
3283 name="setTestGet-" + str( i ),
3284 args=[ onosSetName ] )
3285 threads.append( t )
3286 t.start()
3287 for t in threads:
3288 t.join()
3289 getResponses.append( t.result )
3290 getResults = main.TRUE
3291 for i in range( numControllers ):
3292 if isinstance( getResponses[ i ], list):
3293 current = set( getResponses[ i ] )
3294 if len( current ) == len( getResponses[ i ] ):
3295 # no repeats
3296 if onosSet != current:
3297 main.log.error( "ONOS" + str( i + 1 ) +
3298 " has incorrect view" +
3299 " of set " + onosSetName + ":\n" +
3300 str( getResponses[ i ] ) )
3301 main.log.debug( "Expected: " + str( onosSet ) )
3302 main.log.debug( "Actual: " + str( current ) )
3303 getResults = main.FALSE
3304 else:
3305 # error, set is not a set
3306 main.log.error( "ONOS" + str( i + 1 ) +
3307 " has repeat elements in" +
3308 " set " + onosSetName + ":\n" +
3309 str( getResponses[ i ] ) )
3310 getResults = main.FALSE
3311 elif getResponses[ i ] == main.ERROR:
3312 getResults = main.FALSE
3313 sizeResponses = []
3314 threads = []
3315 for i in range( numControllers ):
3316 t = main.Thread( target=CLIs[i].setTestSize,
3317 name="setTestSize-" + str( i ),
3318 args=[ onosSetName ] )
3319 threads.append( t )
3320 t.start()
3321 for t in threads:
3322 t.join()
3323 sizeResponses.append( t.result )
3324 sizeResults = main.TRUE
3325 for i in range( numControllers ):
3326 if size != sizeResponses[ i ]:
3327 sizeResults = main.FALSE
3328 main.log.error( "ONOS" + str( i + 1 ) +
3329 " expected a size of " + str( size ) +
3330 " for set " + onosSetName +
3331 " but got " + str( sizeResponses[ i ] ) )
3332 removeAllResults = removeAllResults and getResults and sizeResults
3333 utilities.assert_equals( expect=main.TRUE,
3334 actual=removeAllResults,
3335 onpass="Set removeAll correct",
3336 onfail="Set removeAll was incorrect" )
3337
3338 main.step( "Distributed Set addAll()" )
3339 onosSet.update( addAllValue.split() )
3340 addResponses = []
3341 threads = []
3342 for i in range( numControllers ):
3343 t = main.Thread( target=CLIs[i].setTestAdd,
3344 name="setTestAddAll-" + str( i ),
3345 args=[ onosSetName, addAllValue ] )
3346 threads.append( t )
3347 t.start()
3348 for t in threads:
3349 t.join()
3350 addResponses.append( t.result )
3351
3352 # main.TRUE = successfully changed the set
3353 # main.FALSE = action resulted in no change in set
3354 # main.ERROR - Some error in executing the function
3355 addAllResults = main.TRUE
3356 for i in range( numControllers ):
3357 if addResponses[ i ] == main.TRUE:
3358 # All is well
3359 pass
3360 elif addResponses[ i ] == main.FALSE:
3361 # Already in set, probably fine
3362 pass
3363 elif addResponses[ i ] == main.ERROR:
3364 # Error in execution
3365 addAllResults = main.FALSE
3366 else:
3367 # unexpected result
3368 addAllResults = main.FALSE
3369 if addAllResults != main.TRUE:
3370 main.log.error( "Error executing set addAll" )
3371
3372 # Check if set is still correct
3373 size = len( onosSet )
3374 getResponses = []
3375 threads = []
3376 for i in range( numControllers ):
3377 t = main.Thread( target=CLIs[i].setTestGet,
3378 name="setTestGet-" + str( i ),
3379 args=[ onosSetName ] )
3380 threads.append( t )
3381 t.start()
3382 for t in threads:
3383 t.join()
3384 getResponses.append( t.result )
3385 getResults = main.TRUE
3386 for i in range( numControllers ):
3387 if isinstance( getResponses[ i ], list):
3388 current = set( getResponses[ i ] )
3389 if len( current ) == len( getResponses[ i ] ):
3390 # no repeats
3391 if onosSet != current:
3392 main.log.error( "ONOS" + str( i + 1 ) +
3393 " has incorrect view" +
3394 " of set " + onosSetName + ":\n" +
3395 str( getResponses[ i ] ) )
3396 main.log.debug( "Expected: " + str( onosSet ) )
3397 main.log.debug( "Actual: " + str( current ) )
3398 getResults = main.FALSE
3399 else:
3400 # error, set is not a set
3401 main.log.error( "ONOS" + str( i + 1 ) +
3402 " has repeat elements in" +
3403 " set " + onosSetName + ":\n" +
3404 str( getResponses[ i ] ) )
3405 getResults = main.FALSE
3406 elif getResponses[ i ] == main.ERROR:
3407 getResults = main.FALSE
3408 sizeResponses = []
3409 threads = []
3410 for i in range( numControllers ):
3411 t = main.Thread( target=CLIs[i].setTestSize,
3412 name="setTestSize-" + str( i ),
3413 args=[ onosSetName ] )
3414 threads.append( t )
3415 t.start()
3416 for t in threads:
3417 t.join()
3418 sizeResponses.append( t.result )
3419 sizeResults = main.TRUE
3420 for i in range( numControllers ):
3421 if size != sizeResponses[ i ]:
3422 sizeResults = main.FALSE
3423 main.log.error( "ONOS" + str( i + 1 ) +
3424 " expected a size of " + str( size ) +
3425 " for set " + onosSetName +
3426 " but got " + str( sizeResponses[ i ] ) )
3427 addAllResults = addAllResults and getResults and sizeResults
3428 utilities.assert_equals( expect=main.TRUE,
3429 actual=addAllResults,
3430 onpass="Set addAll correct",
3431 onfail="Set addAll was incorrect" )
3432
3433 main.step( "Distributed Set clear()" )
3434 onosSet.clear()
3435 clearResponses = []
3436 threads = []
3437 for i in range( numControllers ):
3438 t = main.Thread( target=CLIs[i].setTestRemove,
3439 name="setTestClear-" + str( i ),
3440 args=[ onosSetName, " "], # Values doesn't matter
3441 kwargs={ "clear": True } )
3442 threads.append( t )
3443 t.start()
3444 for t in threads:
3445 t.join()
3446 clearResponses.append( t.result )
3447
3448 # main.TRUE = successfully changed the set
3449 # main.FALSE = action resulted in no change in set
3450 # main.ERROR - Some error in executing the function
3451 clearResults = main.TRUE
3452 for i in range( numControllers ):
3453 if clearResponses[ i ] == main.TRUE:
3454 # All is well
3455 pass
3456 elif clearResponses[ i ] == main.FALSE:
3457 # Nothing set, probably fine
3458 pass
3459 elif clearResponses[ i ] == main.ERROR:
3460 # Error in execution
3461 clearResults = main.FALSE
3462 else:
3463 # unexpected result
3464 clearResults = main.FALSE
3465 if clearResults != main.TRUE:
3466 main.log.error( "Error executing set clear" )
3467
3468 # Check if set is still correct
3469 size = len( onosSet )
3470 getResponses = []
3471 threads = []
3472 for i in range( numControllers ):
3473 t = main.Thread( target=CLIs[i].setTestGet,
3474 name="setTestGet-" + str( i ),
3475 args=[ onosSetName ] )
3476 threads.append( t )
3477 t.start()
3478 for t in threads:
3479 t.join()
3480 getResponses.append( t.result )
3481 getResults = main.TRUE
3482 for i in range( numControllers ):
3483 if isinstance( getResponses[ i ], list):
3484 current = set( getResponses[ i ] )
3485 if len( current ) == len( getResponses[ i ] ):
3486 # no repeats
3487 if onosSet != current:
3488 main.log.error( "ONOS" + str( i + 1 ) +
3489 " has incorrect view" +
3490 " of set " + onosSetName + ":\n" +
3491 str( getResponses[ i ] ) )
3492 main.log.debug( "Expected: " + str( onosSet ) )
3493 main.log.debug( "Actual: " + str( current ) )
3494 getResults = main.FALSE
3495 else:
3496 # error, set is not a set
3497 main.log.error( "ONOS" + str( i + 1 ) +
3498 " has repeat elements in" +
3499 " set " + onosSetName + ":\n" +
3500 str( getResponses[ i ] ) )
3501 getResults = main.FALSE
3502 elif getResponses[ i ] == main.ERROR:
3503 getResults = main.FALSE
3504 sizeResponses = []
3505 threads = []
3506 for i in range( numControllers ):
3507 t = main.Thread( target=CLIs[i].setTestSize,
3508 name="setTestSize-" + str( i ),
3509 args=[ onosSetName ] )
3510 threads.append( t )
3511 t.start()
3512 for t in threads:
3513 t.join()
3514 sizeResponses.append( t.result )
3515 sizeResults = main.TRUE
3516 for i in range( numControllers ):
3517 if size != sizeResponses[ i ]:
3518 sizeResults = main.FALSE
3519 main.log.error( "ONOS" + str( i + 1 ) +
3520 " expected a size of " + str( size ) +
3521 " for set " + onosSetName +
3522 " but got " + str( sizeResponses[ i ] ) )
3523 clearResults = clearResults and getResults and sizeResults
3524 utilities.assert_equals( expect=main.TRUE,
3525 actual=clearResults,
3526 onpass="Set clear correct",
3527 onfail="Set clear was incorrect" )
3528
3529 main.step( "Distributed Set addAll()" )
3530 onosSet.update( addAllValue.split() )
3531 addResponses = []
3532 threads = []
3533 for i in range( numControllers ):
3534 t = main.Thread( target=CLIs[i].setTestAdd,
3535 name="setTestAddAll-" + str( i ),
3536 args=[ onosSetName, addAllValue ] )
3537 threads.append( t )
3538 t.start()
3539 for t in threads:
3540 t.join()
3541 addResponses.append( t.result )
3542
3543 # main.TRUE = successfully changed the set
3544 # main.FALSE = action resulted in no change in set
3545 # main.ERROR - Some error in executing the function
3546 addAllResults = main.TRUE
3547 for i in range( numControllers ):
3548 if addResponses[ i ] == main.TRUE:
3549 # All is well
3550 pass
3551 elif addResponses[ i ] == main.FALSE:
3552 # Already in set, probably fine
3553 pass
3554 elif addResponses[ i ] == main.ERROR:
3555 # Error in execution
3556 addAllResults = main.FALSE
3557 else:
3558 # unexpected result
3559 addAllResults = main.FALSE
3560 if addAllResults != main.TRUE:
3561 main.log.error( "Error executing set addAll" )
3562
3563 # Check if set is still correct
3564 size = len( onosSet )
3565 getResponses = []
3566 threads = []
3567 for i in range( numControllers ):
3568 t = main.Thread( target=CLIs[i].setTestGet,
3569 name="setTestGet-" + str( i ),
3570 args=[ onosSetName ] )
3571 threads.append( t )
3572 t.start()
3573 for t in threads:
3574 t.join()
3575 getResponses.append( t.result )
3576 getResults = main.TRUE
3577 for i in range( numControllers ):
3578 if isinstance( getResponses[ i ], list):
3579 current = set( getResponses[ i ] )
3580 if len( current ) == len( getResponses[ i ] ):
3581 # no repeats
3582 if onosSet != current:
3583 main.log.error( "ONOS" + str( i + 1 ) +
3584 " has incorrect view" +
3585 " of set " + onosSetName + ":\n" +
3586 str( getResponses[ i ] ) )
3587 main.log.debug( "Expected: " + str( onosSet ) )
3588 main.log.debug( "Actual: " + str( current ) )
3589 getResults = main.FALSE
3590 else:
3591 # error, set is not a set
3592 main.log.error( "ONOS" + str( i + 1 ) +
3593 " has repeat elements in" +
3594 " set " + onosSetName + ":\n" +
3595 str( getResponses[ i ] ) )
3596 getResults = main.FALSE
3597 elif getResponses[ i ] == main.ERROR:
3598 getResults = main.FALSE
3599 sizeResponses = []
3600 threads = []
3601 for i in range( numControllers ):
3602 t = main.Thread( target=CLIs[i].setTestSize,
3603 name="setTestSize-" + str( i ),
3604 args=[ onosSetName ] )
3605 threads.append( t )
3606 t.start()
3607 for t in threads:
3608 t.join()
3609 sizeResponses.append( t.result )
3610 sizeResults = main.TRUE
3611 for i in range( numControllers ):
3612 if size != sizeResponses[ i ]:
3613 sizeResults = main.FALSE
3614 main.log.error( "ONOS" + str( i + 1 ) +
3615 " expected a size of " + str( size ) +
3616 " for set " + onosSetName +
3617 " but got " + str( sizeResponses[ i ] ) )
3618 addAllResults = addAllResults and getResults and sizeResults
3619 utilities.assert_equals( expect=main.TRUE,
3620 actual=addAllResults,
3621 onpass="Set addAll correct",
3622 onfail="Set addAll was incorrect" )
3623
3624 main.step( "Distributed Set retain()" )
3625 onosSet.intersection_update( retainValue.split() )
3626 retainResponses = []
3627 threads = []
3628 for i in range( numControllers ):
3629 t = main.Thread( target=CLIs[i].setTestRemove,
3630 name="setTestRetain-" + str( i ),
3631 args=[ onosSetName, retainValue ],
3632 kwargs={ "retain": True } )
3633 threads.append( t )
3634 t.start()
3635 for t in threads:
3636 t.join()
3637 retainResponses.append( t.result )
3638
3639 # main.TRUE = successfully changed the set
3640 # main.FALSE = action resulted in no change in set
3641 # main.ERROR - Some error in executing the function
3642 retainResults = main.TRUE
3643 for i in range( numControllers ):
3644 if retainResponses[ i ] == main.TRUE:
3645 # All is well
3646 pass
3647 elif retainResponses[ i ] == main.FALSE:
3648 # Already in set, probably fine
3649 pass
3650 elif retainResponses[ i ] == main.ERROR:
3651 # Error in execution
3652 retainResults = main.FALSE
3653 else:
3654 # unexpected result
3655 retainResults = main.FALSE
3656 if retainResults != main.TRUE:
3657 main.log.error( "Error executing set retain" )
3658
3659 # Check if set is still correct
3660 size = len( onosSet )
3661 getResponses = []
3662 threads = []
3663 for i in range( numControllers ):
3664 t = main.Thread( target=CLIs[i].setTestGet,
3665 name="setTestGet-" + str( i ),
3666 args=[ onosSetName ] )
3667 threads.append( t )
3668 t.start()
3669 for t in threads:
3670 t.join()
3671 getResponses.append( t.result )
3672 getResults = main.TRUE
3673 for i in range( numControllers ):
3674 if isinstance( getResponses[ i ], list):
3675 current = set( getResponses[ i ] )
3676 if len( current ) == len( getResponses[ i ] ):
3677 # no repeats
3678 if onosSet != current:
3679 main.log.error( "ONOS" + str( i + 1 ) +
3680 " has incorrect view" +
3681 " of set " + onosSetName + ":\n" +
3682 str( getResponses[ i ] ) )
3683 main.log.debug( "Expected: " + str( onosSet ) )
3684 main.log.debug( "Actual: " + str( current ) )
3685 getResults = main.FALSE
3686 else:
3687 # error, set is not a set
3688 main.log.error( "ONOS" + str( i + 1 ) +
3689 " has repeat elements in" +
3690 " set " + onosSetName + ":\n" +
3691 str( getResponses[ i ] ) )
3692 getResults = main.FALSE
3693 elif getResponses[ i ] == main.ERROR:
3694 getResults = main.FALSE
3695 sizeResponses = []
3696 threads = []
3697 for i in range( numControllers ):
3698 t = main.Thread( target=CLIs[i].setTestSize,
3699 name="setTestSize-" + str( i ),
3700 args=[ onosSetName ] )
3701 threads.append( t )
3702 t.start()
3703 for t in threads:
3704 t.join()
3705 sizeResponses.append( t.result )
3706 sizeResults = main.TRUE
3707 for i in range( numControllers ):
3708 if size != sizeResponses[ i ]:
3709 sizeResults = main.FALSE
3710 main.log.error( "ONOS" + str( i + 1 ) +
3711 " expected a size of " +
3712 str( size ) + " for set " + onosSetName +
3713 " but got " + str( sizeResponses[ i ] ) )
3714 retainResults = retainResults and getResults and sizeResults
3715 utilities.assert_equals( expect=main.TRUE,
3716 actual=retainResults,
3717 onpass="Set retain correct",
3718 onfail="Set retain was incorrect" )
3719