blob: 60c438e44fd5194dc32f148e1b7495ebc2136ec6 [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 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070050 main.log.info( "ONOS HA Sanity test - initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080051 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
Jon Hall40d2cbd2015-06-03 16:24:29 -070098 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080099 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall65844a32015-03-09 19:09:37 -0700100
Jon Hall40d2cbd2015-06-03 16:24:29 -0700101 main.log.info( "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
Jon Hall40d2cbd2015-06-03 16:24:29 -0700106 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700107 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 Hall8f89dda2015-01-22 16:03:33 -0800129 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700130
131 main.step( "Using mvn clean install" )
132 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700133 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700134 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700135 else:
136 main.log.warn( "Did not pull new code so skipping mvn " +
137 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700138 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:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700182 main.log.error( node.name + " didn't start!" )
Jon Hall65844a32015-03-09 19:09:37 -0700183 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 Hall40d2cbd2015-06-03 16:24:29 -0700209 if main.params[ 'tcpdump' ].lower() == "true":
210 main.step( "Start Packet Capture MN" )
211 main.Mininet2.startTcpdump(
212 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
213 + "-MN.pcap",
214 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
215 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hallb1290e82014-11-18 16:17:48 -0500216
Jon Hall390696c2015-05-05 17:13:41 -0700217 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700218 appCheck = main.TRUE
219 threads = []
220 for i in range( numControllers ):
221 t = main.Thread( target=CLIs[i].appToIDCheck,
222 name="appToIDCheck-" + str( i ),
223 args=[] )
224 threads.append( t )
225 t.start()
226
227 for t in threads:
228 t.join()
229 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700230 if appCheck != main.TRUE:
231 main.log.warn( CLIs[0].apps() )
232 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700233 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
234 onpass="App Ids seem to be correct",
235 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700236
Jon Hallfeff3082015-05-19 10:23:26 -0700237 if cliResults == main.FALSE:
238 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hallffb386d2014-11-21 13:43:38 -0800239 main.cleanup()
240 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -0500241
Jon Hall6aec96b2015-01-19 14:49:31 -0800242 def CASE2( self, main ):
243 """
Jon Hallb1290e82014-11-18 16:17:48 -0500244 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800245 """
Jon Hallb1290e82014-11-18 16:17:48 -0500246 import re
Jon Hall390696c2015-05-05 17:13:41 -0700247 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700248 assert numControllers, "numControllers not defined"
249 assert main, "main not defined"
250 assert utilities.assert_equals, "utilities.assert_equals not defined"
251 assert CLIs, "CLIs not defined"
252 assert nodes, "nodes not defined"
253 assert ONOS1Port, "ONOS1Port not defined"
254 assert ONOS2Port, "ONOS2Port not defined"
255 assert ONOS3Port, "ONOS3Port not defined"
256 assert ONOS4Port, "ONOS4Port not defined"
257 assert ONOS5Port, "ONOS5Port not defined"
258 assert ONOS6Port, "ONOS6Port not defined"
259 assert ONOS7Port, "ONOS7Port not defined"
Jon Hallb1290e82014-11-18 16:17:48 -0500260
Jon Hall6aec96b2015-01-19 14:49:31 -0800261 main.case( "Assigning Controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700262 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
263 "and check that an ONOS node becomes the " +\
264 "master of the device. Then manually assign" +\
265 " mastership to specific ONOS nodes using" +\
266 " 'device-role'"
Jon Hall6aec96b2015-01-19 14:49:31 -0800267 main.step( "Assign switches to controllers" )
Jon Hallb1290e82014-11-18 16:17:48 -0500268
Jon Hall65844a32015-03-09 19:09:37 -0700269 # TODO: rewrite this function to take lists of ips and ports?
270 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800271 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800272 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800273 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800274 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -0700275 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
276 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
277 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
278 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
279 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
280 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
281 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hallb1290e82014-11-18 16:17:48 -0500282
Jon Hall8f89dda2015-01-22 16:03:33 -0800283 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800284 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800285 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800286 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800287 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800288 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800289 main.log.info( repr( response ) )
Jon Hall65844a32015-03-09 19:09:37 -0700290 for node in nodes:
291 if re.search( "tcp:" + node.ip_address, response ):
292 mastershipCheck = mastershipCheck and main.TRUE
293 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700294 main.log.error( "Error, node " + node.ip_address + " is " +
295 "not in the list of controllers s" +
296 str( i ) + " is connecting to." )
Jon Hall65844a32015-03-09 19:09:37 -0700297 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800298 utilities.assert_equals(
299 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800300 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800301 onpass="Switch mastership assigned correctly",
302 onfail="Switches not assigned correctly to controllers" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700303 # FIXME: Check topo here
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 Hall40d2cbd2015-06-03 16:24:29 -0700637 for i in range(80):
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 ):
Jon Hall40d2cbd2015-06-03 16:24:29 -0700647 main.log.debug( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700648 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700649 break
650 else:
651 intents = json.loads( cli.intents() )
652 for intent in intents:
653 if intent[ 'state' ] != "INSTALLED":
654 main.log.warn( "Intent " + intent[ 'id' ] +
655 " is " + intent[ 'state' ] )
656 correct = False
657 break
Jon Hall390696c2015-05-05 17:13:41 -0700658 if correct:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700659 break
Jon Hall5cfd23c2015-03-19 11:40:57 -0700660 if not intentStop:
661 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700662 global gossipTime
Jon Hall5cfd23c2015-03-19 11:40:57 -0700663 gossipTime = intentStop - intentStart
664 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700665 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700666 # FIXME: make this time configurable/calculate based off of number of
667 # nodes and gossip rounds
Jon Hall5cfd23c2015-03-19 11:40:57 -0700668 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700669 expect=40, actual=gossipTime,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700670 onpass="ECM anti-entropy for intents worked within " +
671 "expected time",
672 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700673 if gossipTime <= 40:
Jon Halla9d26da2015-03-30 16:45:32 -0700674 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800675
Jon Hall63604932015-02-26 17:09:50 -0800676 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800677 import time
Jon Hall63604932015-02-26 17:09:50 -0800678 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800679 main.log.info( "Sleeping 60 seconds to see if intents are found" )
680 time.sleep( 60 )
681 onosIds = main.ONOScli1.getAllIntentsId()
682 main.log.info( "Submitted intents: " + str( intentIds ) )
683 main.log.info( "Intents in ONOS: " + str( onosIds ) )
684 # Print the intent states
685 intents = main.ONOScli1.intents()
686 intentStates = []
687 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
688 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700689 try:
690 for intent in json.loads( intents ):
691 # Iter through intents of a node
692 state = intent.get( 'state', None )
693 if "INSTALLED" not in state:
694 installedCheck = False
695 intentId = intent.get( 'id', None )
696 intentStates.append( ( intentId, state ) )
697 except ( ValueError, TypeError ):
698 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800699 # add submitted intents not in the store
700 tmplist = [ i for i, s in intentStates ]
701 for i in intentIds:
702 if i not in tmplist:
703 intentStates.append( ( i, " - " ) )
704 intentStates.sort()
705 for i, s in intentStates:
706 count += 1
707 main.log.info( "%-6s%-15s%-15s" %
708 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700709 leaders = main.ONOScli1.leaders()
710 try:
711 if leaders:
712 parsedLeaders = json.loads( leaders )
713 main.log.warn( json.dumps( parsedLeaders,
714 sort_keys=True,
715 indent=4,
716 separators=( ',', ': ' ) ) )
717 # check for all intent partitions
718 # check for election
719 topics = []
720 for i in range( 14 ):
721 topics.append( "intent-partition-" + str( i ) )
722 # FIXME: this should only be after we start the app
723 topics.append( "org.onosproject.election" )
724 main.log.debug( topics )
725 ONOStopics = [ j['topic'] for j in parsedLeaders ]
726 for topic in topics:
727 if topic not in ONOStopics:
728 main.log.error( "Error: " + topic +
729 " not in leaders" )
730 else:
731 main.log.error( "leaders() returned None" )
732 except ( ValueError, TypeError ):
733 main.log.exception( "Error parsing leaders" )
734 main.log.error( repr( leaders ) )
735 partitions = main.ONOScli1.partitions()
736 try:
737 if partitions :
738 parsedPartitions = json.loads( partitions )
739 main.log.warn( json.dumps( parsedPartitions,
740 sort_keys=True,
741 indent=4,
742 separators=( ',', ': ' ) ) )
743 # TODO check for a leader in all paritions
744 # TODO check for consistency among nodes
745 else:
746 main.log.error( "partitions() returned None" )
747 except ( ValueError, TypeError ):
748 main.log.exception( "Error parsing partitions" )
749 main.log.error( repr( partitions ) )
750 pendingMap = main.ONOScli1.pendingMap()
751 try:
752 if pendingMap :
753 parsedPending = json.loads( pendingMap )
754 main.log.warn( json.dumps( parsedPending,
755 sort_keys=True,
756 indent=4,
757 separators=( ',', ': ' ) ) )
758 # TODO check something here?
759 else:
760 main.log.error( "pendingMap() returned None" )
761 except ( ValueError, TypeError ):
762 main.log.exception( "Error parsing pending map" )
763 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500764
Jon Hall6aec96b2015-01-19 14:49:31 -0800765 def CASE4( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500766 """
767 Ping across added host intents
768 """
Jon Hall58c76b72015-02-23 11:09:24 -0800769 import json
Jon Hall65844a32015-03-09 19:09:37 -0700770 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700771 assert numControllers, "numControllers not defined"
772 assert main, "main not defined"
773 assert utilities.assert_equals, "utilities.assert_equals not defined"
774 assert CLIs, "CLIs not defined"
775 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700776 main.case( "Verify connectivity by sendind traffic across Intents" )
777 main.caseExplaination = "Ping across added host intents to check " +\
778 "functionality and check the state of " +\
779 "the intent"
780 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800781 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800782 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800783 ping = main.Mininet1.pingHost( src="h" + str( i ),
784 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800785 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800786 if ping == main.FALSE:
787 main.log.warn( "Ping failed between h" + str( i ) +
788 " and h" + str( i + 10 ) )
789 elif ping == main.TRUE:
790 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800791 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800792 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700793 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800794 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800795 # TODO: pretty print
Jon Hall65844a32015-03-09 19:09:37 -0700796 main.log.warn( "ONOS1 intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700797 try:
798 tmpIntents = main.ONOScli1.intents()
799 main.log.warn( json.dumps( json.loads( tmpIntents ),
800 sort_keys=True,
801 indent=4,
802 separators=( ',', ': ' ) ) )
803 except ( ValueError, TypeError ):
804 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800805 utilities.assert_equals(
806 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800807 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800808 onpass="Intents have been installed correctly and pings work",
809 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallb1290e82014-11-18 16:17:48 -0500810
Jon Hallfeff3082015-05-19 10:23:26 -0700811 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700812 installedCheck = False
Jon Hallfeff3082015-05-19 10:23:26 -0700813 count = 0
Jon Hall40d2cbd2015-06-03 16:24:29 -0700814 while not installedCheck and count < 40:
815 installedCheck = True
816 # Print the intent states
817 intents = main.ONOScli1.intents()
818 intentStates = []
819 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
820 count = 0
821 # Iter through intents of a node
822 try:
823 for intent in json.loads( intents ):
824 state = intent.get( 'state', None )
825 if "INSTALLED" not in state:
826 installedCheck = False
827 intentId = intent.get( 'id', None )
828 intentStates.append( ( intentId, state ) )
829 except ( ValueError, TypeError ):
830 main.log.exception( "Error parsing intents." )
831 # Print states
832 intentStates.sort()
833 for i, s in intentStates:
834 count += 1
835 main.log.info( "%-6s%-15s%-15s" %
836 ( str( count ), str( i ), str( s ) ) )
837 if not installedCheck:
838 time.sleep( 1 )
839 count += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700840 utilities.assert_equals( expect=True, actual=installedCheck,
841 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700842 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700843 "INSTALLED state" )
844
845 main.step( "Check leadership of topics" )
846 leaders = main.ONOScli1.leaders()
847 topicCheck = main.TRUE
848 try:
849 if leaders:
850 parsedLeaders = json.loads( leaders )
851 main.log.warn( json.dumps( parsedLeaders,
852 sort_keys=True,
853 indent=4,
854 separators=( ',', ': ' ) ) )
855 # check for all intent partitions
856 # check for election
857 # TODO: Look at Devices as topics now that it uses this system
858 topics = []
859 for i in range( 14 ):
860 topics.append( "intent-partition-" + str( i ) )
861 # FIXME: this should only be after we start the app
862 # FIXME: topics.append( "org.onosproject.election" )
863 # Print leaders output
864 main.log.debug( topics )
865 ONOStopics = [ j['topic'] for j in parsedLeaders ]
866 for topic in topics:
867 if topic not in ONOStopics:
868 main.log.error( "Error: " + topic +
869 " not in leaders" )
870 topicCheck = main.FALSE
871 else:
872 main.log.error( "leaders() returned None" )
873 topicCheck = main.FALSE
874 except ( ValueError, TypeError ):
875 topicCheck = main.FALSE
876 main.log.exception( "Error parsing leaders" )
877 main.log.error( repr( leaders ) )
878 # TODO: Check for a leader of these topics
879 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
880 onpass="intent Partitions is in leaders",
881 onfail="Some topics were lost " )
882 # Print partitions
883 partitions = main.ONOScli1.partitions()
884 try:
885 if partitions :
886 parsedPartitions = json.loads( partitions )
887 main.log.warn( json.dumps( parsedPartitions,
888 sort_keys=True,
889 indent=4,
890 separators=( ',', ': ' ) ) )
891 # TODO check for a leader in all paritions
892 # TODO check for consistency among nodes
893 else:
894 main.log.error( "partitions() returned None" )
895 except ( ValueError, TypeError ):
896 main.log.exception( "Error parsing partitions" )
897 main.log.error( repr( partitions ) )
898 # Print Pending Map
899 pendingMap = main.ONOScli1.pendingMap()
900 try:
901 if pendingMap :
902 parsedPending = json.loads( pendingMap )
903 main.log.warn( json.dumps( parsedPending,
904 sort_keys=True,
905 indent=4,
906 separators=( ',', ': ' ) ) )
907 # TODO check something here?
908 else:
909 main.log.error( "pendingMap() returned None" )
910 except ( ValueError, TypeError ):
911 main.log.exception( "Error parsing pending map" )
912 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700913
Jon Hall63604932015-02-26 17:09:50 -0800914 if not installedCheck:
Jon Hall65844a32015-03-09 19:09:37 -0700915 main.log.info( "Waiting 60 seconds to see if the state of " +
916 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800917 time.sleep( 60 )
918 # Print the intent states
919 intents = main.ONOScli1.intents()
920 intentStates = []
921 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
922 count = 0
923 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700924 try:
925 for intent in json.loads( intents ):
926 state = intent.get( 'state', None )
927 if "INSTALLED" not in state:
928 installedCheck = False
929 intentId = intent.get( 'id', None )
930 intentStates.append( ( intentId, state ) )
931 except ( ValueError, TypeError ):
932 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800933 intentStates.sort()
934 for i, s in intentStates:
935 count += 1
936 main.log.info( "%-6s%-15s%-15s" %
937 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700938 leaders = main.ONOScli1.leaders()
939 try:
940 if leaders:
941 parsedLeaders = json.loads( leaders )
942 main.log.warn( json.dumps( parsedLeaders,
943 sort_keys=True,
944 indent=4,
945 separators=( ',', ': ' ) ) )
946 # check for all intent partitions
947 # check for election
948 topics = []
949 for i in range( 14 ):
950 topics.append( "intent-partition-" + str( i ) )
951 # FIXME: this should only be after we start the app
952 topics.append( "org.onosproject.election" )
953 main.log.debug( topics )
954 ONOStopics = [ j['topic'] for j in parsedLeaders ]
955 for topic in topics:
956 if topic not in ONOStopics:
957 main.log.error( "Error: " + topic +
958 " not in leaders" )
959 else:
960 main.log.error( "leaders() returned None" )
961 except ( ValueError, TypeError ):
962 main.log.exception( "Error parsing leaders" )
963 main.log.error( repr( leaders ) )
964 partitions = main.ONOScli1.partitions()
965 try:
966 if partitions :
967 parsedPartitions = json.loads( partitions )
968 main.log.warn( json.dumps( parsedPartitions,
969 sort_keys=True,
970 indent=4,
971 separators=( ',', ': ' ) ) )
972 # TODO check for a leader in all paritions
973 # TODO check for consistency among nodes
974 else:
975 main.log.error( "partitions() returned None" )
976 except ( ValueError, TypeError ):
977 main.log.exception( "Error parsing partitions" )
978 main.log.error( repr( partitions ) )
979 pendingMap = main.ONOScli1.pendingMap()
980 try:
981 if pendingMap :
982 parsedPending = json.loads( pendingMap )
983 main.log.warn( json.dumps( parsedPending,
984 sort_keys=True,
985 indent=4,
986 separators=( ',', ': ' ) ) )
987 # TODO check something here?
988 else:
989 main.log.error( "pendingMap() returned None" )
990 except ( ValueError, TypeError ):
991 main.log.exception( "Error parsing pending map" )
992 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700993 # Print flowrules
994 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -0700995 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700996 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -0700997 PingResult = main.TRUE
998 for i in range( 8, 18 ):
999 ping = main.Mininet1.pingHost( src="h" + str( i ),
1000 target="h" + str( i + 10 ) )
1001 PingResult = PingResult and ping
1002 if ping == main.FALSE:
1003 main.log.warn( "Ping failed between h" + str( i ) +
1004 " and h" + str( i + 10 ) )
1005 elif ping == main.TRUE:
1006 main.log.info( "Ping test passed!" )
1007 # Don't set PingResult or you'd override failures
1008 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001009 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001010 "Intents have not been installed correctly, pings failed." )
1011 # TODO: pretty print
1012 main.log.warn( "ONOS1 intents: " )
1013 try:
1014 tmpIntents = main.ONOScli1.intents()
1015 main.log.warn( json.dumps( json.loads( tmpIntents ),
1016 sort_keys=True,
1017 indent=4,
1018 separators=( ',', ': ' ) ) )
1019 except ( ValueError, TypeError ):
1020 main.log.warn( repr( tmpIntents ) )
1021 utilities.assert_equals(
1022 expect=main.TRUE,
1023 actual=PingResult,
1024 onpass="Intents have been installed correctly and pings work",
1025 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallfeff3082015-05-19 10:23:26 -07001026
Jon Hall6aec96b2015-01-19 14:49:31 -08001027 def CASE5( self, main ):
1028 """
Jon Hallb1290e82014-11-18 16:17:48 -05001029 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001030 """
Jon Hallb1290e82014-11-18 16:17:48 -05001031 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001032 import time
1033 assert numControllers, "numControllers not defined"
1034 assert main, "main not defined"
1035 assert utilities.assert_equals, "utilities.assert_equals not defined"
1036 assert CLIs, "CLIs not defined"
1037 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001038 # assumes that sts is already in you PYTHONPATH
1039 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001040
Jon Hall6aec96b2015-01-19 14:49:31 -08001041 main.case( "Setting up and gathering data for current state" )
1042 # The general idea for this test case is to pull the state of
1043 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -07001044 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -05001045
Jon Hall65844a32015-03-09 19:09:37 -07001046 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001047 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001048 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001049
Jon Hall6aec96b2015-01-19 14:49:31 -08001050 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001051 rolesNotNull = main.TRUE
1052 threads = []
1053 for i in range( numControllers ):
1054 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001055 name="rolesNotNull-" + str( i ),
1056 args=[] )
1057 threads.append( t )
1058 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001059
1060 for t in threads:
1061 t.join()
1062 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001063 utilities.assert_equals(
1064 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001065 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001066 onpass="Each device has a master",
1067 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001068
Jon Hall65844a32015-03-09 19:09:37 -07001069 main.step( "Get the Mastership of each switch from each controller" )
1070 ONOSMastership = []
1071 mastershipCheck = main.FALSE
1072 consistentMastership = True
1073 rolesResults = True
1074 threads = []
1075 for i in range( numControllers ):
1076 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001077 name="roles-" + str( i ),
1078 args=[] )
1079 threads.append( t )
1080 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001081
1082 for t in threads:
1083 t.join()
1084 ONOSMastership.append( t.result )
1085
1086 for i in range( numControllers ):
1087 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001088 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001089 " roles" )
1090 main.log.warn(
1091 "ONOS" + str( i + 1 ) + " mastership response: " +
1092 repr( ONOSMastership[i] ) )
1093 rolesResults = False
1094 utilities.assert_equals(
1095 expect=True,
1096 actual=rolesResults,
1097 onpass="No error in reading roles output",
1098 onfail="Error in reading roles from ONOS" )
1099
1100 main.step( "Check for consistency in roles from each controller" )
1101 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001102 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001103 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001104 else:
Jon Hall65844a32015-03-09 19:09:37 -07001105 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001106 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001107 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001108 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001109 onpass="Switch roles are consistent across all ONOS nodes",
1110 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001111
Jon Hall65844a32015-03-09 19:09:37 -07001112 if rolesResults and not consistentMastership:
1113 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001114 try:
1115 main.log.warn(
1116 "ONOS" + str( i + 1 ) + " roles: ",
1117 json.dumps(
1118 json.loads( ONOSMastership[ i ] ),
1119 sort_keys=True,
1120 indent=4,
1121 separators=( ',', ': ' ) ) )
1122 except ( ValueError, TypeError ):
1123 main.log.warn( repr( ONOSMastership[ i ] ) )
1124 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001125 mastershipCheck = main.TRUE
1126 mastershipState = ONOSMastership[ 0 ]
1127
Jon Hall6aec96b2015-01-19 14:49:31 -08001128 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001129 global intentState
1130 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001131 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001132 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001133 consistentIntents = True
1134 intentsResults = True
1135 threads = []
1136 for i in range( numControllers ):
1137 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001138 name="intents-" + str( i ),
1139 args=[],
1140 kwargs={ 'jsonFormat': True } )
1141 threads.append( t )
1142 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001143
1144 for t in threads:
1145 t.join()
1146 ONOSIntents.append( t.result )
1147
1148 for i in range( numControllers ):
1149 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001150 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001151 " intents" )
1152 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1153 repr( ONOSIntents[ i ] ) )
1154 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001155 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001156 expect=True,
1157 actual=intentsResults,
1158 onpass="No error in reading intents output",
1159 onfail="Error in reading intents from ONOS" )
1160
1161 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001162 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001163 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001164 "nodes" )
1165 else:
1166 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001167 main.log.error( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001168 utilities.assert_equals(
1169 expect=True,
1170 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001171 onpass="Intents are consistent across all ONOS nodes",
1172 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001173
Jon Hall390696c2015-05-05 17:13:41 -07001174 if intentsResults:
1175 # Try to make it easy to figure out what is happening
1176 #
1177 # Intent ONOS1 ONOS2 ...
1178 # 0x01 INSTALLED INSTALLING
1179 # ... ... ...
1180 # ... ... ...
1181 title = " Id"
1182 for n in range( numControllers ):
1183 title += " " * 10 + "ONOS" + str( n + 1 )
1184 main.log.warn( title )
Jon Hall390696c2015-05-05 17:13:41 -07001185 keys = []
Jon Hall40d2cbd2015-06-03 16:24:29 -07001186 try:
1187 # Get the set of all intent keys
Jon Hall390696c2015-05-05 17:13:41 -07001188 for nodeStr in ONOSIntents:
1189 node = json.loads( nodeStr )
1190 for intent in node:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001191 keys.append( intent.get( 'id' ) )
1192 keys = set( keys )
1193 # For each intent key, print the state on each node
1194 for key in keys:
1195 row = "%-13s" % key
1196 for nodeStr in ONOSIntents:
1197 node = json.loads( nodeStr )
1198 for intent in node:
1199 if intent.get( 'id', "Error" ) == key:
1200 row += "%-15s" % intent.get( 'state' )
1201 main.log.warn( row )
1202 # End of intent state table
1203 except ValueError as e:
1204 main.log.exception( e )
1205 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall390696c2015-05-05 17:13:41 -07001206
Jon Hall65844a32015-03-09 19:09:37 -07001207 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001208 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001209 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001210 main.log.debug( "ONOS" + str( n ) + " intents: " )
1211 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1212 sort_keys=True,
1213 indent=4,
1214 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001215 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001216 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001217 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1218 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1219 sort_keys=True,
1220 indent=4,
1221 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001222 else:
Jon Hall390696c2015-05-05 17:13:41 -07001223 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1224 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001225 elif intentsResults and consistentIntents:
1226 intentCheck = main.TRUE
1227 intentState = ONOSIntents[ 0 ]
1228
Jon Hall6aec96b2015-01-19 14:49:31 -08001229 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001230 global flowState
1231 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001232 ONOSFlows = []
1233 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001234 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001235 consistentFlows = True
1236 flowsResults = True
1237 threads = []
1238 for i in range( numControllers ):
1239 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001240 name="flows-" + str( i ),
1241 args=[],
1242 kwargs={ 'jsonFormat': True } )
1243 threads.append( t )
1244 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001245
Jon Halla9d26da2015-03-30 16:45:32 -07001246 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001247 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001248 for t in threads:
1249 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001250 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001251 ONOSFlows.append( result )
1252
1253 for i in range( numControllers ):
1254 num = str( i + 1 )
1255 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001256 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall65844a32015-03-09 19:09:37 -07001257 main.log.warn( "ONOS" + num + " flows response: " +
1258 repr( ONOSFlows[ i ] ) )
1259 flowsResults = False
1260 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001261 else:
Jon Hall65844a32015-03-09 19:09:37 -07001262 try:
1263 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1264 except ( ValueError, TypeError ):
1265 # FIXME: change this to log.error?
1266 main.log.exception( "Error in parsing ONOS" + num +
1267 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001268 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001269 ONOSFlowsJson.append( None )
1270 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001271 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001272 expect=True,
1273 actual=flowsResults,
1274 onpass="No error in reading flows output",
1275 onfail="Error in reading flows from ONOS" )
1276
1277 main.step( "Check for consistency in Flows from each controller" )
1278 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1279 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001280 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001281 else:
1282 consistentFlows = False
1283 utilities.assert_equals(
1284 expect=True,
1285 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001286 onpass="The flow count is consistent across all ONOS nodes",
1287 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001288
Jon Hall65844a32015-03-09 19:09:37 -07001289 if flowsResults and not consistentFlows:
1290 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001291 try:
1292 main.log.warn(
1293 "ONOS" + str( i + 1 ) + " flows: " +
1294 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1295 indent=4, separators=( ',', ': ' ) ) )
1296 except ( ValueError, TypeError ):
1297 main.log.warn(
1298 "ONOS" + str( i + 1 ) + " flows: " +
1299 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001300 elif flowsResults and consistentFlows:
1301 flowCheck = main.TRUE
1302 flowState = ONOSFlows[ 0 ]
1303
Jon Hall6aec96b2015-01-19 14:49:31 -08001304 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001305 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001306 flows = []
1307 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001308 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001309 if flowCheck == main.FALSE:
1310 for table in flows:
1311 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001312 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001313
Jon Hall6aec96b2015-01-19 14:49:31 -08001314 main.step( "Start continuous pings" )
1315 main.Mininet2.pingLong(
1316 src=main.params[ 'PING' ][ 'source1' ],
1317 target=main.params[ 'PING' ][ 'target1' ],
1318 pingTime=500 )
1319 main.Mininet2.pingLong(
1320 src=main.params[ 'PING' ][ 'source2' ],
1321 target=main.params[ 'PING' ][ 'target2' ],
1322 pingTime=500 )
1323 main.Mininet2.pingLong(
1324 src=main.params[ 'PING' ][ 'source3' ],
1325 target=main.params[ 'PING' ][ 'target3' ],
1326 pingTime=500 )
1327 main.Mininet2.pingLong(
1328 src=main.params[ 'PING' ][ 'source4' ],
1329 target=main.params[ 'PING' ][ 'target4' ],
1330 pingTime=500 )
1331 main.Mininet2.pingLong(
1332 src=main.params[ 'PING' ][ 'source5' ],
1333 target=main.params[ 'PING' ][ 'target5' ],
1334 pingTime=500 )
1335 main.Mininet2.pingLong(
1336 src=main.params[ 'PING' ][ 'source6' ],
1337 target=main.params[ 'PING' ][ 'target6' ],
1338 pingTime=500 )
1339 main.Mininet2.pingLong(
1340 src=main.params[ 'PING' ][ 'source7' ],
1341 target=main.params[ 'PING' ][ 'target7' ],
1342 pingTime=500 )
1343 main.Mininet2.pingLong(
1344 src=main.params[ 'PING' ][ 'source8' ],
1345 target=main.params[ 'PING' ][ 'target8' ],
1346 pingTime=500 )
1347 main.Mininet2.pingLong(
1348 src=main.params[ 'PING' ][ 'source9' ],
1349 target=main.params[ 'PING' ][ 'target9' ],
1350 pingTime=500 )
1351 main.Mininet2.pingLong(
1352 src=main.params[ 'PING' ][ 'source10' ],
1353 target=main.params[ 'PING' ][ 'target10' ],
1354 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001355
Jon Hall6aec96b2015-01-19 14:49:31 -08001356 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001357 ctrls = []
Jon Hall65844a32015-03-09 19:09:37 -07001358 for node in nodes:
1359 temp = ( node, node.name, node.ip_address, 6633 )
Jon Hall65844a32015-03-09 19:09:37 -07001360 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001361 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001362
Jon Hall6aec96b2015-01-19 14:49:31 -08001363 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001364 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001365 threads = []
1366 for i in range( numControllers ):
1367 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001368 name="devices-" + str( i ),
1369 args=[ ] )
1370 threads.append( t )
1371 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001372
1373 for t in threads:
1374 t.join()
1375 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001376 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001377 threads = []
1378 for i in range( numControllers ):
1379 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001380 name="hosts-" + str( i ),
1381 args=[ ] )
1382 threads.append( t )
1383 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001384
1385 for t in threads:
1386 t.join()
1387 try:
1388 hosts.append( json.loads( t.result ) )
1389 except ( ValueError, TypeError ):
1390 # FIXME: better handling of this, print which node
1391 # Maybe use thread name?
1392 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001393 # FIXME: should this be an empty json object instead?
1394 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001395
Jon Hallb1290e82014-11-18 16:17:48 -05001396 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001397 threads = []
1398 for i in range( numControllers ):
1399 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001400 name="ports-" + str( i ),
1401 args=[ ] )
1402 threads.append( t )
1403 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001404
1405 for t in threads:
1406 t.join()
1407 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001408 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001409 threads = []
1410 for i in range( numControllers ):
1411 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001412 name="links-" + str( i ),
1413 args=[ ] )
1414 threads.append( t )
1415 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001416
1417 for t in threads:
1418 t.join()
1419 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001420 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001421 threads = []
1422 for i in range( numControllers ):
1423 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001424 name="clusters-" + str( i ),
1425 args=[ ] )
1426 threads.append( t )
1427 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001428
1429 for t in threads:
1430 t.join()
1431 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001432 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001433
Jon Hall6aec96b2015-01-19 14:49:31 -08001434 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001435 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001436 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001437 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001438 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001439 if "Error" not in hosts[ controller ]:
1440 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001441 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001442 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001443 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001444 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001445 " is inconsistent with ONOS1" )
1446 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001447 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001448
1449 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001450 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001451 controllerStr )
1452 consistentHostsResult = main.FALSE
1453 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001454 " hosts response: " +
1455 repr( hosts[ controller ] ) )
1456 utilities.assert_equals(
1457 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001458 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001459 onpass="Hosts view is consistent across all ONOS nodes",
1460 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001461
Jon Hall390696c2015-05-05 17:13:41 -07001462 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001463 ipResult = main.TRUE
1464 for controller in range( 0, len( hosts ) ):
1465 controllerStr = str( controller + 1 )
1466 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001467 if not host.get( 'ipAddresses', [ ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001468 main.log.error( "DEBUG:Error with host ips on controller" +
1469 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001470 ipResult = main.FALSE
1471 utilities.assert_equals(
1472 expect=main.TRUE,
1473 actual=ipResult,
1474 onpass="The ips of the hosts aren't empty",
1475 onfail="The ip of at least one host is missing" )
1476
Jon Hall6aec96b2015-01-19 14:49:31 -08001477 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001478 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001479 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001480 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001481 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001482 if "Error" not in clusters[ controller ]:
1483 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001484 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001485 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001486 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001487 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001488 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001489
1490 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001491 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001492 "from ONOS" + controllerStr )
1493 consistentClustersResult = main.FALSE
1494 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001495 " clusters response: " +
1496 repr( clusters[ controller ] ) )
1497 utilities.assert_equals(
1498 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001499 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001500 onpass="Clusters view is consistent across all ONOS nodes",
1501 onfail="ONOS nodes have different views of clusters" )
1502 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001503 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001504 try:
1505 numClusters = len( json.loads( clusters[ 0 ] ) )
1506 except ( ValueError, TypeError ):
1507 main.log.exception( "Error parsing clusters[0]: " +
1508 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001509 clusterResults = main.FALSE
1510 if numClusters == 1:
1511 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 utilities.assert_equals(
1513 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001514 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001516 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001517
Jon Hall6aec96b2015-01-19 14:49:31 -08001518 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001519 devicesResults = main.TRUE
1520 portsResults = main.TRUE
1521 linksResults = main.TRUE
1522 for controller in range( numControllers ):
1523 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001524 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001525 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001526 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001527 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001528 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001529 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001530 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001531 actual=currentDevicesResult,
1532 onpass="ONOS" + controllerStr +
1533 " Switches view is correct",
1534 onfail="ONOS" + controllerStr +
1535 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001536
Jon Hall6aec96b2015-01-19 14:49:31 -08001537 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001538 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001539 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001540 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001541 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001542 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001543 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001544 actual=currentPortsResult,
1545 onpass="ONOS" + controllerStr +
1546 " ports view is correct",
1547 onfail="ONOS" + controllerStr +
1548 " ports view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001549
Jon Hall6aec96b2015-01-19 14:49:31 -08001550 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001551 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001552 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001553 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001554 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001555 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001557 actual=currentLinksResult,
1558 onpass="ONOS" + controllerStr +
1559 " links view is correct",
1560 onfail="ONOS" + controllerStr +
1561 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001562
Jon Hall8f89dda2015-01-22 16:03:33 -08001563 devicesResults = devicesResults and currentDevicesResult
1564 portsResults = portsResults and currentPortsResult
1565 linksResults = linksResults and currentLinksResult
Jon Hallb1290e82014-11-18 16:17:48 -05001566
Jon Hall65844a32015-03-09 19:09:37 -07001567 topoResult = ( devicesResults and portsResults and linksResults
1568 and consistentHostsResult and consistentClustersResult
1569 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001570 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001571 onpass="Topology Check Test successful",
1572 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001573
Jon Hall6aec96b2015-01-19 14:49:31 -08001574 def CASE6( self, main ):
1575 """
Jon Hallb1290e82014-11-18 16:17:48 -05001576 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001577 """
Jon Hall368769f2014-11-19 15:43:35 -08001578 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001579 assert numControllers, "numControllers not defined"
1580 assert main, "main not defined"
1581 assert utilities.assert_equals, "utilities.assert_equals not defined"
1582 assert CLIs, "CLIs not defined"
1583 assert nodes, "nodes not defined"
Jon Hall390696c2015-05-05 17:13:41 -07001584 main.case( "Wait 60 seconds instead of inducing a failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001585 time.sleep( 60 )
1586 utilities.assert_equals(
1587 expect=main.TRUE,
1588 actual=main.TRUE,
1589 onpass="Sleeping 60 seconds",
1590 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001591
Jon Hall6aec96b2015-01-19 14:49:31 -08001592 def CASE7( self, main ):
1593 """
Jon Hall368769f2014-11-19 15:43:35 -08001594 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001595 """
Jon Hallb1290e82014-11-18 16:17:48 -05001596 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001597 assert numControllers, "numControllers not defined"
1598 assert main, "main not defined"
1599 assert utilities.assert_equals, "utilities.assert_equals not defined"
1600 assert CLIs, "CLIs not defined"
1601 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001602 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001603
Jon Hall65844a32015-03-09 19:09:37 -07001604 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001605 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001606 rolesNotNull = main.TRUE
1607 threads = []
1608 for i in range( numControllers ):
1609 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001610 name="rolesNotNull-" + str( i ),
1611 args=[ ] )
1612 threads.append( t )
1613 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001614
1615 for t in threads:
1616 t.join()
1617 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001618 utilities.assert_equals(
1619 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001620 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001621 onpass="Each device has a master",
1622 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001623
Jon Hall390696c2015-05-05 17:13:41 -07001624 main.step( "Read device roles from ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -07001625 ONOSMastership = []
1626 mastershipCheck = main.FALSE
1627 consistentMastership = True
1628 rolesResults = True
1629 threads = []
1630 for i in range( numControllers ):
1631 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001632 name="roles-" + str( i ),
1633 args=[] )
1634 threads.append( t )
1635 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001636
1637 for t in threads:
1638 t.join()
1639 ONOSMastership.append( t.result )
1640
1641 for i in range( numControllers ):
1642 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001643 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001644 " roles" )
1645 main.log.warn(
1646 "ONOS" + str( i + 1 ) + " mastership response: " +
1647 repr( ONOSMastership[i] ) )
1648 rolesResults = False
1649 utilities.assert_equals(
1650 expect=True,
1651 actual=rolesResults,
1652 onpass="No error in reading roles output",
1653 onfail="Error in reading roles from ONOS" )
1654
1655 main.step( "Check for consistency in roles from each controller" )
1656 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001657 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001658 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001659 else:
Jon Hall65844a32015-03-09 19:09:37 -07001660 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001661 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001662 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001663 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001664 onpass="Switch roles are consistent across all ONOS nodes",
1665 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001666
Jon Hall65844a32015-03-09 19:09:37 -07001667 if rolesResults and not consistentMastership:
1668 for i in range( numControllers ):
1669 main.log.warn(
1670 "ONOS" + str( i + 1 ) + " roles: ",
1671 json.dumps(
1672 json.loads( ONOSMastership[ i ] ),
1673 sort_keys=True,
1674 indent=4,
1675 separators=( ',', ': ' ) ) )
1676 elif rolesResults and not consistentMastership:
1677 mastershipCheck = main.TRUE
1678
Jon Hallb1290e82014-11-18 16:17:48 -05001679 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001680 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001681 try:
1682 currentJson = json.loads( ONOSMastership[0] )
1683 oldJson = json.loads( mastershipState )
1684 except ( ValueError, TypeError ):
1685 main.log.exception( "Something is wrong with parsing " +
1686 "ONOSMastership[0] or mastershipState" )
1687 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1688 main.log.error( "mastershipState" + repr( mastershipState ) )
1689 main.cleanup()
1690 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001691 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001692 for i in range( 1, 29 ):
1693 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001694 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001695 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001696 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001697 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001698 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001699 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001700 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001701 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001702 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001703 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001704 utilities.assert_equals(
1705 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001706 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001707 onpass="Mastership of Switches was not changed",
1708 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001709 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001710
Jon Hall6aec96b2015-01-19 14:49:31 -08001711 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001712 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001713 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001714 consistentIntents = True
1715 intentsResults = True
1716 threads = []
1717 for i in range( numControllers ):
1718 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001719 name="intents-" + str( i ),
1720 args=[],
1721 kwargs={ 'jsonFormat': True } )
1722 threads.append( t )
1723 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001724
1725 for t in threads:
1726 t.join()
1727 ONOSIntents.append( t.result )
1728
1729 for i in range( numControllers ):
1730 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001731 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall65844a32015-03-09 19:09:37 -07001732 " intents" )
1733 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1734 repr( ONOSIntents[ i ] ) )
1735 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001736 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001737 expect=True,
1738 actual=intentsResults,
1739 onpass="No error in reading intents output",
1740 onfail="Error in reading intents from ONOS" )
1741
1742 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001743 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001744 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall65844a32015-03-09 19:09:37 -07001745 "nodes" )
1746 else:
1747 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001748
1749 # Try to make it easy to figure out what is happening
1750 #
1751 # Intent ONOS1 ONOS2 ...
1752 # 0x01 INSTALLED INSTALLING
1753 # ... ... ...
1754 # ... ... ...
1755 title = " ID"
1756 for n in range( numControllers ):
1757 title += " " * 10 + "ONOS" + str( n + 1 )
1758 main.log.warn( title )
1759 # get all intent keys in the cluster
1760 keys = []
1761 for nodeStr in ONOSIntents:
1762 node = json.loads( nodeStr )
1763 for intent in node:
1764 keys.append( intent.get( 'id' ) )
1765 keys = set( keys )
1766 for key in keys:
1767 row = "%-13s" % key
1768 for nodeStr in ONOSIntents:
1769 node = json.loads( nodeStr )
1770 for intent in node:
1771 if intent.get( 'id' ) == key:
1772 row += "%-15s" % intent.get( 'state' )
1773 main.log.warn( row )
1774 # End table view
1775
Jon Hall65844a32015-03-09 19:09:37 -07001776 utilities.assert_equals(
1777 expect=True,
1778 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001779 onpass="Intents are consistent across all ONOS nodes",
1780 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001781 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001782 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001783 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001784 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001785 try:
1786 for intent in json.loads( node ):
1787 nodeStates.append( intent[ 'state' ] )
1788 except ( ValueError, TypeError ):
1789 main.log.exception( "Error in parsing intents" )
1790 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001791 intentStates.append( nodeStates )
1792 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1793 main.log.info( dict( out ) )
1794
Jon Hall65844a32015-03-09 19:09:37 -07001795 if intentsResults and not consistentIntents:
1796 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001797 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1798 main.log.warn( json.dumps(
1799 json.loads( ONOSIntents[ i ] ),
1800 sort_keys=True,
1801 indent=4,
1802 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001803 elif intentsResults and consistentIntents:
1804 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001805
Jon Hall58c76b72015-02-23 11:09:24 -08001806 # NOTE: Store has no durability, so intents are lost across system
1807 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001808 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001809 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001810 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001811 sameIntents = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001812 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001813 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001814 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001815 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001816 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001817 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1818 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001819 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001820 before = json.loads( intentState )
1821 after = json.loads( ONOSIntents[ 0 ] )
1822 for intent in before:
1823 if intent not in after:
1824 sameIntents = main.FALSE
1825 main.log.debug( "Intent is not currently in ONOS " +\
1826 "(at least in the same form):" )
1827 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001828 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001829 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001830 main.log.debug( repr( ONOSIntents[0] ) )
1831 main.log.debug( repr( intentState ) )
1832 if sameIntents == main.FALSE:
1833 try:
1834 main.log.debug( "ONOS intents before: " )
1835 main.log.debug( json.dumps( json.loads( intentState ),
1836 sort_keys=True, indent=4,
1837 separators=( ',', ': ' ) ) )
1838 main.log.debug( "Current ONOS intents: " )
1839 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1840 sort_keys=True, indent=4,
1841 separators=( ',', ': ' ) ) )
1842 except ( ValueError, TypeError ):
1843 main.log.exception( "Exception printing intents" )
1844 main.log.debug( repr( ONOSIntents[0] ) )
1845 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001846 utilities.assert_equals(
1847 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001848 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001849 onpass="Intents are consistent with before failure",
1850 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001851 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001852
Jon Hall6aec96b2015-01-19 14:49:31 -08001853 main.step( "Get the OF Table entries and compare to before " +
1854 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001855 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001856 flows2 = []
1857 for i in range( 28 ):
1858 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001859 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1860 flows2.append( tmpFlows )
1861 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001862 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001863 flow2=tmpFlows )
1864 FlowTables = FlowTables and tempResult
1865 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001866 main.log.info( "Differences in flow table for switch: s" +
1867 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001868 utilities.assert_equals(
1869 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001870 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001871 onpass="No changes were found in the flow tables",
1872 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001873
Jon Hall6aec96b2015-01-19 14:49:31 -08001874 main.step( "Check the continuous pings to ensure that no packets " +
1875 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001876 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1877 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001878 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001879 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1880 for i in range( 8, 18 ):
1881 main.log.info(
1882 "Checking for a loss in pings along flow from s" +
1883 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001884 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001885 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001886 str( i ) ) or LossInPings
1887 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001888 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001889 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001890 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001891 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001892 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001893 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001894 utilities.assert_equals(
1895 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001896 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001897 onpass="No Loss of connectivity",
1898 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001899
Jon Hall390696c2015-05-05 17:13:41 -07001900 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001901 # Test of LeadershipElection
1902 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001903 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001904 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001905 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001906 for cli in CLIs:
1907 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001908 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001909 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001910 # all is well
1911 # NOTE: In failure scenario, this could be a new node, maybe
1912 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001913 pass
1914 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001915 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001916 main.log.error( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001917 "electionTestLeader function, check the" +
1918 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001919 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001920 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001921 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001922 main.log.error( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001923 " as the leader of the election app. " +
1924 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001925 utilities.assert_equals(
1926 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001927 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001928 onpass="Leadership election passed",
1929 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001930
Jon Hall6aec96b2015-01-19 14:49:31 -08001931 def CASE8( self, main ):
1932 """
Jon Hallb1290e82014-11-18 16:17:48 -05001933 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001934 """
Jon Hallb1290e82014-11-18 16:17:48 -05001935 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001936 # FIXME add this path to params
1937 sys.path.append( "/home/admin/sts" )
1938 # assumes that sts is already in you PYTHONPATH
1939 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001940 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001941 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001942 assert numControllers, "numControllers not defined"
1943 assert main, "main not defined"
1944 assert utilities.assert_equals, "utilities.assert_equals not defined"
1945 assert CLIs, "CLIs not defined"
1946 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05001947
Jon Hallfeff3082015-05-19 10:23:26 -07001948 main.case( "Compare ONOS Topology view to Mininet topology" )
1949 main.caseExplaination = "Compare topology objects between Mininet" +\
1950 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08001951 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07001952 try:
1953 ctrls = []
1954 for node in nodes:
1955 temp = ( node, node.name, node.ip_address, 6633 )
1956 ctrls.append( temp )
1957 MNTopo = TestONTopology( main.Mininet1, ctrls )
1958 except Exception:
1959 objResult = main.FALSE
1960 else:
1961 objResult = main.TRUE
1962 utilities.assert_equals( expect=main.TRUE, actual=objResult,
1963 onpass="Created TestONTopology object",
1964 onfail="Exception while creating " +
1965 "TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001966
Jon Hallfeff3082015-05-19 10:23:26 -07001967 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001968 devicesResults = main.TRUE
1969 portsResults = main.TRUE
1970 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001971 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001972 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001973 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001974 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001975 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001976 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001977 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001978 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07001979 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001980 if count > 1:
Jon Hall65844a32015-03-09 19:09:37 -07001981 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001982 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001983 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001984 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001985 threads = []
1986 for i in range( numControllers ):
1987 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001988 name="devices-" + str( i ),
1989 args=[ ] )
1990 threads.append( t )
1991 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001992
1993 for t in threads:
1994 t.join()
1995 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001996 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001997 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001998 threads = []
1999 for i in range( numControllers ):
2000 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07002001 name="hosts-" + str( i ),
2002 args=[ ] )
2003 threads.append( t )
2004 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002005
2006 for t in threads:
2007 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002008 try:
2009 hosts.append( json.loads( t.result ) )
2010 except ( ValueError, TypeError ):
2011 main.log.exception( "Error parsing hosts results" )
2012 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08002013 for controller in range( 0, len( hosts ) ):
2014 controllerStr = str( controller + 1 )
2015 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002016 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08002017 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002018 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall529a37f2015-01-28 10:02:00 -08002019 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002020 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002021 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07002022 threads = []
2023 for i in range( numControllers ):
2024 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07002025 name="ports-" + str( i ),
2026 args=[ ] )
2027 threads.append( t )
2028 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002029
2030 for t in threads:
2031 t.join()
2032 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002033 links = []
Jon Hall65844a32015-03-09 19:09:37 -07002034 threads = []
2035 for i in range( numControllers ):
2036 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07002037 name="links-" + str( i ),
2038 args=[ ] )
2039 threads.append( t )
2040 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002041
2042 for t in threads:
2043 t.join()
2044 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002045 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07002046 threads = []
2047 for i in range( numControllers ):
2048 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07002049 name="clusters-" + str( i ),
2050 args=[ ] )
2051 threads.append( t )
2052 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07002053
2054 for t in threads:
2055 t.join()
2056 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05002057
Jon Hall8f89dda2015-01-22 16:03:33 -08002058 elapsed = time.time() - startTime
2059 cliTime = time.time() - cliStart
2060 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05002061
Jon Hall21270ac2015-02-16 17:59:55 -08002062 for controller in range( numControllers ):
2063 controllerStr = str( controller + 1 )
2064 if devices[ controller ] or "Error" not in devices[
2065 controller ]:
2066 currentDevicesResult = main.Mininet1.compareSwitches(
2067 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002068 json.loads( devices[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002069 else:
2070 currentDevicesResult = main.FALSE
2071 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002072 actual=currentDevicesResult,
2073 onpass="ONOS" + controllerStr +
2074 " Switches view is correct",
2075 onfail="ONOS" + controllerStr +
2076 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05002077
Jon Hall21270ac2015-02-16 17:59:55 -08002078 if ports[ controller ] or "Error" not in ports[ controller ]:
2079 currentPortsResult = main.Mininet1.comparePorts(
2080 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002081 json.loads( ports[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002082 else:
2083 currentPortsResult = main.FALSE
2084 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002085 actual=currentPortsResult,
2086 onpass="ONOS" + controllerStr +
2087 " ports view is correct",
2088 onfail="ONOS" + controllerStr +
2089 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002090
Jon Hall21270ac2015-02-16 17:59:55 -08002091 if links[ controller ] or "Error" not in links[ controller ]:
2092 currentLinksResult = main.Mininet1.compareLinks(
2093 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002094 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08002095 else:
2096 currentLinksResult = main.FALSE
2097 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002098 actual=currentLinksResult,
2099 onpass="ONOS" + controllerStr +
2100 " links view is correct",
2101 onfail="ONOS" + controllerStr +
2102 " links view is incorrect" )
2103
2104 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2105 currentHostsResult = main.Mininet1.compareHosts(
2106 MNTopo, hosts[ controller ] )
2107 else:
2108 currentHostsResult = main.FALSE
2109 utilities.assert_equals( expect=main.TRUE,
2110 actual=currentHostsResult,
2111 onpass="ONOS" + controllerStr +
2112 " hosts exist in Mininet",
2113 onfail="ONOS" + controllerStr +
2114 " hosts don't match Mininet" )
2115
2116 devicesResults = devicesResults and currentDevicesResult
2117 portsResults = portsResults and currentPortsResult
2118 linksResults = linksResults and currentLinksResult
2119 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002120
Jon Hall21270ac2015-02-16 17:59:55 -08002121 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002122
Jon Hall21270ac2015-02-16 17:59:55 -08002123 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002124 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall21270ac2015-02-16 17:59:55 -08002125 consistentHostsResult = main.TRUE
2126 for controller in range( len( hosts ) ):
2127 controllerStr = str( controller + 1 )
2128 if "Error" not in hosts[ controller ]:
2129 if hosts[ controller ] == hosts[ 0 ]:
2130 continue
2131 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07002132 main.log.error( "hosts from ONOS" + controllerStr +
Jon Hall21270ac2015-02-16 17:59:55 -08002133 " is inconsistent with ONOS1" )
2134 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002135 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002136
Jon Hall21270ac2015-02-16 17:59:55 -08002137 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002138 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall21270ac2015-02-16 17:59:55 -08002139 controllerStr )
2140 consistentHostsResult = main.FALSE
2141 main.log.warn( "ONOS" + controllerStr +
2142 " hosts response: " +
2143 repr( hosts[ controller ] ) )
2144 utilities.assert_equals(
2145 expect=main.TRUE,
2146 actual=consistentHostsResult,
2147 onpass="Hosts view is consistent across all ONOS nodes",
2148 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002149
Jon Hall21270ac2015-02-16 17:59:55 -08002150 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002151 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall21270ac2015-02-16 17:59:55 -08002152 consistentClustersResult = main.TRUE
2153 for controller in range( len( clusters ) ):
2154 controllerStr = str( controller + 1 )
2155 if "Error" not in clusters[ controller ]:
2156 if clusters[ controller ] == clusters[ 0 ]:
2157 continue
2158 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07002159 main.log.error( "clusters from ONOS" +
Jon Hall21270ac2015-02-16 17:59:55 -08002160 controllerStr +
2161 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002162 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002163
Jon Hall21270ac2015-02-16 17:59:55 -08002164 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002165 main.log.error( "Error in getting dataplane clusters " +
Jon Hall21270ac2015-02-16 17:59:55 -08002166 "from ONOS" + controllerStr )
2167 consistentClustersResult = main.FALSE
2168 main.log.warn( "ONOS" + controllerStr +
2169 " clusters response: " +
2170 repr( clusters[ controller ] ) )
2171 utilities.assert_equals(
2172 expect=main.TRUE,
2173 actual=consistentClustersResult,
2174 onpass="Clusters view is consistent across all ONOS nodes",
2175 onfail="ONOS nodes have different views of clusters" )
2176 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002177 main.step( "Topology view is correct and consistent across all " +
2178 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002179 try:
2180 numClusters = len( json.loads( clusters[ 0 ] ) )
2181 except ( ValueError, TypeError ):
2182 main.log.exception( "Error parsing clusters[0]: " +
2183 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002184 clusterResults = main.FALSE
2185 if numClusters == 1:
2186 clusterResults = main.TRUE
Jon Hall21270ac2015-02-16 17:59:55 -08002187 utilities.assert_equals(
2188 expect=1,
2189 actual=numClusters,
2190 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002191 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002192
Jon Hall21270ac2015-02-16 17:59:55 -08002193 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002194 and hostsResults and consistentHostsResult
2195 and consistentClustersResult and clusterResults
2196 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002197
Jon Hall21270ac2015-02-16 17:59:55 -08002198 topoResult = topoResult and int( count <= 2 )
2199 note = "note it takes about " + str( int( cliTime ) ) + \
2200 " seconds for the test to make all the cli calls to fetch " +\
2201 "the topology from each ONOS instance"
2202 main.log.info(
2203 "Very crass estimate for topology discovery/convergence( " +
2204 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2205 str( count ) + " tries" )
2206 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002207 onpass="Topology Check Test successful",
2208 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05002209
Jon Halla9d26da2015-03-30 16:45:32 -07002210 # FIXME: move this to an ONOS state case
Jon Hall5cfd23c2015-03-19 11:40:57 -07002211 main.step( "Checking ONOS nodes" )
2212 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002213 nodeResults = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002214 threads = []
2215 for i in range( numControllers ):
2216 t = main.Thread( target=CLIs[i].nodes,
2217 name="nodes-" + str( i ),
2218 args=[ ] )
2219 threads.append( t )
2220 t.start()
2221
2222 for t in threads:
2223 t.join()
2224 nodesOutput.append( t.result )
2225 ips = [ node.ip_address for node in nodes ]
2226 for i in nodesOutput:
2227 try:
2228 current = json.loads( i )
2229 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002230 currentResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002231 if node['ip'] in ips: # node in nodes() output is in cell
2232 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002233 currentResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002234 else:
2235 main.log.error( "Error in ONOS node availability" )
2236 main.log.error(
2237 json.dumps( current,
2238 sort_keys=True,
2239 indent=4,
2240 separators=( ',', ': ' ) ) )
2241 break
Jon Hall390696c2015-05-05 17:13:41 -07002242 nodeResults = nodeResults and currentResult
Jon Hall5cfd23c2015-03-19 11:40:57 -07002243 except ( ValueError, TypeError ):
2244 main.log.error( "Error parsing nodes output" )
2245 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002246 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2247 onpass="Nodes check successful",
2248 onfail="Nodes check NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002249
Jon Hall6aec96b2015-01-19 14:49:31 -08002250 def CASE9( self, main ):
2251 """
Jon Hallb1290e82014-11-18 16:17:48 -05002252 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002253 """
2254 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002255 assert numControllers, "numControllers not defined"
2256 assert main, "main not defined"
2257 assert utilities.assert_equals, "utilities.assert_equals not defined"
2258 assert CLIs, "CLIs not defined"
2259 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002260 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002261
Jon Hall8f89dda2015-01-22 16:03:33 -08002262 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002263
Jon Hall6aec96b2015-01-19 14:49:31 -08002264 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002265 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002266 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002267
Jon Hall6aec96b2015-01-19 14:49:31 -08002268 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002269 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002270 main.log.info( "Waiting " + str( linkSleep ) +
2271 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002272 time.sleep( linkSleep )
2273 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002274 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002275 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002276 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002277
Jon Hall6aec96b2015-01-19 14:49:31 -08002278 def CASE10( self, main ):
2279 """
Jon Hallb1290e82014-11-18 16:17:48 -05002280 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002281 """
2282 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002283 assert numControllers, "numControllers not defined"
2284 assert main, "main not defined"
2285 assert utilities.assert_equals, "utilities.assert_equals not defined"
2286 assert CLIs, "CLIs not defined"
2287 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002288 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002289
Jon Hall8f89dda2015-01-22 16:03:33 -08002290 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002291
Jon Hall6aec96b2015-01-19 14:49:31 -08002292 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002293 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002294 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002295
Jon Hall6aec96b2015-01-19 14:49:31 -08002296 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002297 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002298 main.log.info( "Waiting " + str( linkSleep ) +
2299 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002300 time.sleep( linkSleep )
2301 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002302 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002303 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002304 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002305
Jon Hall6aec96b2015-01-19 14:49:31 -08002306 def CASE11( self, main ):
2307 """
Jon Hallb1290e82014-11-18 16:17:48 -05002308 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002309 """
2310 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002311 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002312 assert numControllers, "numControllers not defined"
2313 assert main, "main not defined"
2314 assert utilities.assert_equals, "utilities.assert_equals not defined"
2315 assert CLIs, "CLIs not defined"
2316 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002317
Jon Hall8f89dda2015-01-22 16:03:33 -08002318 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002319
2320 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002321 main.case( description )
2322 switch = main.params[ 'kill' ][ 'switch' ]
2323 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002324
Jon Hall6aec96b2015-01-19 14:49:31 -08002325 # TODO: Make this switch parameterizable
2326 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002327 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002328 main.Mininet1.delSwitch( switch )
2329 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002330 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002331 time.sleep( switchSleep )
2332 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002333 # Peek at the deleted switch
2334 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002335 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002336 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002337 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002338 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002339 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002340 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002341
Jon Hall6aec96b2015-01-19 14:49:31 -08002342 def CASE12( self, main ):
2343 """
Jon Hallb1290e82014-11-18 16:17:48 -05002344 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002345 """
2346 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002347 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002348 assert numControllers, "numControllers not defined"
2349 assert main, "main not defined"
2350 assert utilities.assert_equals, "utilities.assert_equals not defined"
2351 assert CLIs, "CLIs not defined"
2352 assert nodes, "nodes not defined"
2353 assert ONOS1Port, "ONOS1Port not defined"
2354 assert ONOS2Port, "ONOS2Port not defined"
2355 assert ONOS3Port, "ONOS3Port not defined"
2356 assert ONOS4Port, "ONOS4Port not defined"
2357 assert ONOS5Port, "ONOS5Port not defined"
2358 assert ONOS6Port, "ONOS6Port not defined"
2359 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002360
Jon Hall8f89dda2015-01-22 16:03:33 -08002361 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002362 switch = main.params[ 'kill' ][ 'switch' ]
2363 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2364 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002365 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002366 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002367
Jon Hall6aec96b2015-01-19 14:49:31 -08002368 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002369 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002370 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002371 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002372 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2373 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -07002374 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002375 port1=ONOS1Port,
Jon Hall65844a32015-03-09 19:09:37 -07002376 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002377 port2=ONOS2Port,
Jon Hall65844a32015-03-09 19:09:37 -07002378 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002379 port3=ONOS3Port,
Jon Hall65844a32015-03-09 19:09:37 -07002380 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002381 port4=ONOS4Port,
Jon Hall65844a32015-03-09 19:09:37 -07002382 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002383 port5=ONOS5Port,
Jon Hall65844a32015-03-09 19:09:37 -07002384 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002385 port6=ONOS6Port,
Jon Hall65844a32015-03-09 19:09:37 -07002386 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002387 port7=ONOS7Port )
2388 main.log.info( "Waiting " + str( switchSleep ) +
2389 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002390 time.sleep( switchSleep )
2391 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002392 # Peek at the deleted switch
2393 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002394 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002395 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002396 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002397 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002398 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002399 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002400
Jon Hall6aec96b2015-01-19 14:49:31 -08002401 def CASE13( self, main ):
2402 """
Jon Hallb1290e82014-11-18 16:17:48 -05002403 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002404 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002405 import os
2406 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002407 assert numControllers, "numControllers not defined"
2408 assert main, "main not defined"
2409 assert utilities.assert_equals, "utilities.assert_equals not defined"
2410 assert CLIs, "CLIs not defined"
2411 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002412
2413 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002414 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2415 'blue': '\033[94m', 'green': '\033[92m',
2416 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002417 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002418 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002419 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002420
Jon Hall6aec96b2015-01-19 14:49:31 -08002421 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002422 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002423 teststationUser = main.params[ 'TESTONUSER' ]
2424 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002425 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002426 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002427 # FIXME: scp
2428 # mn files
2429 # TODO: Load these from params
2430 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002431 logFolder = "/opt/onos/log/"
2432 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002433 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002434 dstDir = "~/packet_captures/"
2435 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002436 for node in nodes:
2437 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2438 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002439 teststationUser + "@" +
2440 teststationIP + ":" +
2441 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002442 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002443 main.ONOSbench.handle.expect( "\$" )
2444
Jon Hall6aec96b2015-01-19 14:49:31 -08002445 # std*.log's
2446 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002447 logFolder = "/opt/onos/var/"
2448 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002449 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002450 dstDir = "~/packet_captures/"
2451 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002452 for node in nodes:
2453 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2454 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002455 teststationUser + "@" +
2456 teststationIP + ":" +
2457 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002458 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002459 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002460 # sleep so scp can finish
2461 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002462
2463 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002464 mnResult = main.Mininet1.stopNet()
2465 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2466 onpass="Mininet stopped",
2467 onfail="MN cleanup NOT successful" )
Jon Hall65844a32015-03-09 19:09:37 -07002468
2469 main.step( "Checking ONOS Logs for errors" )
2470 for node in nodes:
2471 print colors[ 'purple' ] + "Checking logs for errors on " + \
2472 node.name + ":" + colors[ 'end' ]
2473 print main.ONOSbench.checkLogs( node.ip_address )
2474
Jon Hall6aec96b2015-01-19 14:49:31 -08002475 main.step( "Packing and rotating pcap archives" )
2476 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002477
Jon Hall390696c2015-05-05 17:13:41 -07002478 try:
Jon Hallfeff3082015-05-19 10:23:26 -07002479 timerLog = open( main.logdir + "/Timers.csv", 'w')
Jon Hall390696c2015-05-05 17:13:41 -07002480 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002481 labels = "Gossip Intents"
2482 data = str( gossipTime )
2483 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002484 timerLog.close()
Jon Hall390696c2015-05-05 17:13:41 -07002485 except NameError, e:
2486 main.log.exception(e)
Jon Hall73cf9cc2014-11-20 22:28:38 -08002487
Jon Hall6aec96b2015-01-19 14:49:31 -08002488 def CASE14( self, main ):
2489 """
Jon Hall94fd0472014-12-08 11:52:42 -08002490 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002491 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002492 assert numControllers, "numControllers not defined"
2493 assert main, "main not defined"
2494 assert utilities.assert_equals, "utilities.assert_equals not defined"
2495 assert CLIs, "CLIs not defined"
2496 assert nodes, "nodes not defined"
2497
Jon Hall390696c2015-05-05 17:13:41 -07002498 main.case("Start Leadership Election app")
2499 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002500 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2501 utilities.assert_equals(
2502 expect=main.TRUE,
2503 actual=appResult,
2504 onpass="Election app installed",
2505 onfail="Something went wrong with installing Leadership election" )
2506
2507 main.step( "Run for election on each node" )
2508 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002509 leaders = []
2510 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002511 cli.electionTestRun()
2512 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002513 leader = cli.electionTestLeader()
2514 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002515 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002516 "should be an ONOS node, instead got '" +
2517 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002518 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002519 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002520 utilities.assert_equals(
2521 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002522 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002523 onpass="Successfully ran for leadership",
2524 onfail="Failed to run for leadership" )
2525
2526 main.step( "Check that each node shows the same leader" )
2527 sameLeader = main.TRUE
2528 if len( set( leaders ) ) != 1:
2529 sameLeader = main.FALSE
2530 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2531 str( leaders ) )
2532 utilities.assert_equals(
2533 expect=main.TRUE,
2534 actual=sameLeader,
2535 onpass="Leadership is consistent for the election topic",
2536 onfail="Nodes have different leaders" )
Jon Hall94fd0472014-12-08 11:52:42 -08002537
Jon Hall6aec96b2015-01-19 14:49:31 -08002538 def CASE15( self, main ):
2539 """
Jon Hall669173b2014-12-17 11:36:30 -08002540 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002541 """
Jon Hall390696c2015-05-05 17:13:41 -07002542 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002543 assert numControllers, "numControllers not defined"
2544 assert main, "main not defined"
2545 assert utilities.assert_equals, "utilities.assert_equals not defined"
2546 assert CLIs, "CLIs not defined"
2547 assert nodes, "nodes not defined"
2548
Jon Hall8f89dda2015-01-22 16:03:33 -08002549 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002550 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002551 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002552
2553 main.step( "Check that each node shows the same leader" )
2554 sameLeader = main.TRUE
2555 leaders = []
2556 for cli in CLIs:
2557 leader = cli.electionTestLeader()
2558 leaders.append( leader )
2559 if len( set( leaders ) ) != 1:
2560 sameLeader = main.FALSE
2561 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2562 str( leaders ) )
2563 utilities.assert_equals(
2564 expect=main.TRUE,
2565 actual=sameLeader,
2566 onpass="Leadership is consistent for the election topic",
2567 onfail="Nodes have different leaders" )
2568
Jon Hall6aec96b2015-01-19 14:49:31 -08002569 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002570 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002571 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002572 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002573 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002574 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002575 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002576 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002577 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002578 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002579 for i in range( len( CLIs ) ):
2580 if leader == nodes[ i ].ip_address:
2581 oldLeader = CLIs[ i ]
2582 break
Jon Halla9d26da2015-03-30 16:45:32 -07002583 else: # FOR/ELSE statement
Jon Hall65844a32015-03-09 19:09:37 -07002584 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002585 if oldLeader:
2586 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002587 utilities.assert_equals(
2588 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002589 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002590 onpass="Node was withdrawn from election",
2591 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002592
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002594 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002595 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002596 for cli in CLIs:
2597 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002598 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002599 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002600 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002601 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002602 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002603 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002604 # error in response
2605 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002606 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002607 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002608 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002609 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002610 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002611 elif leaderN is None:
2612 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002613 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002614 leaderN = cli.electionTestLeader()
2615 leaderList.pop()
2616 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002617 consistentLeader = main.FALSE
2618 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002619 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002620 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002621 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002622 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002623 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002624 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002625 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002626 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002627 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002628 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002629 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002630 utilities.assert_equals(
2631 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002632 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002633 onpass="Leadership election passed",
2634 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002635
Jon Hall58c76b72015-02-23 11:09:24 -08002636 main.step( "Run for election on old leader( just so everyone " +
2637 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002638 if oldLeader:
2639 runResult = oldLeader.electionTestRun()
2640 else:
2641 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002642 utilities.assert_equals(
2643 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002644 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002645 onpass="App re-ran for election",
2646 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002647
Jon Hallfeff3082015-05-19 10:23:26 -07002648 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002649 afterRun = main.ONOScli1.electionTestLeader()
2650 # verify leader didn't just change
2651 if afterRun == leaderList[ 0 ]:
2652 afterResult = main.TRUE
2653 else:
2654 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002655
Jon Hall6aec96b2015-01-19 14:49:31 -08002656 utilities.assert_equals(
2657 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002658 actual=afterResult,
2659 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002660 onfail="Something went wrong with Leadership election after " +
2661 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002662
Jon Hall390696c2015-05-05 17:13:41 -07002663 def CASE16( self, main ):
2664 """
2665 Install Distributed Primitives app
2666 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002667 import time
Jon Hall390696c2015-05-05 17:13:41 -07002668 assert numControllers, "numControllers not defined"
2669 assert main, "main not defined"
2670 assert utilities.assert_equals, "utilities.assert_equals not defined"
2671 assert CLIs, "CLIs not defined"
2672 assert nodes, "nodes not defined"
2673
2674 # Variables for the distributed primitives tests
2675 global pCounterName
2676 global iCounterName
2677 global pCounterValue
2678 global iCounterValue
2679 global onosSet
2680 global onosSetName
2681 pCounterName = "TestON-Partitions"
2682 iCounterName = "TestON-inMemory"
2683 pCounterValue = 0
2684 iCounterValue = 0
2685 onosSet = set([])
2686 onosSetName = "TestON-set"
2687
2688 description = "Install Primitives app"
2689 main.case( description )
2690 main.step( "Install Primitives app" )
2691 appName = "org.onosproject.distributedprimitives"
2692 appResults = CLIs[0].activateApp( appName )
2693 utilities.assert_equals( expect=main.TRUE,
2694 actual=appResults,
2695 onpass="Primitives app activated",
2696 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002697 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002698
2699 def CASE17( self, main ):
2700 """
2701 Check for basic functionality with distributed primitives
2702 """
2703 # Make sure variables are defined/set
2704 assert numControllers, "numControllers not defined"
2705 assert main, "main not defined"
2706 assert utilities.assert_equals, "utilities.assert_equals not defined"
2707 assert CLIs, "CLIs not defined"
2708 assert nodes, "nodes not defined"
2709 assert pCounterName, "pCounterName not defined"
2710 assert iCounterName, "iCounterName not defined"
2711 assert onosSetName, "onosSetName not defined"
2712 # NOTE: assert fails if value is 0/None/Empty/False
2713 try:
2714 pCounterValue
2715 except NameError:
2716 main.log.error( "pCounterValue not defined, setting to 0" )
2717 pCounterValue = 0
2718 try:
2719 iCounterValue
2720 except NameError:
2721 main.log.error( "iCounterValue not defined, setting to 0" )
2722 iCounterValue = 0
2723 try:
2724 onosSet
2725 except NameError:
2726 main.log.error( "onosSet not defined, setting to empty Set" )
2727 onosSet = set([])
2728 # Variables for the distributed primitives tests. These are local only
2729 addValue = "a"
2730 addAllValue = "a b c d e f"
2731 retainValue = "c d e f"
2732
2733 description = "Check for basic functionality with distributed " +\
2734 "primitives"
2735 main.case( description )
2736 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2737 # DISTRIBUTED ATOMIC COUNTERS
2738 main.step( "Increment and get a default counter on each node" )
2739 pCounters = []
2740 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002741 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002742 for i in range( numControllers ):
2743 t = main.Thread( target=CLIs[i].counterTestIncrement,
2744 name="counterIncrement-" + str( i ),
2745 args=[ pCounterName ] )
2746 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002747 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002748 threads.append( t )
2749 t.start()
2750
2751 for t in threads:
2752 t.join()
2753 pCounters.append( t.result )
2754 # Check that counter incremented numController times
2755 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002756 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002757 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002758 pCounterResults = pCounterResults and tmpResult
2759 if not tmpResult:
2760 main.log.error( str( i ) + " is not in partitioned "
2761 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002762 utilities.assert_equals( expect=True,
2763 actual=pCounterResults,
2764 onpass="Default counter incremented",
2765 onfail="Error incrementing default" +
2766 " counter" )
2767
2768 main.step( "Increment and get an in memory counter on each node" )
2769 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002770 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002771 threads = []
2772 for i in range( numControllers ):
2773 t = main.Thread( target=CLIs[i].counterTestIncrement,
2774 name="icounterIncrement-" + str( i ),
2775 args=[ iCounterName ],
2776 kwargs={ "inMemory": True } )
2777 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002778 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002779 threads.append( t )
2780 t.start()
2781
2782 for t in threads:
2783 t.join()
2784 iCounters.append( t.result )
2785 # Check that counter incremented numController times
2786 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002787 for i in addedIValues:
2788 tmpResult = i in iCounters
2789 iCounterResults = iCounterResults and tmpResult
2790 if not tmpResult:
2791 main.log.error( str( i ) + " is not in the in-memory "
2792 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002793 utilities.assert_equals( expect=True,
2794 actual=iCounterResults,
2795 onpass="In memory counter incremented",
2796 onfail="Error incrementing in memory" +
2797 " counter" )
2798
2799 main.step( "Check counters are consistant across nodes" )
2800 onosCounters = []
2801 threads = []
2802 for i in range( numControllers ):
2803 t = main.Thread( target=CLIs[i].counters,
2804 name="counters-" + str( i ) )
2805 threads.append( t )
2806 t.start()
2807 for t in threads:
2808 t.join()
2809 onosCounters.append( t.result )
2810 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2811 if all( tmp ):
2812 main.log.info( "Counters are consistent across all nodes" )
2813 consistentCounterResults = main.TRUE
2814 else:
2815 main.log.error( "Counters are not consistent across all nodes" )
2816 consistentCounterResults = main.FALSE
2817 utilities.assert_equals( expect=main.TRUE,
2818 actual=consistentCounterResults,
2819 onpass="ONOS counters are consistent " +
2820 "across nodes",
2821 onfail="ONOS Counters are inconsistent " +
2822 "across nodes" )
2823
2824 main.step( "Counters we added have the correct values" )
2825 correctResults = main.TRUE
2826 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002827 current = json.loads( onosCounters[i] )
2828 pValue = None
2829 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002830 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002831 for database in current:
2832 partitioned = database.get( 'partitionedDatabaseCounters' )
2833 if partitioned:
2834 for value in partitioned:
2835 if value.get( 'name' ) == pCounterName:
2836 pValue = value.get( 'value' )
2837 break
2838 inMemory = database.get( 'inMemoryDatabaseCounters' )
2839 if inMemory:
2840 for value in inMemory:
2841 if value.get( 'name' ) == iCounterName:
2842 iValue = value.get( 'value' )
2843 break
Jon Hall390696c2015-05-05 17:13:41 -07002844 except AttributeError, e:
2845 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2846 "is not as expected" )
2847 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07002848 if pValue == pCounterValue:
2849 main.log.info( "Partitioned counter value is correct" )
2850 else:
2851 main.log.error( "Partitioned counter value is incorrect," +
2852 " expected value: " + str( pCounterValue )
2853 + " current value: " + str( pValue ) )
2854 correctResults = main.FALSE
2855 if iValue == iCounterValue:
2856 main.log.info( "In memory counter value is correct" )
2857 else:
2858 main.log.error( "In memory counter value is incorrect, " +
2859 "expected value: " + str( iCounterValue ) +
2860 " current value: " + str( iValue ) )
2861 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07002862 utilities.assert_equals( expect=main.TRUE,
2863 actual=correctResults,
2864 onpass="Added counters are correct",
2865 onfail="Added counters are incorrect" )
2866 # DISTRIBUTED SETS
2867 main.step( "Distributed Set get" )
2868 size = len( onosSet )
2869 getResponses = []
2870 threads = []
2871 for i in range( numControllers ):
2872 t = main.Thread( target=CLIs[i].setTestGet,
2873 name="setTestGet-" + str( i ),
2874 args=[ onosSetName ] )
2875 threads.append( t )
2876 t.start()
2877 for t in threads:
2878 t.join()
2879 getResponses.append( t.result )
2880
2881 getResults = main.TRUE
2882 for i in range( numControllers ):
2883 if isinstance( getResponses[ i ], list):
2884 current = set( getResponses[ i ] )
2885 if len( current ) == len( getResponses[ i ] ):
2886 # no repeats
2887 if onosSet != current:
2888 main.log.error( "ONOS" + str( i + 1 ) +
2889 " has incorrect view" +
2890 " of set " + onosSetName + ":\n" +
2891 str( getResponses[ i ] ) )
2892 main.log.debug( "Expected: " + str( onosSet ) )
2893 main.log.debug( "Actual: " + str( current ) )
2894 getResults = main.FALSE
2895 else:
2896 # error, set is not a set
2897 main.log.error( "ONOS" + str( i + 1 ) +
2898 " has repeat elements in" +
2899 " set " + onosSetName + ":\n" +
2900 str( getResponses[ i ] ) )
2901 getResults = main.FALSE
2902 elif getResponses[ i ] == main.ERROR:
2903 getResults = main.FALSE
2904 utilities.assert_equals( expect=main.TRUE,
2905 actual=getResults,
2906 onpass="Set elements are correct",
2907 onfail="Set elements are incorrect" )
2908
2909 main.step( "Distributed Set size" )
2910 sizeResponses = []
2911 threads = []
2912 for i in range( numControllers ):
2913 t = main.Thread( target=CLIs[i].setTestSize,
2914 name="setTestSize-" + str( i ),
2915 args=[ onosSetName ] )
2916 threads.append( t )
2917 t.start()
2918 for t in threads:
2919 t.join()
2920 sizeResponses.append( t.result )
2921
2922 sizeResults = main.TRUE
2923 for i in range( numControllers ):
2924 if size != sizeResponses[ i ]:
2925 sizeResults = main.FALSE
2926 main.log.error( "ONOS" + str( i + 1 ) +
2927 " expected a size of " + str( size ) +
2928 " for set " + onosSetName +
2929 " but got " + str( sizeResponses[ i ] ) )
2930 utilities.assert_equals( expect=main.TRUE,
2931 actual=sizeResults,
2932 onpass="Set sizes are correct",
2933 onfail="Set sizes are incorrect" )
2934
2935 main.step( "Distributed Set add()" )
2936 onosSet.add( addValue )
2937 addResponses = []
2938 threads = []
2939 for i in range( numControllers ):
2940 t = main.Thread( target=CLIs[i].setTestAdd,
2941 name="setTestAdd-" + str( i ),
2942 args=[ onosSetName, addValue ] )
2943 threads.append( t )
2944 t.start()
2945 for t in threads:
2946 t.join()
2947 addResponses.append( t.result )
2948
2949 # main.TRUE = successfully changed the set
2950 # main.FALSE = action resulted in no change in set
2951 # main.ERROR - Some error in executing the function
2952 addResults = main.TRUE
2953 for i in range( numControllers ):
2954 if addResponses[ i ] == main.TRUE:
2955 # All is well
2956 pass
2957 elif addResponses[ i ] == main.FALSE:
2958 # Already in set, probably fine
2959 pass
2960 elif addResponses[ i ] == main.ERROR:
2961 # Error in execution
2962 addResults = main.FALSE
2963 else:
2964 # unexpected result
2965 addResults = main.FALSE
2966 if addResults != main.TRUE:
2967 main.log.error( "Error executing set add" )
2968
2969 # Check if set is still correct
2970 size = len( onosSet )
2971 getResponses = []
2972 threads = []
2973 for i in range( numControllers ):
2974 t = main.Thread( target=CLIs[i].setTestGet,
2975 name="setTestGet-" + str( i ),
2976 args=[ onosSetName ] )
2977 threads.append( t )
2978 t.start()
2979 for t in threads:
2980 t.join()
2981 getResponses.append( t.result )
2982 getResults = main.TRUE
2983 for i in range( numControllers ):
2984 if isinstance( getResponses[ i ], list):
2985 current = set( getResponses[ i ] )
2986 if len( current ) == len( getResponses[ i ] ):
2987 # no repeats
2988 if onosSet != current:
2989 main.log.error( "ONOS" + str( i + 1 ) +
2990 " has incorrect view" +
2991 " of set " + onosSetName + ":\n" +
2992 str( getResponses[ i ] ) )
2993 main.log.debug( "Expected: " + str( onosSet ) )
2994 main.log.debug( "Actual: " + str( current ) )
2995 getResults = main.FALSE
2996 else:
2997 # error, set is not a set
2998 main.log.error( "ONOS" + str( i + 1 ) +
2999 " has repeat elements in" +
3000 " set " + onosSetName + ":\n" +
3001 str( getResponses[ i ] ) )
3002 getResults = main.FALSE
3003 elif getResponses[ i ] == main.ERROR:
3004 getResults = main.FALSE
3005 sizeResponses = []
3006 threads = []
3007 for i in range( numControllers ):
3008 t = main.Thread( target=CLIs[i].setTestSize,
3009 name="setTestSize-" + str( i ),
3010 args=[ onosSetName ] )
3011 threads.append( t )
3012 t.start()
3013 for t in threads:
3014 t.join()
3015 sizeResponses.append( t.result )
3016 sizeResults = main.TRUE
3017 for i in range( numControllers ):
3018 if size != sizeResponses[ i ]:
3019 sizeResults = main.FALSE
3020 main.log.error( "ONOS" + str( i + 1 ) +
3021 " expected a size of " + str( size ) +
3022 " for set " + onosSetName +
3023 " but got " + str( sizeResponses[ i ] ) )
3024 addResults = addResults and getResults and sizeResults
3025 utilities.assert_equals( expect=main.TRUE,
3026 actual=addResults,
3027 onpass="Set add correct",
3028 onfail="Set add was incorrect" )
3029
3030 main.step( "Distributed Set addAll()" )
3031 onosSet.update( addAllValue.split() )
3032 addResponses = []
3033 threads = []
3034 for i in range( numControllers ):
3035 t = main.Thread( target=CLIs[i].setTestAdd,
3036 name="setTestAddAll-" + str( i ),
3037 args=[ onosSetName, addAllValue ] )
3038 threads.append( t )
3039 t.start()
3040 for t in threads:
3041 t.join()
3042 addResponses.append( t.result )
3043
3044 # main.TRUE = successfully changed the set
3045 # main.FALSE = action resulted in no change in set
3046 # main.ERROR - Some error in executing the function
3047 addAllResults = main.TRUE
3048 for i in range( numControllers ):
3049 if addResponses[ i ] == main.TRUE:
3050 # All is well
3051 pass
3052 elif addResponses[ i ] == main.FALSE:
3053 # Already in set, probably fine
3054 pass
3055 elif addResponses[ i ] == main.ERROR:
3056 # Error in execution
3057 addAllResults = main.FALSE
3058 else:
3059 # unexpected result
3060 addAllResults = main.FALSE
3061 if addAllResults != main.TRUE:
3062 main.log.error( "Error executing set addAll" )
3063
3064 # Check if set is still correct
3065 size = len( onosSet )
3066 getResponses = []
3067 threads = []
3068 for i in range( numControllers ):
3069 t = main.Thread( target=CLIs[i].setTestGet,
3070 name="setTestGet-" + str( i ),
3071 args=[ onosSetName ] )
3072 threads.append( t )
3073 t.start()
3074 for t in threads:
3075 t.join()
3076 getResponses.append( t.result )
3077 getResults = main.TRUE
3078 for i in range( numControllers ):
3079 if isinstance( getResponses[ i ], list):
3080 current = set( getResponses[ i ] )
3081 if len( current ) == len( getResponses[ i ] ):
3082 # no repeats
3083 if onosSet != current:
3084 main.log.error( "ONOS" + str( i + 1 ) +
3085 " has incorrect view" +
3086 " of set " + onosSetName + ":\n" +
3087 str( getResponses[ i ] ) )
3088 main.log.debug( "Expected: " + str( onosSet ) )
3089 main.log.debug( "Actual: " + str( current ) )
3090 getResults = main.FALSE
3091 else:
3092 # error, set is not a set
3093 main.log.error( "ONOS" + str( i + 1 ) +
3094 " has repeat elements in" +
3095 " set " + onosSetName + ":\n" +
3096 str( getResponses[ i ] ) )
3097 getResults = main.FALSE
3098 elif getResponses[ i ] == main.ERROR:
3099 getResults = main.FALSE
3100 sizeResponses = []
3101 threads = []
3102 for i in range( numControllers ):
3103 t = main.Thread( target=CLIs[i].setTestSize,
3104 name="setTestSize-" + str( i ),
3105 args=[ onosSetName ] )
3106 threads.append( t )
3107 t.start()
3108 for t in threads:
3109 t.join()
3110 sizeResponses.append( t.result )
3111 sizeResults = main.TRUE
3112 for i in range( numControllers ):
3113 if size != sizeResponses[ i ]:
3114 sizeResults = main.FALSE
3115 main.log.error( "ONOS" + str( i + 1 ) +
3116 " expected a size of " + str( size ) +
3117 " for set " + onosSetName +
3118 " but got " + str( sizeResponses[ i ] ) )
3119 addAllResults = addAllResults and getResults and sizeResults
3120 utilities.assert_equals( expect=main.TRUE,
3121 actual=addAllResults,
3122 onpass="Set addAll correct",
3123 onfail="Set addAll was incorrect" )
3124
3125 main.step( "Distributed Set contains()" )
3126 containsResponses = []
3127 threads = []
3128 for i in range( numControllers ):
3129 t = main.Thread( target=CLIs[i].setTestGet,
3130 name="setContains-" + str( i ),
3131 args=[ onosSetName ],
3132 kwargs={ "values": addValue } )
3133 threads.append( t )
3134 t.start()
3135 for t in threads:
3136 t.join()
3137 # NOTE: This is the tuple
3138 containsResponses.append( t.result )
3139
3140 containsResults = main.TRUE
3141 for i in range( numControllers ):
3142 if containsResponses[ i ] == main.ERROR:
3143 containsResults = main.FALSE
3144 else:
3145 containsResults = containsResults and\
3146 containsResponses[ i ][ 1 ]
3147 utilities.assert_equals( expect=main.TRUE,
3148 actual=containsResults,
3149 onpass="Set contains is functional",
3150 onfail="Set contains failed" )
3151
3152 main.step( "Distributed Set containsAll()" )
3153 containsAllResponses = []
3154 threads = []
3155 for i in range( numControllers ):
3156 t = main.Thread( target=CLIs[i].setTestGet,
3157 name="setContainsAll-" + str( i ),
3158 args=[ onosSetName ],
3159 kwargs={ "values": addAllValue } )
3160 threads.append( t )
3161 t.start()
3162 for t in threads:
3163 t.join()
3164 # NOTE: This is the tuple
3165 containsAllResponses.append( t.result )
3166
3167 containsAllResults = main.TRUE
3168 for i in range( numControllers ):
3169 if containsResponses[ i ] == main.ERROR:
3170 containsResults = main.FALSE
3171 else:
3172 containsResults = containsResults and\
3173 containsResponses[ i ][ 1 ]
3174 utilities.assert_equals( expect=main.TRUE,
3175 actual=containsAllResults,
3176 onpass="Set containsAll is functional",
3177 onfail="Set containsAll failed" )
3178
3179 main.step( "Distributed Set remove()" )
3180 onosSet.remove( addValue )
3181 removeResponses = []
3182 threads = []
3183 for i in range( numControllers ):
3184 t = main.Thread( target=CLIs[i].setTestRemove,
3185 name="setTestRemove-" + str( i ),
3186 args=[ onosSetName, addValue ] )
3187 threads.append( t )
3188 t.start()
3189 for t in threads:
3190 t.join()
3191 removeResponses.append( t.result )
3192
3193 # main.TRUE = successfully changed the set
3194 # main.FALSE = action resulted in no change in set
3195 # main.ERROR - Some error in executing the function
3196 removeResults = main.TRUE
3197 for i in range( numControllers ):
3198 if removeResponses[ i ] == main.TRUE:
3199 # All is well
3200 pass
3201 elif removeResponses[ i ] == main.FALSE:
3202 # not in set, probably fine
3203 pass
3204 elif removeResponses[ i ] == main.ERROR:
3205 # Error in execution
3206 removeResults = main.FALSE
3207 else:
3208 # unexpected result
3209 removeResults = main.FALSE
3210 if removeResults != main.TRUE:
3211 main.log.error( "Error executing set remove" )
3212
3213 # Check if set is still correct
3214 size = len( onosSet )
3215 getResponses = []
3216 threads = []
3217 for i in range( numControllers ):
3218 t = main.Thread( target=CLIs[i].setTestGet,
3219 name="setTestGet-" + str( i ),
3220 args=[ onosSetName ] )
3221 threads.append( t )
3222 t.start()
3223 for t in threads:
3224 t.join()
3225 getResponses.append( t.result )
3226 getResults = main.TRUE
3227 for i in range( numControllers ):
3228 if isinstance( getResponses[ i ], list):
3229 current = set( getResponses[ i ] )
3230 if len( current ) == len( getResponses[ i ] ):
3231 # no repeats
3232 if onosSet != current:
3233 main.log.error( "ONOS" + str( i + 1 ) +
3234 " has incorrect view" +
3235 " of set " + onosSetName + ":\n" +
3236 str( getResponses[ i ] ) )
3237 main.log.debug( "Expected: " + str( onosSet ) )
3238 main.log.debug( "Actual: " + str( current ) )
3239 getResults = main.FALSE
3240 else:
3241 # error, set is not a set
3242 main.log.error( "ONOS" + str( i + 1 ) +
3243 " has repeat elements in" +
3244 " set " + onosSetName + ":\n" +
3245 str( getResponses[ i ] ) )
3246 getResults = main.FALSE
3247 elif getResponses[ i ] == main.ERROR:
3248 getResults = main.FALSE
3249 sizeResponses = []
3250 threads = []
3251 for i in range( numControllers ):
3252 t = main.Thread( target=CLIs[i].setTestSize,
3253 name="setTestSize-" + str( i ),
3254 args=[ onosSetName ] )
3255 threads.append( t )
3256 t.start()
3257 for t in threads:
3258 t.join()
3259 sizeResponses.append( t.result )
3260 sizeResults = main.TRUE
3261 for i in range( numControllers ):
3262 if size != sizeResponses[ i ]:
3263 sizeResults = main.FALSE
3264 main.log.error( "ONOS" + str( i + 1 ) +
3265 " expected a size of " + str( size ) +
3266 " for set " + onosSetName +
3267 " but got " + str( sizeResponses[ i ] ) )
3268 removeResults = removeResults and getResults and sizeResults
3269 utilities.assert_equals( expect=main.TRUE,
3270 actual=removeResults,
3271 onpass="Set remove correct",
3272 onfail="Set remove was incorrect" )
3273
3274 main.step( "Distributed Set removeAll()" )
3275 onosSet.difference_update( addAllValue.split() )
3276 removeAllResponses = []
3277 threads = []
3278 try:
3279 for i in range( numControllers ):
3280 t = main.Thread( target=CLIs[i].setTestRemove,
3281 name="setTestRemoveAll-" + str( i ),
3282 args=[ onosSetName, addAllValue ] )
3283 threads.append( t )
3284 t.start()
3285 for t in threads:
3286 t.join()
3287 removeAllResponses.append( t.result )
3288 except Exception, e:
3289 main.log.exception(e)
3290
3291 # main.TRUE = successfully changed the set
3292 # main.FALSE = action resulted in no change in set
3293 # main.ERROR - Some error in executing the function
3294 removeAllResults = main.TRUE
3295 for i in range( numControllers ):
3296 if removeAllResponses[ i ] == main.TRUE:
3297 # All is well
3298 pass
3299 elif removeAllResponses[ i ] == main.FALSE:
3300 # not in set, probably fine
3301 pass
3302 elif removeAllResponses[ i ] == main.ERROR:
3303 # Error in execution
3304 removeAllResults = main.FALSE
3305 else:
3306 # unexpected result
3307 removeAllResults = main.FALSE
3308 if removeAllResults != main.TRUE:
3309 main.log.error( "Error executing set removeAll" )
3310
3311 # Check if set is still correct
3312 size = len( onosSet )
3313 getResponses = []
3314 threads = []
3315 for i in range( numControllers ):
3316 t = main.Thread( target=CLIs[i].setTestGet,
3317 name="setTestGet-" + str( i ),
3318 args=[ onosSetName ] )
3319 threads.append( t )
3320 t.start()
3321 for t in threads:
3322 t.join()
3323 getResponses.append( t.result )
3324 getResults = main.TRUE
3325 for i in range( numControllers ):
3326 if isinstance( getResponses[ i ], list):
3327 current = set( getResponses[ i ] )
3328 if len( current ) == len( getResponses[ i ] ):
3329 # no repeats
3330 if onosSet != current:
3331 main.log.error( "ONOS" + str( i + 1 ) +
3332 " has incorrect view" +
3333 " of set " + onosSetName + ":\n" +
3334 str( getResponses[ i ] ) )
3335 main.log.debug( "Expected: " + str( onosSet ) )
3336 main.log.debug( "Actual: " + str( current ) )
3337 getResults = main.FALSE
3338 else:
3339 # error, set is not a set
3340 main.log.error( "ONOS" + str( i + 1 ) +
3341 " has repeat elements in" +
3342 " set " + onosSetName + ":\n" +
3343 str( getResponses[ i ] ) )
3344 getResults = main.FALSE
3345 elif getResponses[ i ] == main.ERROR:
3346 getResults = main.FALSE
3347 sizeResponses = []
3348 threads = []
3349 for i in range( numControllers ):
3350 t = main.Thread( target=CLIs[i].setTestSize,
3351 name="setTestSize-" + str( i ),
3352 args=[ onosSetName ] )
3353 threads.append( t )
3354 t.start()
3355 for t in threads:
3356 t.join()
3357 sizeResponses.append( t.result )
3358 sizeResults = main.TRUE
3359 for i in range( numControllers ):
3360 if size != sizeResponses[ i ]:
3361 sizeResults = main.FALSE
3362 main.log.error( "ONOS" + str( i + 1 ) +
3363 " expected a size of " + str( size ) +
3364 " for set " + onosSetName +
3365 " but got " + str( sizeResponses[ i ] ) )
3366 removeAllResults = removeAllResults and getResults and sizeResults
3367 utilities.assert_equals( expect=main.TRUE,
3368 actual=removeAllResults,
3369 onpass="Set removeAll correct",
3370 onfail="Set removeAll was incorrect" )
3371
3372 main.step( "Distributed Set addAll()" )
3373 onosSet.update( addAllValue.split() )
3374 addResponses = []
3375 threads = []
3376 for i in range( numControllers ):
3377 t = main.Thread( target=CLIs[i].setTestAdd,
3378 name="setTestAddAll-" + str( i ),
3379 args=[ onosSetName, addAllValue ] )
3380 threads.append( t )
3381 t.start()
3382 for t in threads:
3383 t.join()
3384 addResponses.append( t.result )
3385
3386 # main.TRUE = successfully changed the set
3387 # main.FALSE = action resulted in no change in set
3388 # main.ERROR - Some error in executing the function
3389 addAllResults = main.TRUE
3390 for i in range( numControllers ):
3391 if addResponses[ i ] == main.TRUE:
3392 # All is well
3393 pass
3394 elif addResponses[ i ] == main.FALSE:
3395 # Already in set, probably fine
3396 pass
3397 elif addResponses[ i ] == main.ERROR:
3398 # Error in execution
3399 addAllResults = main.FALSE
3400 else:
3401 # unexpected result
3402 addAllResults = main.FALSE
3403 if addAllResults != main.TRUE:
3404 main.log.error( "Error executing set addAll" )
3405
3406 # Check if set is still correct
3407 size = len( onosSet )
3408 getResponses = []
3409 threads = []
3410 for i in range( numControllers ):
3411 t = main.Thread( target=CLIs[i].setTestGet,
3412 name="setTestGet-" + str( i ),
3413 args=[ onosSetName ] )
3414 threads.append( t )
3415 t.start()
3416 for t in threads:
3417 t.join()
3418 getResponses.append( t.result )
3419 getResults = main.TRUE
3420 for i in range( numControllers ):
3421 if isinstance( getResponses[ i ], list):
3422 current = set( getResponses[ i ] )
3423 if len( current ) == len( getResponses[ i ] ):
3424 # no repeats
3425 if onosSet != current:
3426 main.log.error( "ONOS" + str( i + 1 ) +
3427 " has incorrect view" +
3428 " of set " + onosSetName + ":\n" +
3429 str( getResponses[ i ] ) )
3430 main.log.debug( "Expected: " + str( onosSet ) )
3431 main.log.debug( "Actual: " + str( current ) )
3432 getResults = main.FALSE
3433 else:
3434 # error, set is not a set
3435 main.log.error( "ONOS" + str( i + 1 ) +
3436 " has repeat elements in" +
3437 " set " + onosSetName + ":\n" +
3438 str( getResponses[ i ] ) )
3439 getResults = main.FALSE
3440 elif getResponses[ i ] == main.ERROR:
3441 getResults = main.FALSE
3442 sizeResponses = []
3443 threads = []
3444 for i in range( numControllers ):
3445 t = main.Thread( target=CLIs[i].setTestSize,
3446 name="setTestSize-" + str( i ),
3447 args=[ onosSetName ] )
3448 threads.append( t )
3449 t.start()
3450 for t in threads:
3451 t.join()
3452 sizeResponses.append( t.result )
3453 sizeResults = main.TRUE
3454 for i in range( numControllers ):
3455 if size != sizeResponses[ i ]:
3456 sizeResults = main.FALSE
3457 main.log.error( "ONOS" + str( i + 1 ) +
3458 " expected a size of " + str( size ) +
3459 " for set " + onosSetName +
3460 " but got " + str( sizeResponses[ i ] ) )
3461 addAllResults = addAllResults and getResults and sizeResults
3462 utilities.assert_equals( expect=main.TRUE,
3463 actual=addAllResults,
3464 onpass="Set addAll correct",
3465 onfail="Set addAll was incorrect" )
3466
3467 main.step( "Distributed Set clear()" )
3468 onosSet.clear()
3469 clearResponses = []
3470 threads = []
3471 for i in range( numControllers ):
3472 t = main.Thread( target=CLIs[i].setTestRemove,
3473 name="setTestClear-" + str( i ),
3474 args=[ onosSetName, " "], # Values doesn't matter
3475 kwargs={ "clear": True } )
3476 threads.append( t )
3477 t.start()
3478 for t in threads:
3479 t.join()
3480 clearResponses.append( t.result )
3481
3482 # main.TRUE = successfully changed the set
3483 # main.FALSE = action resulted in no change in set
3484 # main.ERROR - Some error in executing the function
3485 clearResults = main.TRUE
3486 for i in range( numControllers ):
3487 if clearResponses[ i ] == main.TRUE:
3488 # All is well
3489 pass
3490 elif clearResponses[ i ] == main.FALSE:
3491 # Nothing set, probably fine
3492 pass
3493 elif clearResponses[ i ] == main.ERROR:
3494 # Error in execution
3495 clearResults = main.FALSE
3496 else:
3497 # unexpected result
3498 clearResults = main.FALSE
3499 if clearResults != main.TRUE:
3500 main.log.error( "Error executing set clear" )
3501
3502 # Check if set is still correct
3503 size = len( onosSet )
3504 getResponses = []
3505 threads = []
3506 for i in range( numControllers ):
3507 t = main.Thread( target=CLIs[i].setTestGet,
3508 name="setTestGet-" + str( i ),
3509 args=[ onosSetName ] )
3510 threads.append( t )
3511 t.start()
3512 for t in threads:
3513 t.join()
3514 getResponses.append( t.result )
3515 getResults = main.TRUE
3516 for i in range( numControllers ):
3517 if isinstance( getResponses[ i ], list):
3518 current = set( getResponses[ i ] )
3519 if len( current ) == len( getResponses[ i ] ):
3520 # no repeats
3521 if onosSet != current:
3522 main.log.error( "ONOS" + str( i + 1 ) +
3523 " has incorrect view" +
3524 " of set " + onosSetName + ":\n" +
3525 str( getResponses[ i ] ) )
3526 main.log.debug( "Expected: " + str( onosSet ) )
3527 main.log.debug( "Actual: " + str( current ) )
3528 getResults = main.FALSE
3529 else:
3530 # error, set is not a set
3531 main.log.error( "ONOS" + str( i + 1 ) +
3532 " has repeat elements in" +
3533 " set " + onosSetName + ":\n" +
3534 str( getResponses[ i ] ) )
3535 getResults = main.FALSE
3536 elif getResponses[ i ] == main.ERROR:
3537 getResults = main.FALSE
3538 sizeResponses = []
3539 threads = []
3540 for i in range( numControllers ):
3541 t = main.Thread( target=CLIs[i].setTestSize,
3542 name="setTestSize-" + str( i ),
3543 args=[ onosSetName ] )
3544 threads.append( t )
3545 t.start()
3546 for t in threads:
3547 t.join()
3548 sizeResponses.append( t.result )
3549 sizeResults = main.TRUE
3550 for i in range( numControllers ):
3551 if size != sizeResponses[ i ]:
3552 sizeResults = main.FALSE
3553 main.log.error( "ONOS" + str( i + 1 ) +
3554 " expected a size of " + str( size ) +
3555 " for set " + onosSetName +
3556 " but got " + str( sizeResponses[ i ] ) )
3557 clearResults = clearResults and getResults and sizeResults
3558 utilities.assert_equals( expect=main.TRUE,
3559 actual=clearResults,
3560 onpass="Set clear correct",
3561 onfail="Set clear was incorrect" )
3562
3563 main.step( "Distributed Set addAll()" )
3564 onosSet.update( addAllValue.split() )
3565 addResponses = []
3566 threads = []
3567 for i in range( numControllers ):
3568 t = main.Thread( target=CLIs[i].setTestAdd,
3569 name="setTestAddAll-" + str( i ),
3570 args=[ onosSetName, addAllValue ] )
3571 threads.append( t )
3572 t.start()
3573 for t in threads:
3574 t.join()
3575 addResponses.append( t.result )
3576
3577 # main.TRUE = successfully changed the set
3578 # main.FALSE = action resulted in no change in set
3579 # main.ERROR - Some error in executing the function
3580 addAllResults = main.TRUE
3581 for i in range( numControllers ):
3582 if addResponses[ i ] == main.TRUE:
3583 # All is well
3584 pass
3585 elif addResponses[ i ] == main.FALSE:
3586 # Already in set, probably fine
3587 pass
3588 elif addResponses[ i ] == main.ERROR:
3589 # Error in execution
3590 addAllResults = main.FALSE
3591 else:
3592 # unexpected result
3593 addAllResults = main.FALSE
3594 if addAllResults != main.TRUE:
3595 main.log.error( "Error executing set addAll" )
3596
3597 # Check if set is still correct
3598 size = len( onosSet )
3599 getResponses = []
3600 threads = []
3601 for i in range( numControllers ):
3602 t = main.Thread( target=CLIs[i].setTestGet,
3603 name="setTestGet-" + str( i ),
3604 args=[ onosSetName ] )
3605 threads.append( t )
3606 t.start()
3607 for t in threads:
3608 t.join()
3609 getResponses.append( t.result )
3610 getResults = main.TRUE
3611 for i in range( numControllers ):
3612 if isinstance( getResponses[ i ], list):
3613 current = set( getResponses[ i ] )
3614 if len( current ) == len( getResponses[ i ] ):
3615 # no repeats
3616 if onosSet != current:
3617 main.log.error( "ONOS" + str( i + 1 ) +
3618 " has incorrect view" +
3619 " of set " + onosSetName + ":\n" +
3620 str( getResponses[ i ] ) )
3621 main.log.debug( "Expected: " + str( onosSet ) )
3622 main.log.debug( "Actual: " + str( current ) )
3623 getResults = main.FALSE
3624 else:
3625 # error, set is not a set
3626 main.log.error( "ONOS" + str( i + 1 ) +
3627 " has repeat elements in" +
3628 " set " + onosSetName + ":\n" +
3629 str( getResponses[ i ] ) )
3630 getResults = main.FALSE
3631 elif getResponses[ i ] == main.ERROR:
3632 getResults = main.FALSE
3633 sizeResponses = []
3634 threads = []
3635 for i in range( numControllers ):
3636 t = main.Thread( target=CLIs[i].setTestSize,
3637 name="setTestSize-" + str( i ),
3638 args=[ onosSetName ] )
3639 threads.append( t )
3640 t.start()
3641 for t in threads:
3642 t.join()
3643 sizeResponses.append( t.result )
3644 sizeResults = main.TRUE
3645 for i in range( numControllers ):
3646 if size != sizeResponses[ i ]:
3647 sizeResults = main.FALSE
3648 main.log.error( "ONOS" + str( i + 1 ) +
3649 " expected a size of " + str( size ) +
3650 " for set " + onosSetName +
3651 " but got " + str( sizeResponses[ i ] ) )
3652 addAllResults = addAllResults and getResults and sizeResults
3653 utilities.assert_equals( expect=main.TRUE,
3654 actual=addAllResults,
3655 onpass="Set addAll correct",
3656 onfail="Set addAll was incorrect" )
3657
3658 main.step( "Distributed Set retain()" )
3659 onosSet.intersection_update( retainValue.split() )
3660 retainResponses = []
3661 threads = []
3662 for i in range( numControllers ):
3663 t = main.Thread( target=CLIs[i].setTestRemove,
3664 name="setTestRetain-" + str( i ),
3665 args=[ onosSetName, retainValue ],
3666 kwargs={ "retain": True } )
3667 threads.append( t )
3668 t.start()
3669 for t in threads:
3670 t.join()
3671 retainResponses.append( t.result )
3672
3673 # main.TRUE = successfully changed the set
3674 # main.FALSE = action resulted in no change in set
3675 # main.ERROR - Some error in executing the function
3676 retainResults = main.TRUE
3677 for i in range( numControllers ):
3678 if retainResponses[ i ] == main.TRUE:
3679 # All is well
3680 pass
3681 elif retainResponses[ i ] == main.FALSE:
3682 # Already in set, probably fine
3683 pass
3684 elif retainResponses[ i ] == main.ERROR:
3685 # Error in execution
3686 retainResults = main.FALSE
3687 else:
3688 # unexpected result
3689 retainResults = main.FALSE
3690 if retainResults != main.TRUE:
3691 main.log.error( "Error executing set retain" )
3692
3693 # Check if set is still correct
3694 size = len( onosSet )
3695 getResponses = []
3696 threads = []
3697 for i in range( numControllers ):
3698 t = main.Thread( target=CLIs[i].setTestGet,
3699 name="setTestGet-" + str( i ),
3700 args=[ onosSetName ] )
3701 threads.append( t )
3702 t.start()
3703 for t in threads:
3704 t.join()
3705 getResponses.append( t.result )
3706 getResults = main.TRUE
3707 for i in range( numControllers ):
3708 if isinstance( getResponses[ i ], list):
3709 current = set( getResponses[ i ] )
3710 if len( current ) == len( getResponses[ i ] ):
3711 # no repeats
3712 if onosSet != current:
3713 main.log.error( "ONOS" + str( i + 1 ) +
3714 " has incorrect view" +
3715 " of set " + onosSetName + ":\n" +
3716 str( getResponses[ i ] ) )
3717 main.log.debug( "Expected: " + str( onosSet ) )
3718 main.log.debug( "Actual: " + str( current ) )
3719 getResults = main.FALSE
3720 else:
3721 # error, set is not a set
3722 main.log.error( "ONOS" + str( i + 1 ) +
3723 " has repeat elements in" +
3724 " set " + onosSetName + ":\n" +
3725 str( getResponses[ i ] ) )
3726 getResults = main.FALSE
3727 elif getResponses[ i ] == main.ERROR:
3728 getResults = main.FALSE
3729 sizeResponses = []
3730 threads = []
3731 for i in range( numControllers ):
3732 t = main.Thread( target=CLIs[i].setTestSize,
3733 name="setTestSize-" + str( i ),
3734 args=[ onosSetName ] )
3735 threads.append( t )
3736 t.start()
3737 for t in threads:
3738 t.join()
3739 sizeResponses.append( t.result )
3740 sizeResults = main.TRUE
3741 for i in range( numControllers ):
3742 if size != sizeResponses[ i ]:
3743 sizeResults = main.FALSE
3744 main.log.error( "ONOS" + str( i + 1 ) +
3745 " expected a size of " +
3746 str( size ) + " for set " + onosSetName +
3747 " but got " + str( sizeResponses[ i ] ) )
3748 retainResults = retainResults and getResults and sizeResults
3749 utilities.assert_equals( expect=main.TRUE,
3750 actual=retainResults,
3751 onpass="Set retain correct",
3752 onfail="Set retain was incorrect" )
3753