blob: c03c655ab6a2f5748f5556efb1e8131bf7fca1be [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if a single
3 instance ONOS 'cluster' can handle a restart
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
Jon Hallc9eabec2015-06-10 14:33:14 -07007CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
Jon Hall73cf9cc2014-11-20 22:28:38 -08009CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
Jon Hallc9eabec2015-06-10 14:33:14 -070012CASE6: The Failure case.
Jon Hall73cf9cc2014-11-20 22:28:38 -080013CASE7: Check state after control plane failure
14CASE8: 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 Hall48cf3ce2015-01-12 15:43:18 -080027class HATestSingleInstanceRestart:
Jon Hall73cf9cc2014-11-20 22:28:38 -080028
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080030 self.default = ''
31
Jon Hall6aec96b2015-01-19 14:49:31 -080032 def CASE1( self, main ):
33 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080034 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080037 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 Hall73cf9cc2014-11-20 22:28:38 -080045 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 Single node cluster restart " +
Jon Hall6aec96b2015-01-19 14:49:31 -080051 "HA test - initialization" )
52 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070053 main.caseExplaination = "Setup the test environment including " +\
54 "installing ONOS, starting Mininet and ONOS" +\
55 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080056 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080057
Jon Hall5cfd23c2015-03-19 11:40:57 -070058 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080059 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080060 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080061 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080062 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080063 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080064
65 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS1Ip
67 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080072 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080073 global ONOS7Port
74 global numControllers
Jon Hall5cfd23c2015-03-19 11:40:57 -070075 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080076
Jon Hall8f89dda2015-01-22 16:03:33 -080077 ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
78 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080079 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080080 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080081 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080082 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080083 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080084 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -080085
Jon Halla9d26da2015-03-30 16:45:32 -070086 global CLIs
87 CLIs = []
88 global nodes
89 nodes = []
90 for i in range( 1, numControllers + 1 ):
91 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
92 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
93
Jon Hall6aec96b2015-01-19 14:49:31 -080094 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080095 cellResult = main.ONOSbench.setCell( cellName )
96 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080097
Jon Hall6aec96b2015-01-19 14:49:31 -080098 # FIXME:this is short term fix
Jon Hallfeff3082015-05-19 10:23:26 -070099 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 main.ONOSbench.onosRemoveRaftLogs()
Jon Halla9d26da2015-03-30 16:45:32 -0700101
Jon Hallfeff3082015-05-19 10:23:26 -0700102 main.log.info( "Uninstalling ONOS" )
Jon Halla9d26da2015-03-30 16:45:32 -0700103 for node in nodes:
104 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800105
Jon Hall390696c2015-05-05 17:13:41 -0700106 # Make sure ONOS is DEAD
Jon Hallfeff3082015-05-19 10:23:26 -0700107 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700108 killResults = main.TRUE
109 for node in nodes:
110 killed = main.ONOSbench.onosKill( node.ip_address )
111 killResults = killResults and killed
112
Jon Hall8f89dda2015-01-22 16:03:33 -0800113 cleanInstallResult = main.TRUE
114 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800115
Jon Hall97f31752015-02-04 12:01:04 -0800116 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700117 mnResult = main.Mininet1.startNet( )
118 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
119 onpass="Mininet Started",
120 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800121
Jon Hallfeff3082015-05-19 10:23:26 -0700122 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800123 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800124 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800125 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700126 # values of 1 or 3 are good
127 utilities.assert_lesser( expect=0, actual=gitPullResult,
128 onpass="Git pull successful",
129 onfail="Git pull failed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700131
132 main.step( "Using mvn clean install" )
133 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700134 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700135 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700136 else:
137 main.log.warn( "Did not pull new code so skipping mvn " +
138 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700139 utilities.assert_equals( expect=main.TRUE,
140 actual=cleanInstallResult,
141 onpass="MCI successful",
142 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700143 # GRAPHS
144 # NOTE: important params here:
145 # job = name of Jenkins job
146 # Plot Name = Plot-HA, only can be used if multiple plots
147 # index = The number of the graph under plot name
148 job = "HASingleInstanceRestart"
Jon Hall40d2cbd2015-06-03 16:24:29 -0700149 plotName = "Plot-HA"
Jon Hall390696c2015-05-05 17:13:41 -0700150 graphs = '<ac:structured-macro ac:name="html">\n'
151 graphs += '<ac:plain-text-body><![CDATA[\n'
152 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Hall40d2cbd2015-06-03 16:24:29 -0700153 '/plot/' + plotName + '/getPlot?index=0' +\
154 '&width=500&height=300"' +\
Jon Hall390696c2015-05-05 17:13:41 -0700155 'noborder="0" width="500" height="300" scrolling="yes" ' +\
156 'seamless="seamless"></iframe>\n'
157 graphs += ']]></ac:plain-text-body>\n'
158 graphs += '</ac:structured-macro>\n'
159 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800160
Jon Hall8f89dda2015-01-22 16:03:33 -0800161 cellResult = main.ONOSbench.setCell( "SingleHA" )
162 verifyResult = main.ONOSbench.verifyCell()
Jon Hall6aec96b2015-01-19 14:49:31 -0800163 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800164 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700165 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
166 onpass="ONOS package successful",
167 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800168
Jon Hall6aec96b2015-01-19 14:49:31 -0800169 main.step( "Installing ONOS package" )
Jon Hall390696c2015-05-05 17:13:41 -0700170 onosInstallResult = main.ONOSbench.onosInstall( options="-f",
Jon Hall8f89dda2015-01-22 16:03:33 -0800171 node=ONOS1Ip )
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 Hall73cf9cc2014-11-20 22:28:38 -0800175
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 Hall8f89dda2015-01-22 16:03:33 -0800178 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
179 if onos1Isup:
Jon Hall94fd0472014-12-08 11:52:42 -0800180 break
Jon Hall390696c2015-05-05 17:13:41 -0700181 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
182 onpass="ONOS startup successful",
183 onfail="ONOS startup failed" )
Jon Hall94fd0472014-12-08 11:52:42 -0800184
Jon Hall390696c2015-05-05 17:13:41 -0700185 main.log.step( "Starting ONOS CLI sessions" )
186 cliResults = main.ONOScli1.startOnosCli( ONOS1Ip )
187 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
188 onpass="ONOS cli startup successful",
189 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800190
Jon Hall40d2cbd2015-06-03 16:24:29 -0700191 if main.params[ 'tcpdump' ].lower() == "true":
192 main.step( "Start Packet Capture MN" )
193 main.Mininet2.startTcpdump(
194 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
195 + "-MN.pcap",
196 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
197 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800198
Jon Hall390696c2015-05-05 17:13:41 -0700199 main.step( "App Ids check" )
Jon Hallfeff3082015-05-19 10:23:26 -0700200 appCheck = main.ONOScli1.appToIDCheck()
Jon Hall390696c2015-05-05 17:13:41 -0700201 if appCheck != main.TRUE:
202 main.log.warn( CLIs[0].apps() )
203 main.log.warn( CLIs[0].appIDs() )
204 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
205 onpass="App Ids seem to be correct",
206 onfail="Something is wrong with app Ids" )
207
Jon Hallfeff3082015-05-19 10:23:26 -0700208 if cliResults == main.FALSE:
209 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800210 main.cleanup()
211 main.exit()
212
Jon Hall6aec96b2015-01-19 14:49:31 -0800213 def CASE2( self, main ):
214 """
Jon Hallc9eabec2015-06-10 14:33:14 -0700215 Assign devices to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800216 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800217 import re
Jon Hallc9eabec2015-06-10 14:33:14 -0700218 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700219 assert numControllers, "numControllers not defined"
220 assert main, "main not defined"
221 assert utilities.assert_equals, "utilities.assert_equals not defined"
222 assert ONOS1Port, "ONOS1Port not defined"
223 assert ONOS2Port, "ONOS2Port not defined"
224 assert ONOS3Port, "ONOS3Port not defined"
225 assert ONOS4Port, "ONOS4Port not defined"
226 assert ONOS5Port, "ONOS5Port not defined"
227 assert ONOS6Port, "ONOS6Port not defined"
228 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800229
Jon Hallc9eabec2015-06-10 14:33:14 -0700230 main.case( "Assigning devices to controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700231 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
232 "and check that an ONOS node becomes the " +\
233 "master of the device."
Jon Hall6aec96b2015-01-19 14:49:31 -0800234 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800235
Jon Hall0f523f22015-07-06 09:31:09 -0700236 ipList = []
237 for i in range( numControllers ):
238 ipList.append( nodes[ i ].ip_address )
239 swList = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800240 for i in range( 1, 29 ):
Jon Hall0f523f22015-07-06 09:31:09 -0700241 swList.append( "s" + str( i ) )
242 main.Mininet1.assignSwController( sw=swList, ip=ipList )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800243
Jon Hall8f89dda2015-01-22 16:03:33 -0800244 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800245 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800246 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800247 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800248 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800249 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800250 main.log.info( repr( response ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800251 if re.search( "tcp:" + ONOS1Ip, response ):
252 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800253 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800254 mastershipCheck = main.FALSE
255 if mastershipCheck == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700256 main.log.info( "Switch mastership assigned correctly" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800257 utilities.assert_equals(
258 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800259 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800260 onpass="Switch mastership assigned correctly",
261 onfail="Switches not assigned correctly to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800262
Jon Hallc9eabec2015-06-10 14:33:14 -0700263 def CASE21( self, main ):
264 """
265 Assign mastership to controllers
266 """
267 import re
268 import time
269 assert numControllers, "numControllers not defined"
270 assert main, "main not defined"
271 assert utilities.assert_equals, "utilities.assert_equals not defined"
272 assert CLIs, "CLIs not defined"
273 assert nodes, "nodes not defined"
274 assert ONOS1Port, "ONOS1Port not defined"
275 assert ONOS2Port, "ONOS2Port not defined"
276 assert ONOS3Port, "ONOS3Port not defined"
277 assert ONOS4Port, "ONOS4Port not defined"
278 assert ONOS5Port, "ONOS5Port not defined"
279 assert ONOS6Port, "ONOS6Port not defined"
280 assert ONOS7Port, "ONOS7Port not defined"
281
282 main.case( "Assigning Controller roles for switches" )
283 main.caseExplaination = "Check that ONOS is connected to each " +\
284 "device. Then manually assign" +\
285 " mastership to specific ONOS nodes using" +\
286 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700287 main.step( "Assign mastership of switches to specific controllers" )
Jon Halla9d26da2015-03-30 16:45:32 -0700288 roleCall = main.TRUE
289 roleCheck = main.TRUE
290 try:
291 for i in range( 1, 29 ): # switches 1 through 28
292 ip = nodes[ 0 ].ip_address # ONOS1
293 # set up correct variables:
294 if i == 1:
295 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
296 elif i == 2:
297 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
298 elif i == 3:
299 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
300 elif i == 4:
301 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
302 elif i == 5:
303 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
304 elif i == 6:
305 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
306 elif i == 7:
307 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
308 elif i >= 8 and i <= 17:
309 dpid = '3' + str( i ).zfill( 3 )
310 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
311 elif i >= 18 and i <= 27:
312 dpid = '6' + str( i ).zfill( 3 )
313 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
314 elif i == 28:
315 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
316 else:
317 main.log.error( "You didn't write an else statement for " +
318 "switch s" + str( i ) )
319 # Assign switch
320 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
321 # TODO: make this controller dynamic
322 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
323 ip )
324 # Check assignment
Jon Hall390696c2015-05-05 17:13:41 -0700325 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
Jon Hall678f4512015-03-31 09:48:31 -0700326 if ip in master:
Jon Halla9d26da2015-03-30 16:45:32 -0700327 roleCheck = roleCheck and main.TRUE
328 else:
329 roleCheck = roleCheck and main.FALSE
330 main.log.error( "Error, controller " + ip + " is not" +
331 " master " + "of device " +
Jon Hall678f4512015-03-31 09:48:31 -0700332 str( deviceId ) + ". Master is " +
333 repr( master ) + "." )
Jon Halla9d26da2015-03-30 16:45:32 -0700334 except ( AttributeError, AssertionError ):
335 main.log.exception( "Something is wrong with ONOS device view" )
336 main.log.info( main.ONOScli1.devices() )
337 utilities.assert_equals(
338 expect=main.TRUE,
339 actual=roleCall,
340 onpass="Re-assigned switch mastership to designated controller",
341 onfail="Something wrong with deviceRole calls" )
342
Jon Hall390696c2015-05-05 17:13:41 -0700343 main.step( "Check mastership was correctly assigned" )
Jon Halla9d26da2015-03-30 16:45:32 -0700344 utilities.assert_equals(
345 expect=main.TRUE,
346 actual=roleCheck,
347 onpass="Switches were successfully reassigned to designated " +
348 "controller",
349 onfail="Switches were not successfully reassigned" )
Jon Halla9d26da2015-03-30 16:45:32 -0700350
Jon Hall6aec96b2015-01-19 14:49:31 -0800351 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800352 """
353 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800354 """
355 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800356 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700357 assert numControllers, "numControllers not defined"
358 assert main, "main not defined"
359 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700360 # NOTE: we must reinstall intents until we have a persistant intent
361 # datastore!
Jon Hall6aec96b2015-01-19 14:49:31 -0800362 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700363 main.caseExplaination = "Discover hosts by using pingall then " +\
364 "assign predetermined host-to-host intents." +\
365 " After installation, check that the intent" +\
366 " is distributed to all nodes and the state" +\
367 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800368
Jon Hall6aec96b2015-01-19 14:49:31 -0800369 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700370 main.step( "Install reactive forwarding app" )
371 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
372 utilities.assert_equals( expect=main.TRUE, actual=installResults,
373 onpass="Install fwd successful",
374 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700375
Jon Hallfeff3082015-05-19 10:23:26 -0700376 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700377 appCheck = main.ONOScli1.appToIDCheck()
378 if appCheck != main.TRUE:
379 main.log.warn( CLIs[0].apps() )
380 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700381 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
382 onpass="App Ids seem to be correct",
383 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800384
Jon Hallfeff3082015-05-19 10:23:26 -0700385 main.step( "Discovering Hosts( Via pingall for now )" )
386 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800387 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800388 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700389 for i in range(2): # Retry if pingall fails first time
390 time1 = time.time()
391 pingResult = main.Mininet1.pingall()
Jon Hall0f523f22015-07-06 09:31:09 -0700392 if i == 0:
393 utilities.assert_equals(
394 expect=main.TRUE,
395 actual=pingResult,
396 onpass="Reactive Pingall test passed",
397 onfail="Reactive Pingall failed, " +
398 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700399 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700400 main.log.info( "Time for pingall: %2f seconds" %
401 ( time2 - time1 ) )
402 # timeout for fwd flows
403 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800404 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700405 main.step( "Uninstall reactive forwarding app" )
406 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
407 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
408 onpass="Uninstall fwd successful",
409 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700410
411 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700412 appCheck2 = main.ONOScli1.appToIDCheck()
413 if appCheck2 != main.TRUE:
414 main.log.warn( CLIs[0].apps() )
415 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700416 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
417 onpass="App Ids seem to be correct",
418 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700419
Jon Hallfeff3082015-05-19 10:23:26 -0700420 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800421 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800422 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800423 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800424 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800425 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800426 for i in range( 8, 18 ):
427 main.log.info( "Adding host intent between h" + str( i ) +
428 " and h" + str( i + 10 ) )
429 host1 = "00:00:00:00:00:" + \
430 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
431 host2 = "00:00:00:00:00:" + \
432 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800433 # NOTE: getHost can return None
434 host1Dict = main.ONOScli1.getHost( host1 )
435 host2Dict = main.ONOScli1.getHost( host2 )
436 host1Id = None
437 host2Id = None
438 if host1Dict and host2Dict:
439 host1Id = host1Dict.get( 'id', None )
440 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800441 if host1Id and host2Id:
Jon Halla9d26da2015-03-30 16:45:32 -0700442 tmpId = main.ONOScli1.addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800443 if tmpId:
444 main.log.info( "Added intent with id: " + tmpId )
445 intentIds.append( tmpId )
446 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700447 main.log.error( "addHostIntent returned: " +
448 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800449 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700450 main.log.error( "Error, getHost() failed for h" + str( i ) +
451 " and/or h" + str( i + 10 ) )
452 hosts = main.ONOScli1.hosts()
453 main.log.warn( "Hosts output: " )
454 try:
455 main.log.warn( json.dumps( json.loads( hosts ),
456 sort_keys=True,
457 indent=4,
458 separators=( ',', ': ' ) ) )
459 except ( ValueError, TypeError ):
460 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800461 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700462 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
463 onpass="Found a host id for each host",
464 onfail="Error looking up host ids" )
465
Jon Halla9d26da2015-03-30 16:45:32 -0700466 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800467 onosIds = main.ONOScli1.getAllIntentsId()
468 main.log.info( "Submitted intents: " + str( intentIds ) )
469 main.log.info( "Intents in ONOS: " + str( onosIds ) )
470 for intent in intentIds:
471 if intent in onosIds:
Jon Halla9d26da2015-03-30 16:45:32 -0700472 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800473 else:
474 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700475 if intentAddResult:
476 intentStop = time.time()
477 else:
478 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800479 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800480 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800481 intentStates = []
Jon Halla9d26da2015-03-30 16:45:32 -0700482 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800483 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
484 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700485 try:
486 for intent in json.loads( intents ):
487 state = intent.get( 'state', None )
488 if "INSTALLED" not in state:
489 installedCheck = False
490 intentId = intent.get( 'id', None )
491 intentStates.append( ( intentId, state ) )
492 except ( ValueError, TypeError ):
493 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800494 # add submitted intents not in the store
495 tmplist = [ i for i, s in intentStates ]
496 missingIntents = False
497 for i in intentIds:
498 if i not in tmplist:
499 intentStates.append( ( i, " - " ) )
500 missingIntents = True
501 intentStates.sort()
502 for i, s in intentStates:
503 count += 1
504 main.log.info( "%-6s%-15s%-15s" %
505 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700506 leaders = main.ONOScli1.leaders()
507 try:
Jon Hallafa8a472015-06-12 14:02:42 -0700508 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700509 if leaders:
510 parsedLeaders = json.loads( leaders )
511 main.log.warn( json.dumps( parsedLeaders,
512 sort_keys=True,
513 indent=4,
514 separators=( ',', ': ' ) ) )
515 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700516 topics = []
517 for i in range( 14 ):
518 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700519 main.log.debug( topics )
520 ONOStopics = [ j['topic'] for j in parsedLeaders ]
521 for topic in topics:
522 if topic not in ONOStopics:
523 main.log.error( "Error: " + topic +
524 " not in leaders" )
Jon Hallafa8a472015-06-12 14:02:42 -0700525 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700526 else:
527 main.log.error( "leaders() returned None" )
528 except ( ValueError, TypeError ):
529 main.log.exception( "Error parsing leaders" )
530 main.log.error( repr( leaders ) )
Jon Hallafa8a472015-06-12 14:02:42 -0700531 # Check all nodes
532 if missing:
533 response = main.ONOScli1.leaders( jsonFormat=False)
534 main.log.warn( "ONOS1 leaders output: \n" +
535 str( response ) )
536
Jon Hall5cfd23c2015-03-19 11:40:57 -0700537 partitions = main.ONOScli1.partitions()
538 try:
539 if partitions :
540 parsedPartitions = json.loads( partitions )
541 main.log.warn( json.dumps( parsedPartitions,
542 sort_keys=True,
543 indent=4,
544 separators=( ',', ': ' ) ) )
545 # TODO check for a leader in all paritions
546 # TODO check for consistency among nodes
547 else:
548 main.log.error( "partitions() returned None" )
549 except ( ValueError, TypeError ):
550 main.log.exception( "Error parsing partitions" )
551 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800552 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700553 try:
554 if pendingMap :
555 parsedPending = json.loads( pendingMap )
556 main.log.warn( json.dumps( parsedPending,
557 sort_keys=True,
558 indent=4,
559 separators=( ',', ': ' ) ) )
560 # TODO check something here?
561 else:
562 main.log.error( "pendingMap() returned None" )
563 except ( ValueError, TypeError ):
564 main.log.exception( "Error parsing pending map" )
565 main.log.error( repr( pendingMap ) )
566
Jon Hallfeff3082015-05-19 10:23:26 -0700567 intentAddResult = bool( intentAddResult and not missingIntents and
568 installedCheck )
569 if not intentAddResult:
570 main.log.error( "Error in pushing host intents to ONOS" )
571
Jon Hall390696c2015-05-05 17:13:41 -0700572 main.step( "Intent Anti-Entropy dispersion" )
573 for i in range(100):
574 correct = True
575 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
576 for cli in CLIs:
577 onosIds = []
578 ids = cli.getAllIntentsId()
579 onosIds.append( ids )
580 main.log.debug( "Intents in " + cli.name + ": " +
581 str( sorted( onosIds ) ) )
582 if sorted( ids ) != sorted( intentIds ):
Jon Hallafa8a472015-06-12 14:02:42 -0700583 main.log.warn( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700584 correct = False
Jon Hallafa8a472015-06-12 14:02:42 -0700585 break
586 else:
587 intents = json.loads( cli.intents() )
588 for intent in intents:
589 if intent[ 'state' ] != "INSTALLED":
590 main.log.warn( "Intent " + intent[ 'id' ] +
591 " is " + intent[ 'state' ] )
592 correct = False
593 break
Jon Hall390696c2015-05-05 17:13:41 -0700594 if correct:
595 break
596 else:
597 time.sleep(1)
598 if not intentStop:
599 intentStop = time.time()
600 global gossipTime
601 gossipTime = intentStop - intentStart
602 main.log.info( "It took about " + str( gossipTime ) +
603 " seconds for all intents to appear in each node" )
604 # FIXME: make this time configurable/calculate based off of number of
605 # nodes and gossip rounds
606 utilities.assert_greater_equals(
607 expect=40, actual=gossipTime,
608 onpass="ECM anti-entropy for intents worked within " +
609 "expected time",
610 onfail="Intent ECM anti-entropy took too long" )
611 if gossipTime <= 40:
612 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800613
Jon Hall63604932015-02-26 17:09:50 -0800614 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800615 import time
Jon Hall63604932015-02-26 17:09:50 -0800616 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800617 main.log.info( "Sleeping 60 seconds to see if intents are found" )
618 time.sleep( 60 )
619 onosIds = main.ONOScli1.getAllIntentsId()
620 main.log.info( "Submitted intents: " + str( intentIds ) )
621 main.log.info( "Intents in ONOS: " + str( onosIds ) )
622 # Print the intent states
623 intents = main.ONOScli1.intents()
624 intentStates = []
625 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
626 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700627 try:
628 for intent in json.loads( intents ):
629 # Iter through intents of a node
630 state = intent.get( 'state', None )
631 if "INSTALLED" not in state:
632 installedCheck = False
633 intentId = intent.get( 'id', None )
634 intentStates.append( ( intentId, state ) )
635 except ( ValueError, TypeError ):
636 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800637 # add submitted intents not in the store
638 tmplist = [ i for i, s in intentStates ]
639 for i in intentIds:
640 if i not in tmplist:
641 intentStates.append( ( i, " - " ) )
642 intentStates.sort()
643 for i, s in intentStates:
644 count += 1
645 main.log.info( "%-6s%-15s%-15s" %
646 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700647 leaders = main.ONOScli1.leaders()
648 try:
Jon Hallafa8a472015-06-12 14:02:42 -0700649 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700650 if leaders:
651 parsedLeaders = json.loads( leaders )
652 main.log.warn( json.dumps( parsedLeaders,
653 sort_keys=True,
654 indent=4,
655 separators=( ',', ': ' ) ) )
656 # check for all intent partitions
657 # check for election
658 topics = []
659 for i in range( 14 ):
660 topics.append( "intent-partition-" + str( i ) )
661 # FIXME: this should only be after we start the app
662 topics.append( "org.onosproject.election" )
663 main.log.debug( topics )
664 ONOStopics = [ j['topic'] for j in parsedLeaders ]
665 for topic in topics:
666 if topic not in ONOStopics:
667 main.log.error( "Error: " + topic +
668 " not in leaders" )
Jon Hallafa8a472015-06-12 14:02:42 -0700669 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700670 else:
671 main.log.error( "leaders() returned None" )
672 except ( ValueError, TypeError ):
673 main.log.exception( "Error parsing leaders" )
674 main.log.error( repr( leaders ) )
Jon Hallafa8a472015-06-12 14:02:42 -0700675 # Check all nodes
676 if missing:
677 response = main.ONOScli1.leaders( jsonFormat=False)
678 main.log.warn( "ONOS1 leaders output: \n" +
679 str( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700680 partitions = main.ONOScli1.partitions()
681 try:
682 if partitions :
683 parsedPartitions = json.loads( partitions )
684 main.log.warn( json.dumps( parsedPartitions,
685 sort_keys=True,
686 indent=4,
687 separators=( ',', ': ' ) ) )
688 # TODO check for a leader in all paritions
689 # TODO check for consistency among nodes
690 else:
691 main.log.error( "partitions() returned None" )
692 except ( ValueError, TypeError ):
693 main.log.exception( "Error parsing partitions" )
694 main.log.error( repr( partitions ) )
695 pendingMap = main.ONOScli1.pendingMap()
696 try:
697 if pendingMap :
698 parsedPending = json.loads( pendingMap )
699 main.log.warn( json.dumps( parsedPending,
700 sort_keys=True,
701 indent=4,
702 separators=( ',', ': ' ) ) )
703 # TODO check something here?
704 else:
705 main.log.error( "pendingMap() returned None" )
706 except ( ValueError, TypeError ):
707 main.log.exception( "Error parsing pending map" )
708 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800709
Jon Hall6aec96b2015-01-19 14:49:31 -0800710 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800711 """
712 Ping across added host intents
713 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800714 import json
Jon Halla9d26da2015-03-30 16:45:32 -0700715 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700716 assert numControllers, "numControllers not defined"
717 assert main, "main not defined"
718 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700719 main.case( "Verify connectivity by sendind traffic across Intents" )
720 main.caseExplaination = "Ping across added host intents to check " +\
721 "functionality and check the state of " +\
722 "the intent"
723 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800724 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800725 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800726 ping = main.Mininet1.pingHost( src="h" + str( i ),
727 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800728 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800729 if ping == main.FALSE:
730 main.log.warn( "Ping failed between h" + str( i ) +
731 " and h" + str( i + 10 ) )
732 elif ping == main.TRUE:
733 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800734 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800735 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700736 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800737 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800738 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700739 main.log.warn( "ONOS1 intents: " )
740 try:
741 tmpIntents = main.ONOScli1.intents()
742 main.log.warn( json.dumps( json.loads( tmpIntents ),
743 sort_keys=True,
744 indent=4,
745 separators=( ',', ': ' ) ) )
746 except ( ValueError, TypeError ):
747 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800748 utilities.assert_equals(
749 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800750 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800751 onpass="Intents have been installed correctly and pings work",
752 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800753
Jon Hallfeff3082015-05-19 10:23:26 -0700754 main.step( "Check Intent state" )
Jon Hall63604932015-02-26 17:09:50 -0800755 installedCheck = True
Jon Hallfeff3082015-05-19 10:23:26 -0700756 # Print the intent states
757 intents = main.ONOScli1.intents()
758 intentStates = []
759 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
760 count = 0
761 # Iter through intents of a node
762 try:
763 for intent in json.loads( intents ):
764 state = intent.get( 'state', None )
765 if "INSTALLED" not in state:
766 installedCheck = False
767 intentId = intent.get( 'id', None )
768 intentStates.append( ( intentId, state ) )
769 except ( ValueError, TypeError ):
770 main.log.exception( "Error parsing intents." )
771 # Print states
772 intentStates.sort()
773 for i, s in intentStates:
774 count += 1
775 main.log.info( "%-6s%-15s%-15s" %
776 ( str( count ), str( i ), str( s ) ) )
777 utilities.assert_equals( expect=True, actual=installedCheck,
778 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700779 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700780 "INSTALLED state" )
781
782 main.step( "Check leadership of topics" )
783 leaders = main.ONOScli1.leaders()
784 topicCheck = main.TRUE
785 try:
786 if leaders:
787 parsedLeaders = json.loads( leaders )
788 main.log.warn( json.dumps( parsedLeaders,
789 sort_keys=True,
790 indent=4,
791 separators=( ',', ': ' ) ) )
792 # check for all intent partitions
793 # check for election
794 # TODO: Look at Devices as topics now that it uses this system
795 topics = []
796 for i in range( 14 ):
797 topics.append( "intent-partition-" + str( i ) )
798 # FIXME: this should only be after we start the app
799 # FIXME: topics.append( "org.onosproject.election" )
800 # Print leaders output
801 main.log.debug( topics )
802 ONOStopics = [ j['topic'] for j in parsedLeaders ]
803 for topic in topics:
804 if topic not in ONOStopics:
805 main.log.error( "Error: " + topic +
806 " not in leaders" )
807 topicCheck = main.FALSE
808 else:
809 main.log.error( "leaders() returned None" )
810 topicCheck = main.FALSE
811 except ( ValueError, TypeError ):
812 topicCheck = main.FALSE
813 main.log.exception( "Error parsing leaders" )
814 main.log.error( repr( leaders ) )
815 # TODO: Check for a leader of these topics
816 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
817 onpass="intent Partitions is in leaders",
818 onfail="Some topics were lost " )
819 # Print partitions
820 partitions = main.ONOScli1.partitions()
821 try:
822 if partitions :
823 parsedPartitions = json.loads( partitions )
824 main.log.warn( json.dumps( parsedPartitions,
825 sort_keys=True,
826 indent=4,
827 separators=( ',', ': ' ) ) )
828 # TODO check for a leader in all paritions
829 # TODO check for consistency among nodes
830 else:
831 main.log.error( "partitions() returned None" )
832 except ( ValueError, TypeError ):
833 main.log.exception( "Error parsing partitions" )
834 main.log.error( repr( partitions ) )
835 # Print Pending Map
836 pendingMap = main.ONOScli1.pendingMap()
837 try:
838 if pendingMap :
839 parsedPending = json.loads( pendingMap )
840 main.log.warn( json.dumps( parsedPending,
841 sort_keys=True,
842 indent=4,
843 separators=( ',', ': ' ) ) )
844 # TODO check something here?
845 else:
846 main.log.error( "pendingMap() returned None" )
847 except ( ValueError, TypeError ):
848 main.log.exception( "Error parsing pending map" )
849 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700850
Jon Hall63604932015-02-26 17:09:50 -0800851 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700852 main.log.info( "Waiting 60 seconds to see if the state of " +
853 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800854 time.sleep( 60 )
855 # Print the intent states
856 intents = main.ONOScli1.intents()
857 intentStates = []
858 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
859 count = 0
860 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700861 try:
862 for intent in json.loads( intents ):
863 state = intent.get( 'state', None )
864 if "INSTALLED" not in state:
865 installedCheck = False
866 intentId = intent.get( 'id', None )
867 intentStates.append( ( intentId, state ) )
868 except ( ValueError, TypeError ):
869 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800870 intentStates.sort()
871 for i, s in intentStates:
872 count += 1
873 main.log.info( "%-6s%-15s%-15s" %
874 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700875 leaders = main.ONOScli1.leaders()
876 try:
Jon Hallafa8a472015-06-12 14:02:42 -0700877 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700878 if leaders:
879 parsedLeaders = json.loads( leaders )
880 main.log.warn( json.dumps( parsedLeaders,
881 sort_keys=True,
882 indent=4,
883 separators=( ',', ': ' ) ) )
884 # check for all intent partitions
885 # check for election
886 topics = []
887 for i in range( 14 ):
888 topics.append( "intent-partition-" + str( i ) )
889 # FIXME: this should only be after we start the app
890 topics.append( "org.onosproject.election" )
891 main.log.debug( topics )
892 ONOStopics = [ j['topic'] for j in parsedLeaders ]
893 for topic in topics:
894 if topic not in ONOStopics:
895 main.log.error( "Error: " + topic +
896 " not in leaders" )
Jon Hallafa8a472015-06-12 14:02:42 -0700897 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700898 else:
899 main.log.error( "leaders() returned None" )
900 except ( ValueError, TypeError ):
901 main.log.exception( "Error parsing leaders" )
902 main.log.error( repr( leaders ) )
Jon Hallafa8a472015-06-12 14:02:42 -0700903 if missing:
904 response = main.ONOScli1.leaders( jsonFormat=False)
905 main.log.warn( "ONOS1 leaders output: \n" +
906 str( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700907 partitions = main.ONOScli1.partitions()
908 try:
909 if partitions :
910 parsedPartitions = json.loads( partitions )
911 main.log.warn( json.dumps( parsedPartitions,
912 sort_keys=True,
913 indent=4,
914 separators=( ',', ': ' ) ) )
915 # TODO check for a leader in all paritions
916 # TODO check for consistency among nodes
917 else:
918 main.log.error( "partitions() returned None" )
919 except ( ValueError, TypeError ):
920 main.log.exception( "Error parsing partitions" )
921 main.log.error( repr( partitions ) )
922 pendingMap = main.ONOScli1.pendingMap()
923 try:
924 if pendingMap :
925 parsedPending = json.loads( pendingMap )
926 main.log.warn( json.dumps( parsedPending,
927 sort_keys=True,
928 indent=4,
929 separators=( ',', ': ' ) ) )
930 # TODO check something here?
931 else:
932 main.log.error( "pendingMap() returned None" )
933 except ( ValueError, TypeError ):
934 main.log.exception( "Error parsing pending map" )
935 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700936 # Print flowrules
937 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -0700938 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700939 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -0700940 PingResult = main.TRUE
941 for i in range( 8, 18 ):
942 ping = main.Mininet1.pingHost( src="h" + str( i ),
943 target="h" + str( i + 10 ) )
944 PingResult = PingResult and ping
945 if ping == main.FALSE:
946 main.log.warn( "Ping failed between h" + str( i ) +
947 " and h" + str( i + 10 ) )
948 elif ping == main.TRUE:
949 main.log.info( "Ping test passed!" )
950 # Don't set PingResult or you'd override failures
951 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700952 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -0700953 "Intents have not been installed correctly, pings failed." )
954 # TODO: pretty print
955 main.log.warn( "ONOS1 intents: " )
956 try:
957 tmpIntents = main.ONOScli1.intents()
958 main.log.warn( json.dumps( json.loads( tmpIntents ),
959 sort_keys=True,
960 indent=4,
961 separators=( ',', ': ' ) ) )
962 except ( ValueError, TypeError ):
963 main.log.warn( repr( tmpIntents ) )
964 utilities.assert_equals(
965 expect=main.TRUE,
966 actual=PingResult,
967 onpass="Intents have been installed correctly and pings work",
968 onfail="Intents have not been installed correctly, pings failed." )
969
Jon Hall6aec96b2015-01-19 14:49:31 -0800970 def CASE5( self, main ):
971 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800972 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800973 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800974 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700975 assert numControllers, "numControllers not defined"
976 assert main, "main not defined"
977 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hallb87f3db2015-07-06 03:10:27 -0700978 # assumes that sts is already in you PYTHONPATH
979 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800980
Jon Hall6aec96b2015-01-19 14:49:31 -0800981 main.case( "Setting up and gathering data for current state" )
982 # The general idea for this test case is to pull the state of
983 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700984 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800985
Jon Halla9d26da2015-03-30 16:45:32 -0700986 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800987 global mastershipState
Jon Halla9d26da2015-03-30 16:45:32 -0700988 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800989
Jon Hall6aec96b2015-01-19 14:49:31 -0800990 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -0800991 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -0800992 utilities.assert_equals(
993 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800994 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800995 onpass="Each device has a master",
996 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800997
Jon Hall390696c2015-05-05 17:13:41 -0700998 main.step( "Get the Mastership of each switch" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800999 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -08001000 # TODO: Make this a meaningful check
Jon Hall8f89dda2015-01-22 16:03:33 -08001001 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001002 main.log.error( "Error in getting ONOS roles" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001003 main.log.warn(
1004 "ONOS1 mastership response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001005 repr( ONOS1Mastership ) )
1006 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001007 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001008 mastershipState = ONOS1Mastership
1009 consistentMastership = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001010
Jon Hall6aec96b2015-01-19 14:49:31 -08001011 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001012 global intentState
1013 intentState = []
1014 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1015 intentCheck = main.FALSE
1016 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001017 main.log.error( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001018 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001019 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001020 intentCheck = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001021
Jon Hall6aec96b2015-01-19 14:49:31 -08001022 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001023 global flowState
1024 flowState = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001025 flowCheck = main.FALSE
Jon Hall58c76b72015-02-23 11:09:24 -08001026 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
Jon Hall8f89dda2015-01-22 16:03:33 -08001027 if "Error" in ONOS1Flows or not ONOS1Flows:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001028 main.log.error( "Error in getting ONOS flows" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001029 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001030 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001031 # TODO: Do a better check, maybe compare flows on switches?
Jon Hall8f89dda2015-01-22 16:03:33 -08001032 flowState = ONOS1Flows
1033 flowCheck = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001034
Jon Hall6aec96b2015-01-19 14:49:31 -08001035 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001036 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001037 flows = []
1038 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001039 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001040 if flowCheck == main.FALSE:
1041 for table in flows:
1042 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001043 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001044
Jon Hall6aec96b2015-01-19 14:49:31 -08001045 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001046 devices = []
1047 devices.append( main.ONOScli1.devices() )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001048 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001049 hosts.append( json.loads( main.ONOScli1.hosts() ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001050 ports = []
1051 ports.append( main.ONOScli1.ports() )
1052 links = []
1053 links.append( main.ONOScli1.links() )
Jon Hall58c76b72015-02-23 11:09:24 -08001054 clusters = []
1055 clusters.append( main.ONOScli1.clusters() )
Jon Hall390696c2015-05-05 17:13:41 -07001056
1057 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001058 ipResult = main.TRUE
1059 for controller in range( 0, len( hosts ) ):
1060 controllerStr = str( controller + 1 )
1061 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001062 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall58c76b72015-02-23 11:09:24 -08001063 main.log.error(
1064 "DEBUG:Error with host ips on controller" +
1065 controllerStr + ": " + str( host ) )
1066 ipResult = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07001067 utilities.assert_equals(
1068 expect=main.TRUE,
1069 actual=ipResult,
1070 onpass="The ips of the hosts aren't empty",
1071 onfail="The ip of at least one host is missing" )
Jon Hall58c76b72015-02-23 11:09:24 -08001072
1073 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001074 main.step( "There is only one dataplane cluster" )
1075 try:
1076 numClusters = len( json.loads( clusters[ 0 ] ) )
1077 except ( ValueError, TypeError ):
1078 main.log.exception( "Error parsing clusters[0]: " +
1079 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001080 clusterResults = main.FALSE
1081 if numClusters == 1:
1082 clusterResults = main.TRUE
1083 utilities.assert_equals(
1084 expect=1,
1085 actual=numClusters,
1086 onpass="ONOS shows 1 SCC",
1087 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001088
Jon Hall6aec96b2015-01-19 14:49:31 -08001089 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001090 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001091 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001092 hostsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001093 mnSwitches = main.Mininet1.getSwitches()
1094 mnLinks = main.Mininet1.getLinks()
1095 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001096 for controller in range( numControllers ):
1097 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001098 if devices[ controller ] and ports[ controller ] and\
1099 "Error" not in devices[ controller ] and\
1100 "Error" not in ports[ controller ]:
1101
Jon Hall8f89dda2015-01-22 16:03:33 -08001102 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001103 mnSwitches,
1104 json.loads( devices[ controller ] ),
1105 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001106 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001107 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001109 actual=currentDevicesResult,
1110 onpass="ONOS" + controllerStr +
1111 " Switches view is correct",
1112 onfail="ONOS" + controllerStr +
1113 " Switches view is incorrect" )
Jon Hallafa8a472015-06-12 14:02:42 -07001114 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001115 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001116 mnSwitches, mnLinks,
1117 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001118 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001119 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001120 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001121 actual=currentLinksResult,
1122 onpass="ONOS" + controllerStr +
1123 " links view is correct",
1124 onfail="ONOS" + controllerStr +
1125 " links view is incorrect" )
1126
1127 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1128 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07001129 mnHosts,
1130 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08001131 else:
1132 currentHostsResult = main.FALSE
1133 utilities.assert_equals( expect=main.TRUE,
1134 actual=currentHostsResult,
1135 onpass="ONOS" + controllerStr +
1136 " hosts exist in Mininet",
1137 onfail="ONOS" + controllerStr +
1138 " hosts don't match Mininet" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001139
Jon Hall8f89dda2015-01-22 16:03:33 -08001140 devicesResults = devicesResults and currentDevicesResult
Jon Hall8f89dda2015-01-22 16:03:33 -08001141 linksResults = linksResults and currentLinksResult
Jon Hall58c76b72015-02-23 11:09:24 -08001142 hostsResults = hostsResults and currentHostsResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001143
Jon Hallafa8a472015-06-12 14:02:42 -07001144 main.step( "Device information is correct" )
1145 utilities.assert_equals(
1146 expect=main.TRUE,
1147 actual=devicesResults,
1148 onpass="Device information is correct",
1149 onfail="Device information is incorrect" )
1150
1151 main.step( "Links are correct" )
1152 utilities.assert_equals(
1153 expect=main.TRUE,
1154 actual=linksResults,
1155 onpass="Link are correct",
1156 onfail="Links are incorrect" )
1157
1158 main.step( "Hosts are correct" )
1159 utilities.assert_equals(
1160 expect=main.TRUE,
1161 actual=hostsResults,
1162 onpass="Hosts are correct",
1163 onfail="Hosts are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001164
Jon Hall6aec96b2015-01-19 14:49:31 -08001165 def CASE6( self, main ):
1166 """
Jon Hallffb386d2014-11-21 13:43:38 -08001167 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001168 """
Jon Hallffb386d2014-11-21 13:43:38 -08001169 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001170 assert numControllers, "numControllers not defined"
1171 assert main, "main not defined"
1172 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001173
Jon Hall390696c2015-05-05 17:13:41 -07001174 # Reset non-persistent variables
1175 try:
1176 iCounterValue = 0
1177 except NameError:
1178 main.log.error( "iCounterValue not defined, setting to 0" )
1179 iCounterValue = 0
1180
Jon Hallfeff3082015-05-19 10:23:26 -07001181 main.case( "Restart ONOS node" )
1182 main.caseExplaination = "Killing ONOS process and restart cli " +\
1183 "sessions once onos is up."
Jon Hall390696c2015-05-05 17:13:41 -07001184 main.step( "Killing ONOS processes" )
1185 killResult = main.ONOSbench.onosKill( ONOS1Ip )
Jon Hallffb386d2014-11-21 13:43:38 -08001186 start = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001187 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1188 onpass="ONOS Killed",
1189 onfail="Error killing ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001190
Jon Hall6aec96b2015-01-19 14:49:31 -08001191 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001192 count = 0
Jon Hall94fd0472014-12-08 11:52:42 -08001193 while count < 10:
Jon Hall8f89dda2015-01-22 16:03:33 -08001194 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
1195 if onos1Isup == main.TRUE:
Jon Hallffb386d2014-11-21 13:43:38 -08001196 elapsed = time.time() - start
1197 break
1198 else:
1199 count = count + 1
Jon Hall390696c2015-05-05 17:13:41 -07001200 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1201 onpass="ONOS is back up",
1202 onfail="ONOS failed to start" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001203
Jon Hall390696c2015-05-05 17:13:41 -07001204 main.log.step( "Starting ONOS CLI sessions" )
1205 cliResults = main.ONOScli1.startOnosCli( ONOS1Ip )
1206 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1207 onpass="ONOS cli startup successful",
1208 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001209
Jon Hallfebb1c72015-03-05 13:30:09 -08001210 if elapsed:
1211 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1212 str( elapsed ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001213 main.restartTime = elapsed
1214 else:
1215 main.restartTime = -1
Jon Hall6aec96b2015-01-19 14:49:31 -08001216 time.sleep( 5 )
Jon Hallfeff3082015-05-19 10:23:26 -07001217 # rerun on election apps
1218 main.ONOScli1.electionTestRun()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001219
Jon Hall6aec96b2015-01-19 14:49:31 -08001220 def CASE7( self, main ):
1221 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001222 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001223 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001224 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001225 assert numControllers, "numControllers not defined"
1226 assert main, "main not defined"
1227 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001228 main.case( "Running ONOS Constant State Tests" )
Jon Hall390696c2015-05-05 17:13:41 -07001229 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001230 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -08001231 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -08001232 utilities.assert_equals(
1233 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001234 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001235 onpass="Each device has a master",
1236 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001237
Jon Hall6aec96b2015-01-19 14:49:31 -08001238 main.step( "Check if switch roles are consistent across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001239 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -08001240 # FIXME: Refactor this whole case for single instance
Jon Hall8f89dda2015-01-22 16:03:33 -08001241 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001242 main.log.error( "Error in getting ONOS mastership" )
Jon Hall58c76b72015-02-23 11:09:24 -08001243 main.log.warn( "ONOS1 mastership response: " +
1244 repr( ONOS1Mastership ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001245 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001246 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001247 consistentMastership = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001248 utilities.assert_equals(
1249 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001250 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001251 onpass="Switch roles are consistent across all ONOS nodes",
1252 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001253
1254 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001255 main.step( description2 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001256
Jon Hall8f89dda2015-01-22 16:03:33 -08001257 currentJson = json.loads( ONOS1Mastership )
1258 oldJson = json.loads( mastershipState )
1259 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001260 for i in range( 1, 29 ):
1261 switchDPID = str(
Jon Hall58c76b72015-02-23 11:09:24 -08001262 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001263
Jon Hall8f89dda2015-01-22 16:03:33 -08001264 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001265 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001266 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001267 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001268 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001269 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001270 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001271 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001272 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001273 utilities.assert_equals(
1274 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001275 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001276 onpass="Mastership of Switches was not changed",
1277 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001278 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001279
Jon Hall6aec96b2015-01-19 14:49:31 -08001280 main.step( "Get the intents and compare across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001281 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1282 intentCheck = main.FALSE
1283 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001284 main.log.error( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001285 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001286 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001287 intentCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001288 utilities.assert_equals(
1289 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001290 actual=intentCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001291 onpass="Intents are consistent across all ONOS nodes",
1292 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001293 # Print the intent states
1294 intents = []
1295 intents.append( ONOS1Intents )
1296 intentStates = []
1297 for node in intents: # Iter through ONOS nodes
1298 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001299 # Iter through intents of a node
1300 for intent in json.loads( node ):
Jon Hall1b8f54a2015-02-04 13:24:20 -08001301 nodeStates.append( intent[ 'state' ] )
1302 intentStates.append( nodeStates )
1303 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1304 main.log.info( dict( out ) )
1305
Jon Hall58c76b72015-02-23 11:09:24 -08001306 # NOTE: Store has no durability, so intents are lost across system
1307 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001308 """
1309 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001310 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall6aec96b2015-01-19 14:49:31 -08001311 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001312 sameIntents = main.FALSE
1313 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001314 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001315 main.log.info( "Intents are consistent with before failure" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001316 # TODO: possibly the states have changed? we may need to figure out
Jon Hallfeff3082015-05-19 10:23:26 -07001317 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001318 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1319 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001320 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001321 before = json.loads( intentState )
1322 after = json.loads( ONOSIntents[ 0 ] )
1323 for intent in before:
1324 if intent not in after:
1325 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001326 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001327 "(at least in the same form):" )
1328 main.log.debug( json.dumps( intent ) )
1329 except ( ValueError, TypeError ):
1330 main.log.exception( "Exception printing intents" )
1331 main.log.debug( repr( ONOSIntents[0] ) )
1332 main.log.debug( repr( intentState ) )
1333 if sameIntents == main.FALSE:
1334 try:
1335 main.log.debug( "ONOS intents before: " )
1336 main.log.debug( json.dumps( json.loads( intentState ),
1337 sort_keys=True, indent=4,
1338 separators=( ',', ': ' ) ) )
1339 main.log.debug( "Current ONOS intents: " )
1340 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1341 sort_keys=True, indent=4,
1342 separators=( ',', ': ' ) ) )
1343 except ( ValueError, TypeError ):
1344 main.log.exception( "Exception printing intents" )
1345 main.log.debug( repr( ONOSIntents[0] ) )
1346 main.log.debug( repr( intentState ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001347 utilities.assert_equals(
1348 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001349 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001350 onpass="Intents are consistent with before failure",
1351 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001352 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08001353 """
1354 main.step( "Get the OF Table entries and compare to before " +
1355 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001356 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001357 flows2 = []
1358 for i in range( 28 ):
1359 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001360 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1361 flows2.append( tmpFlows )
1362 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001363 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001364 flow2=tmpFlows )
1365 FlowTables = FlowTables and tempResult
1366 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001367 main.log.info( "Differences in flow table for switch: s" +
1368 str( i + 1 ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001369 utilities.assert_equals(
1370 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001371 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001372 onpass="No changes were found in the flow tables",
1373 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001374
Jon Hallfeff3082015-05-19 10:23:26 -07001375 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001376 # Test of LeadershipElection
Jon Hall669173b2014-12-17 11:36:30 -08001377
Jon Hall8f89dda2015-01-22 16:03:33 -08001378 leader = ONOS1Ip
1379 leaderResult = main.TRUE
1380 for controller in range( 1, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001381 # loop through ONOScli handlers
1382 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001383 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001384 # verify leader is ONOS1
1385 # NOTE even though we restarted ONOS, it is the only one so onos 1
1386 # must be leader
Jon Hall669173b2014-12-17 11:36:30 -08001387 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001388 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001389 pass
1390 elif leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07001391 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07001392 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001393 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001394 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001395 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001396 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001397 leaderResult = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07001398 main.log.error( "ONOS" + str( controller ) + " sees " +
Jon Hall58c76b72015-02-23 11:09:24 -08001399 str( leaderN ) +
1400 " as the leader of the election app. " +
1401 "Leader should be " + str( leader ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001402 utilities.assert_equals(
1403 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001404 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001405 onpass="Leadership election passed",
1406 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001407
Jon Hall6aec96b2015-01-19 14:49:31 -08001408 def CASE8( self, main ):
1409 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001410 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001411 """
Jon Hallb87f3db2015-07-06 03:10:27 -07001412 import sys
1413 # FIXME add this path to params
1414 sys.path.append( "/home/admin/sts" )
1415 # assumes that sts is already in you PYTHONPATH
1416 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001417 import json
1418 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001419 assert numControllers, "numControllers not defined"
1420 assert main, "main not defined"
1421 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001422
Jon Hallfeff3082015-05-19 10:23:26 -07001423 main.case( "Compare ONOS Topology view to Mininet topology" )
1424 main.caseExplaination = "Compare topology objects between Mininet" +\
1425 " and ONOS"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001426
Jon Hall6aec96b2015-01-19 14:49:31 -08001427 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001428 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001429 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001430 hostsResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001431 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08001432 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001433 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001434 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001435 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001436 startTime = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -08001437 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001438 while topoResult == main.FALSE and elapsed < 60:
Jon Halla9d26da2015-03-30 16:45:32 -07001439 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08001440 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001441 devices = []
1442 devices.append( main.ONOScli1.devices() )
Jon Hall94fd0472014-12-08 11:52:42 -08001443 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001444 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1445 ipResult = main.TRUE
1446 for controller in range( 0, len( hosts ) ):
1447 controllerStr = str( controller + 1 )
1448 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001449 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall58c76b72015-02-23 11:09:24 -08001450 main.log.error(
1451 "DEBUG:Error with host ips on controller" +
1452 controllerStr + ": " + str( host ) )
1453 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001454 ports = []
1455 ports.append( main.ONOScli1.ports() )
1456 links = []
1457 links.append( main.ONOScli1.links() )
Jon Hall58c76b72015-02-23 11:09:24 -08001458 clusters = []
1459 clusters.append( main.ONOScli1.clusters() )
1460
Jon Hall8f89dda2015-01-22 16:03:33 -08001461 elapsed = time.time() - startTime
1462 cliTime = time.time() - cliStart
1463 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001464
Jon Hallafa8a472015-06-12 14:02:42 -07001465 mnSwitches = main.Mininet1.getSwitches()
1466 mnLinks = main.Mininet1.getLinks()
1467 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001468 for controller in range( numControllers ):
1469 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001470 if devices[ controller ] and ports[ controller ] and\
1471 "Error" not in devices[ controller ] and\
1472 "Error" not in ports[ controller ]:
1473
Jon Hall8f89dda2015-01-22 16:03:33 -08001474 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001475 mnSwitches,
1476 json.loads( devices[ controller ] ),
1477 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001478 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001479 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001480 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001481 actual=currentDevicesResult,
1482 onpass="ONOS" + controllerStr +
1483 " Switches view is correct",
1484 onfail="ONOS" + controllerStr +
1485 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001486
Jon Hallafa8a472015-06-12 14:02:42 -07001487 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001488 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001489 mnSwitches, mnLinks,
1490 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001491 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001492 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001493 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001494 actual=currentLinksResult,
1495 onpass="ONOS" + controllerStr +
1496 " links view is correct",
1497 onfail="ONOS" + controllerStr +
1498 " links view is incorrect" )
1499
1500 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1501 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07001502 mnHosts,
1503 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08001504 else:
1505 currentHostsResult = main.FALSE
1506 utilities.assert_equals( expect=main.TRUE,
1507 actual=currentHostsResult,
1508 onpass="ONOS" + controllerStr +
1509 " hosts exist in Mininet",
1510 onfail="ONOS" + controllerStr +
1511 " hosts don't match Mininet" )
Jon Hallafa8a472015-06-12 14:02:42 -07001512 # CHECKING HOST ATTACHMENT POINTS
1513 hostAttachment = True
1514 zeroHosts = False
1515 # FIXME: topo-HA/obelisk specific mappings:
1516 # key is mac and value is dpid
1517 mappings = {}
1518 for i in range( 1, 29 ): # hosts 1 through 28
1519 # set up correct variables:
1520 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1521 if i == 1:
1522 deviceId = "1000".zfill(16)
1523 elif i == 2:
1524 deviceId = "2000".zfill(16)
1525 elif i == 3:
1526 deviceId = "3000".zfill(16)
1527 elif i == 4:
1528 deviceId = "3004".zfill(16)
1529 elif i == 5:
1530 deviceId = "5000".zfill(16)
1531 elif i == 6:
1532 deviceId = "6000".zfill(16)
1533 elif i == 7:
1534 deviceId = "6007".zfill(16)
1535 elif i >= 8 and i <= 17:
1536 dpid = '3' + str( i ).zfill( 3 )
1537 deviceId = dpid.zfill(16)
1538 elif i >= 18 and i <= 27:
1539 dpid = '6' + str( i ).zfill( 3 )
1540 deviceId = dpid.zfill(16)
1541 elif i == 28:
1542 deviceId = "2800".zfill(16)
1543 mappings[ macId ] = deviceId
1544 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1545 if hosts[ controller ] == []:
1546 main.log.warn( "There are no hosts discovered" )
1547 zeroHosts = True
1548 else:
1549 for host in hosts[ controller ]:
1550 mac = None
1551 location = None
1552 device = None
1553 port = None
1554 try:
1555 mac = host.get( 'mac' )
1556 assert mac, "mac field could not be found for this host object"
1557
1558 location = host.get( 'location' )
1559 assert location, "location field could not be found for this host object"
1560
1561 # Trim the protocol identifier off deviceId
1562 device = str( location.get( 'elementId' ) ).split(':')[1]
1563 assert device, "elementId field could not be found for this host location object"
1564
1565 port = location.get( 'port' )
1566 assert port, "port field could not be found for this host location object"
1567
1568 # Now check if this matches where they should be
1569 if mac and device and port:
1570 if str( port ) != "1":
1571 main.log.error( "The attachment port is incorrect for " +
1572 "host " + str( mac ) +
1573 ". Expected: 1 Actual: " + str( port) )
1574 hostAttachment = False
1575 if device != mappings[ str( mac ) ]:
1576 main.log.error( "The attachment device is incorrect for " +
1577 "host " + str( mac ) +
1578 ". Expected: " + mappings[ str( mac ) ] +
1579 " Actual: " + device )
1580 hostAttachment = False
1581 else:
1582 hostAttachment = False
1583 except AssertionError:
1584 main.log.exception( "Json object not as expected" )
1585 main.log.error( repr( host ) )
1586 hostAttachment = False
1587 else:
1588 main.log.error( "No hosts json output or \"Error\"" +
1589 " in output. hosts = " +
1590 repr( hosts[ controller ] ) )
1591 if zeroHosts is False:
1592 hostAttachment = True
1593
Jon Hall58c76b72015-02-23 11:09:24 -08001594
1595 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08001596 linksResults = linksResults and currentLinksResult
1597 hostsResults = hostsResults and currentHostsResult
Jon Hallafa8a472015-06-12 14:02:42 -07001598 hostAttachmentResults = hostAttachmentResults and\
1599 hostAttachment
Jon Hall58c76b72015-02-23 11:09:24 -08001600
Jon Hall63604932015-02-26 17:09:50 -08001601 # "consistent" results don't make sense for single instance
Jon Hall58c76b72015-02-23 11:09:24 -08001602 # there should always only be one cluster
1603 numClusters = len( json.loads( clusters[ 0 ] ) )
1604 clusterResults = main.FALSE
1605 if numClusters == 1:
1606 clusterResults = main.TRUE
1607 utilities.assert_equals(
1608 expect=1,
1609 actual=numClusters,
1610 onpass="ONOS shows 1 SCC",
1611 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1612
Jon Hallafa8a472015-06-12 14:02:42 -07001613 topoResult = ( devicesResults and linksResults
1614 and hostsResults and ipResult and clusterResults and
1615 hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08001616
Jon Hall8f89dda2015-01-22 16:03:33 -08001617 topoResult = topoResult and int( count <= 2 )
1618 note = "note it takes about " + str( int( cliTime ) ) + \
1619 " seconds for the test to make all the cli calls to fetch " +\
1620 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08001621 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08001622 "Very crass estimate for topology discovery/convergence( " +
1623 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001624 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001625 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001626 onpass="Topology Check Test successful",
1627 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001628
Jon Hall6aec96b2015-01-19 14:49:31 -08001629 def CASE9( self, main ):
1630 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001631 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 """
1633 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001634 assert numControllers, "numControllers not defined"
1635 assert main, "main not defined"
1636 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001637 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001638
Jon Hall8f89dda2015-01-22 16:03:33 -08001639 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001640
Jon Hall6aec96b2015-01-19 14:49:31 -08001641 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08001642 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001643 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001644
Jon Hall6aec96b2015-01-19 14:49:31 -08001645 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001646 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08001647 main.log.info( "Waiting " + str( linkSleep ) +
1648 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001649 time.sleep( linkSleep )
1650 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Halla9d26da2015-03-30 16:45:32 -07001651 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08001652 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001653 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08001654
Jon Hall6aec96b2015-01-19 14:49:31 -08001655 def CASE10( self, main ):
1656 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001657 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08001658 """
1659 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001660 assert numControllers, "numControllers not defined"
1661 assert main, "main not defined"
1662 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001663 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001664
Jon Hall8f89dda2015-01-22 16:03:33 -08001665 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001666
Jon Hall6aec96b2015-01-19 14:49:31 -08001667 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall58c76b72015-02-23 11:09:24 -08001668 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001669 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001670
Jon Hall6aec96b2015-01-19 14:49:31 -08001671 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001672 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08001673 main.log.info( "Waiting " + str( linkSleep ) +
1674 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001675 time.sleep( linkSleep )
1676 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Halla9d26da2015-03-30 16:45:32 -07001677 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08001678 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001679 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08001680
Jon Hall6aec96b2015-01-19 14:49:31 -08001681 def CASE11( self, main ):
1682 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001683 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08001684 """
1685 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001686 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001687 assert numControllers, "numControllers not defined"
1688 assert main, "main not defined"
1689 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001690
Jon Hall8f89dda2015-01-22 16:03:33 -08001691 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001692
1693 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001694 main.case( description )
1695 switch = main.params[ 'kill' ][ 'switch' ]
1696 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001697
Jon Hall6aec96b2015-01-19 14:49:31 -08001698 # TODO: Make this switch parameterizable
1699 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001700 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08001701 main.Mininet1.delSwitch( switch )
1702 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001703 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001704 time.sleep( switchSleep )
1705 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001706 # Peek at the deleted switch
1707 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001708 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08001710 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001711 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Halla9d26da2015-03-30 16:45:32 -07001712 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08001713 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001714
Jon Hall6aec96b2015-01-19 14:49:31 -08001715 def CASE12( self, main ):
1716 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001717 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08001718 """
1719 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001720 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001721 assert numControllers, "numControllers not defined"
1722 assert main, "main not defined"
1723 assert utilities.assert_equals, "utilities.assert_equals not defined"
1724 assert ONOS1Port, "ONOS1Port not defined"
1725 assert ONOS2Port, "ONOS2Port not defined"
1726 assert ONOS3Port, "ONOS3Port not defined"
1727 assert ONOS4Port, "ONOS4Port not defined"
1728 assert ONOS5Port, "ONOS5Port not defined"
1729 assert ONOS6Port, "ONOS6Port not defined"
1730 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08001731
Jon Hall8f89dda2015-01-22 16:03:33 -08001732 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08001733 switch = main.params[ 'kill' ][ 'switch' ]
1734 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1735 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001736 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001737 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001738
Jon Hall6aec96b2015-01-19 14:49:31 -08001739 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08001740 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001741 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08001742 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07001743 ipList = []
1744 for i in range( numControllers ):
1745 ipList.append( nodes[ i ].ip_address )
1746 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08001747 main.log.info( "Waiting " + str( switchSleep ) +
1748 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001749 time.sleep( switchSleep )
1750 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001751 # Peek at the deleted switch
1752 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001753 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001755 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001756 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Halla9d26da2015-03-30 16:45:32 -07001757 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08001758 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001759
Jon Hall6aec96b2015-01-19 14:49:31 -08001760 def CASE13( self, main ):
1761 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001762 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08001763 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001764 import os
1765 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001766 assert numControllers, "numControllers not defined"
1767 assert main, "main not defined"
1768 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001769 # printing colors to terminal
Jon Halla9d26da2015-03-30 16:45:32 -07001770 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1771 'blue': '\033[94m', 'green': '\033[92m',
1772 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07001773 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001774 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001775 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001776
Jon Hall6aec96b2015-01-19 14:49:31 -08001777 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001778 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08001779 teststationUser = main.params[ 'TESTONUSER' ]
1780 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001781 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08001782 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08001783 # FIXME: scp
1784 # mn files
1785 # TODO: Load these from params
1786 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001787 logFolder = "/opt/onos/log/"
1788 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001789 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001790 dstDir = "~/packet_captures/"
1791 for f in logFiles:
1792 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
1793 logFolder + f + " " +
1794 teststationUser + "@" +
1795 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001796 str( testname ) + "-ONOS1-" + f )
1797 main.ONOSbench.handle.expect( "\$" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001798
Jon Hall6aec96b2015-01-19 14:49:31 -08001799 # std*.log's
1800 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001801 logFolder = "/opt/onos/var/"
1802 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001803 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001804 dstDir = "~/packet_captures/"
1805 for f in logFiles:
1806 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
1807 logFolder + f + " " +
1808 teststationUser + "@" +
1809 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001810 str( testname ) + "-ONOS1-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08001811 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001812 # sleep so scp can finish
1813 time.sleep( 10 )
Jon Halla9d26da2015-03-30 16:45:32 -07001814
1815 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07001816 mnResult = main.Mininet1.stopNet()
1817 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
1818 onpass="Mininet stopped",
1819 onfail="MN cleanup NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07001820
1821 main.step( "Checking ONOS Logs for errors" )
1822 print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
1823 colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07001824 print main.ONOSbench.checkLogs( ONOS1Ip, restart=True )
Jon Halla9d26da2015-03-30 16:45:32 -07001825
Jon Hall6aec96b2015-01-19 14:49:31 -08001826 main.step( "Packing and rotating pcap archives" )
1827 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001828
Jon Hall40d2cbd2015-06-03 16:24:29 -07001829 try:
1830 timerLog = open( main.logdir + "/Timers.csv", 'w')
1831 # Overwrite with empty line and close
1832 labels = "Gossip Intents, Restart"
1833 data = str( gossipTime ) + ", " + str( main.restartTime )
1834 timerLog.write( labels + "\n" + data )
1835 timerLog.close()
1836 except NameError, e:
1837 main.log.exception(e)
1838
Jon Hall6aec96b2015-01-19 14:49:31 -08001839 def CASE14( self, main ):
1840 """
Jon Hall669173b2014-12-17 11:36:30 -08001841 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08001842 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07001843 assert numControllers, "numControllers not defined"
1844 assert main, "main not defined"
1845 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halla9d26da2015-03-30 16:45:32 -07001846
Jon Hall390696c2015-05-05 17:13:41 -07001847 main.case("Start Leadership Election app")
1848 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07001849 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
1850 utilities.assert_equals(
1851 expect=main.TRUE,
1852 actual=appResult,
1853 onpass="Election app installed",
1854 onfail="Something went wrong with installing Leadership election" )
1855
1856 main.step( "Run for election on each node" )
1857 leaderResult = main.ONOScli1.electionTestRun()
Jon Hall6aec96b2015-01-19 14:49:31 -08001858 # check for leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001859 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001860 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001861 if leader == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001862 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001863 pass
Jon Hall6aec96b2015-01-19 14:49:31 -08001864 elif leader is None:
1865 # No leader elected
Jon Hallfeff3082015-05-19 10:23:26 -07001866 main.log.error( "No leader was elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001868 elif leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001869 # error in response
1870 # TODO: add check for "Command not found:" in the driver, this
1871 # means the app isn't loaded
Jon Hallfeff3082015-05-19 10:23:26 -07001872 main.log.error( "Something is wrong with electionTestLeader" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001873 " function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001874 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001875 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001876 # error in response
Jon Hallfeff3082015-05-19 10:23:26 -07001877 main.log.error(
Jon Hall8f89dda2015-01-22 16:03:33 -08001878 "Unexpected response from electionTestLeader function:'" +
1879 str( leader ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001880 "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001881 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001882 utilities.assert_equals(
1883 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001884 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07001885 onpass="Successfully ran for leadership",
1886 onfail="Failed to run for leadership" )
Jon Hall669173b2014-12-17 11:36:30 -08001887
Jon Hall6aec96b2015-01-19 14:49:31 -08001888 def CASE15( self, main ):
1889 """
Jon Hall669173b2014-12-17 11:36:30 -08001890 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08001891 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07001892 assert numControllers, "numControllers not defined"
1893 assert main, "main not defined"
1894 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Hall8f89dda2015-01-22 16:03:33 -08001895 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001896 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08001897 main.case( description )
1898 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001899 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07001900 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 withdrawResult = main.FALSE
1902 if leader == ONOS1Ip:
1903 oldLeader = getattr( main, "ONOScli1" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001904 elif leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001905 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08001906 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08001907 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001908 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08001909 oldLeader = None
1910 else:
1911 main.log.error( "Leader election --- why am I HERE?!?")
Jon Hallfeff3082015-05-19 10:23:26 -07001912 leaderResult = main.FALSE
1913 oldLeader = None
Jon Hall63604932015-02-26 17:09:50 -08001914 if oldLeader:
1915 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08001916 utilities.assert_equals(
1917 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001918 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07001919 onpass="Node was withdrawn from election",
1920 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08001921
Jon Hall6aec96b2015-01-19 14:49:31 -08001922 main.step( "Make sure new leader is elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001923 leaderN = main.ONOScli1.electionTestLeader()
Jon Hall669173b2014-12-17 11:36:30 -08001924 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001925 main.log.error( "ONOS still sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001926 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001927 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001928 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001929 # error in response
1930 # TODO: add check for "Command not found:" in the driver, this
1931 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07001932 main.log.error( "Something is wrong with electionTestLeader " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001933 "function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001934 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001935 elif leaderN is None:
1936 main.log.info(
1937 "There is no leader after the app withdrew from election" )
Jon Hallfeff3082015-05-19 10:23:26 -07001938 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 utilities.assert_equals(
1940 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001941 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001942 onpass="Leadership election passed",
1943 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001944
Jon Hall58c76b72015-02-23 11:09:24 -08001945 main.step( "Run for election on old leader( just so everyone " +
1946 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08001947 if oldLeader:
1948 runResult = oldLeader.electionTestRun()
1949 else:
1950 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001951 utilities.assert_equals(
1952 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001953 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001954 onpass="App re-ran for election",
1955 onfail="App failed to run for election" )
Jon Hallfeff3082015-05-19 10:23:26 -07001956
1957 main.step( "Node became leader when it ran for election" )
1958 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001959 # verify leader is ONOS1
Jon Hallfeff3082015-05-19 10:23:26 -07001960 if afterRun == ONOS1Ip:
1961 afterResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001962 else:
Jon Hallfeff3082015-05-19 10:23:26 -07001963 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001964
Jon Hall6aec96b2015-01-19 14:49:31 -08001965 utilities.assert_equals(
1966 expect=main.TRUE,
Jon Hallfeff3082015-05-19 10:23:26 -07001967 actual=afterResult,
1968 onpass="Old leader successfully re-ran for election",
1969 onfail="Something went wrong with Leadership election after " +
1970 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07001971
1972 def CASE16( self, main ):
1973 """
1974 Install Distributed Primitives app
1975 """
1976 assert numControllers, "numControllers not defined"
1977 assert main, "main not defined"
1978 assert utilities.assert_equals, "utilities.assert_equals not defined"
1979 assert CLIs, "CLIs not defined"
1980 assert nodes, "nodes not defined"
1981
1982 # Variables for the distributed primitives tests
1983 global pCounterName
1984 global iCounterName
1985 global pCounterValue
1986 global iCounterValue
1987 global onosSet
1988 global onosSetName
1989 pCounterName = "TestON-Partitions"
1990 iCounterName = "TestON-inMemory"
1991 pCounterValue = 0
1992 iCounterValue = 0
1993 onosSet = set([])
1994 onosSetName = "TestON-set"
1995
1996 description = "Install Primitives app"
1997 main.case( description )
1998 main.step( "Install Primitives app" )
1999 appName = "org.onosproject.distributedprimitives"
2000 appResults = CLIs[0].activateApp( appName )
2001 utilities.assert_equals( expect=main.TRUE,
2002 actual=appResults,
2003 onpass="Primitives app activated",
2004 onfail="Primitives app not activated" )
2005
2006 def CASE17( self, main ):
2007 """
2008 Check for basic functionality with distributed primitives
2009 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002010 import json
Jon Hall390696c2015-05-05 17:13:41 -07002011 # Make sure variables are defined/set
2012 assert numControllers, "numControllers not defined"
2013 assert main, "main not defined"
2014 assert utilities.assert_equals, "utilities.assert_equals not defined"
2015 assert CLIs, "CLIs not defined"
2016 assert nodes, "nodes not defined"
2017 assert pCounterName, "pCounterName not defined"
2018 assert iCounterName, "iCounterName not defined"
2019 assert onosSetName, "onosSetName not defined"
2020 # NOTE: assert fails if value is 0/None/Empty/False
2021 try:
2022 pCounterValue
2023 except NameError:
2024 main.log.error( "pCounterValue not defined, setting to 0" )
2025 pCounterValue = 0
2026 try:
2027 iCounterValue
2028 except NameError:
2029 main.log.error( "iCounterValue not defined, setting to 0" )
2030 iCounterValue = 0
2031 try:
2032 onosSet
2033 except NameError:
2034 main.log.error( "onosSet not defined, setting to empty Set" )
2035 onosSet = set([])
2036 # Variables for the distributed primitives tests. These are local only
2037 addValue = "a"
2038 addAllValue = "a b c d e f"
2039 retainValue = "c d e f"
2040
2041 description = "Check for basic functionality with distributed " +\
2042 "primitives"
2043 main.case( description )
2044 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2045 # DISTRIBUTED ATOMIC COUNTERS
2046 main.step( "Increment and get a default counter on each node" )
2047 pCounters = []
2048 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002049 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002050 for i in range( numControllers ):
2051 t = main.Thread( target=CLIs[i].counterTestIncrement,
2052 name="counterIncrement-" + str( i ),
2053 args=[ pCounterName ] )
2054 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002055 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002056 threads.append( t )
2057 t.start()
2058
2059 for t in threads:
2060 t.join()
2061 pCounters.append( t.result )
2062 # Check that counter incremented numController times
2063 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002064 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002065 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002066 pCounterResults = pCounterResults and tmpResult
2067 if not tmpResult:
2068 main.log.error( str( i ) + " is not in partitioned "
2069 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002070 utilities.assert_equals( expect=True,
2071 actual=pCounterResults,
2072 onpass="Default counter incremented",
2073 onfail="Error incrementing default" +
2074 " counter" )
2075
2076 main.step( "Increment and get an in memory counter on each node" )
2077 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002078 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002079 threads = []
2080 for i in range( numControllers ):
2081 t = main.Thread( target=CLIs[i].counterTestIncrement,
2082 name="icounterIncrement-" + str( i ),
2083 args=[ iCounterName ],
2084 kwargs={ "inMemory": True } )
2085 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002086 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002087 threads.append( t )
2088 t.start()
2089
2090 for t in threads:
2091 t.join()
2092 iCounters.append( t.result )
2093 # Check that counter incremented numController times
2094 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002095 for i in addedIValues:
2096 tmpResult = i in iCounters
2097 iCounterResults = iCounterResults and tmpResult
2098 if not tmpResult:
2099 main.log.error( str( i ) + " is not in the in-memory "
2100 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002101 utilities.assert_equals( expect=True,
2102 actual=iCounterResults,
2103 onpass="In memory counter incremented",
2104 onfail="Error incrementing in memory" +
2105 " counter" )
2106
2107 main.step( "Check counters are consistant across nodes" )
2108 onosCounters = []
2109 threads = []
2110 for i in range( numControllers ):
2111 t = main.Thread( target=CLIs[i].counters,
2112 name="counters-" + str( i ) )
2113 threads.append( t )
2114 t.start()
2115 for t in threads:
2116 t.join()
2117 onosCounters.append( t.result )
2118 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2119 if all( tmp ):
2120 main.log.info( "Counters are consistent across all nodes" )
2121 consistentCounterResults = main.TRUE
2122 else:
2123 main.log.error( "Counters are not consistent across all nodes" )
2124 consistentCounterResults = main.FALSE
2125 utilities.assert_equals( expect=main.TRUE,
2126 actual=consistentCounterResults,
2127 onpass="ONOS counters are consistent " +
2128 "across nodes",
2129 onfail="ONOS Counters are inconsistent " +
2130 "across nodes" )
2131
2132 main.step( "Counters we added have the correct values" )
2133 correctResults = main.TRUE
2134 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002135 current = json.loads( onosCounters[i] )
2136 pValue = None
2137 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07002138 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002139 for database in current:
2140 partitioned = database.get( 'partitionedDatabaseCounters' )
2141 if partitioned:
2142 for value in partitioned:
2143 if value.get( 'name' ) == pCounterName:
2144 pValue = value.get( 'value' )
2145 break
2146 inMemory = database.get( 'inMemoryDatabaseCounters' )
2147 if inMemory:
2148 for value in inMemory:
2149 if value.get( 'name' ) == iCounterName:
2150 iValue = value.get( 'value' )
2151 break
Jon Hall390696c2015-05-05 17:13:41 -07002152 except AttributeError, e:
2153 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2154 "is not as expected" )
2155 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07002156 if pValue == pCounterValue:
2157 main.log.info( "Partitioned counter value is correct" )
2158 else:
2159 main.log.error( "Partitioned counter value is incorrect," +
2160 " expected value: " + str( pCounterValue )
2161 + " current value: " + str( pValue ) )
2162 correctResults = main.FALSE
2163 if iValue == iCounterValue:
2164 main.log.info( "In memory counter value is correct" )
2165 else:
2166 main.log.error( "In memory counter value is incorrect, " +
2167 "expected value: " + str( iCounterValue ) +
2168 " current value: " + str( iValue ) )
2169 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07002170 utilities.assert_equals( expect=main.TRUE,
2171 actual=correctResults,
2172 onpass="Added counters are correct",
2173 onfail="Added counters are incorrect" )
2174 # DISTRIBUTED SETS
2175 main.step( "Distributed Set get" )
2176 size = len( onosSet )
2177 getResponses = []
2178 threads = []
2179 for i in range( numControllers ):
2180 t = main.Thread( target=CLIs[i].setTestGet,
2181 name="setTestGet-" + str( i ),
2182 args=[ onosSetName ] )
2183 threads.append( t )
2184 t.start()
2185 for t in threads:
2186 t.join()
2187 getResponses.append( t.result )
2188
2189 getResults = main.TRUE
2190 for i in range( numControllers ):
2191 if isinstance( getResponses[ i ], list):
2192 current = set( getResponses[ i ] )
2193 if len( current ) == len( getResponses[ i ] ):
2194 # no repeats
2195 if onosSet != current:
2196 main.log.error( "ONOS" + str( i + 1 ) +
2197 " has incorrect view" +
2198 " of set " + onosSetName + ":\n" +
2199 str( getResponses[ i ] ) )
2200 main.log.debug( "Expected: " + str( onosSet ) )
2201 main.log.debug( "Actual: " + str( current ) )
2202 getResults = main.FALSE
2203 else:
2204 # error, set is not a set
2205 main.log.error( "ONOS" + str( i + 1 ) +
2206 " has repeat elements in" +
2207 " set " + onosSetName + ":\n" +
2208 str( getResponses[ i ] ) )
2209 getResults = main.FALSE
2210 elif getResponses[ i ] == main.ERROR:
2211 getResults = main.FALSE
2212 utilities.assert_equals( expect=main.TRUE,
2213 actual=getResults,
2214 onpass="Set elements are correct",
2215 onfail="Set elements are incorrect" )
2216
2217 main.step( "Distributed Set size" )
2218 sizeResponses = []
2219 threads = []
2220 for i in range( numControllers ):
2221 t = main.Thread( target=CLIs[i].setTestSize,
2222 name="setTestSize-" + str( i ),
2223 args=[ onosSetName ] )
2224 threads.append( t )
2225 t.start()
2226 for t in threads:
2227 t.join()
2228 sizeResponses.append( t.result )
2229
2230 sizeResults = main.TRUE
2231 for i in range( numControllers ):
2232 if size != sizeResponses[ i ]:
2233 sizeResults = main.FALSE
2234 main.log.error( "ONOS" + str( i + 1 ) +
2235 " expected a size of " + str( size ) +
2236 " for set " + onosSetName +
2237 " but got " + str( sizeResponses[ i ] ) )
2238 utilities.assert_equals( expect=main.TRUE,
2239 actual=sizeResults,
2240 onpass="Set sizes are correct",
2241 onfail="Set sizes are incorrect" )
2242
2243 main.step( "Distributed Set add()" )
2244 onosSet.add( addValue )
2245 addResponses = []
2246 threads = []
2247 for i in range( numControllers ):
2248 t = main.Thread( target=CLIs[i].setTestAdd,
2249 name="setTestAdd-" + str( i ),
2250 args=[ onosSetName, addValue ] )
2251 threads.append( t )
2252 t.start()
2253 for t in threads:
2254 t.join()
2255 addResponses.append( t.result )
2256
2257 # main.TRUE = successfully changed the set
2258 # main.FALSE = action resulted in no change in set
2259 # main.ERROR - Some error in executing the function
2260 addResults = main.TRUE
2261 for i in range( numControllers ):
2262 if addResponses[ i ] == main.TRUE:
2263 # All is well
2264 pass
2265 elif addResponses[ i ] == main.FALSE:
2266 # Already in set, probably fine
2267 pass
2268 elif addResponses[ i ] == main.ERROR:
2269 # Error in execution
2270 addResults = main.FALSE
2271 else:
2272 # unexpected result
2273 addResults = main.FALSE
2274 if addResults != main.TRUE:
2275 main.log.error( "Error executing set add" )
2276
2277 # Check if set is still correct
2278 size = len( onosSet )
2279 getResponses = []
2280 threads = []
2281 for i in range( numControllers ):
2282 t = main.Thread( target=CLIs[i].setTestGet,
2283 name="setTestGet-" + str( i ),
2284 args=[ onosSetName ] )
2285 threads.append( t )
2286 t.start()
2287 for t in threads:
2288 t.join()
2289 getResponses.append( t.result )
2290 getResults = main.TRUE
2291 for i in range( numControllers ):
2292 if isinstance( getResponses[ i ], list):
2293 current = set( getResponses[ i ] )
2294 if len( current ) == len( getResponses[ i ] ):
2295 # no repeats
2296 if onosSet != current:
2297 main.log.error( "ONOS" + str( i + 1 ) +
2298 " has incorrect view" +
2299 " of set " + onosSetName + ":\n" +
2300 str( getResponses[ i ] ) )
2301 main.log.debug( "Expected: " + str( onosSet ) )
2302 main.log.debug( "Actual: " + str( current ) )
2303 getResults = main.FALSE
2304 else:
2305 # error, set is not a set
2306 main.log.error( "ONOS" + str( i + 1 ) +
2307 " has repeat elements in" +
2308 " set " + onosSetName + ":\n" +
2309 str( getResponses[ i ] ) )
2310 getResults = main.FALSE
2311 elif getResponses[ i ] == main.ERROR:
2312 getResults = main.FALSE
2313 sizeResponses = []
2314 threads = []
2315 for i in range( numControllers ):
2316 t = main.Thread( target=CLIs[i].setTestSize,
2317 name="setTestSize-" + str( i ),
2318 args=[ onosSetName ] )
2319 threads.append( t )
2320 t.start()
2321 for t in threads:
2322 t.join()
2323 sizeResponses.append( t.result )
2324 sizeResults = main.TRUE
2325 for i in range( numControllers ):
2326 if size != sizeResponses[ i ]:
2327 sizeResults = main.FALSE
2328 main.log.error( "ONOS" + str( i + 1 ) +
2329 " expected a size of " + str( size ) +
2330 " for set " + onosSetName +
2331 " but got " + str( sizeResponses[ i ] ) )
2332 addResults = addResults and getResults and sizeResults
2333 utilities.assert_equals( expect=main.TRUE,
2334 actual=addResults,
2335 onpass="Set add correct",
2336 onfail="Set add was incorrect" )
2337
2338 main.step( "Distributed Set addAll()" )
2339 onosSet.update( addAllValue.split() )
2340 addResponses = []
2341 threads = []
2342 for i in range( numControllers ):
2343 t = main.Thread( target=CLIs[i].setTestAdd,
2344 name="setTestAddAll-" + str( i ),
2345 args=[ onosSetName, addAllValue ] )
2346 threads.append( t )
2347 t.start()
2348 for t in threads:
2349 t.join()
2350 addResponses.append( t.result )
2351
2352 # main.TRUE = successfully changed the set
2353 # main.FALSE = action resulted in no change in set
2354 # main.ERROR - Some error in executing the function
2355 addAllResults = main.TRUE
2356 for i in range( numControllers ):
2357 if addResponses[ i ] == main.TRUE:
2358 # All is well
2359 pass
2360 elif addResponses[ i ] == main.FALSE:
2361 # Already in set, probably fine
2362 pass
2363 elif addResponses[ i ] == main.ERROR:
2364 # Error in execution
2365 addAllResults = main.FALSE
2366 else:
2367 # unexpected result
2368 addAllResults = main.FALSE
2369 if addAllResults != main.TRUE:
2370 main.log.error( "Error executing set addAll" )
2371
2372 # Check if set is still correct
2373 size = len( onosSet )
2374 getResponses = []
2375 threads = []
2376 for i in range( numControllers ):
2377 t = main.Thread( target=CLIs[i].setTestGet,
2378 name="setTestGet-" + str( i ),
2379 args=[ onosSetName ] )
2380 threads.append( t )
2381 t.start()
2382 for t in threads:
2383 t.join()
2384 getResponses.append( t.result )
2385 getResults = main.TRUE
2386 for i in range( numControllers ):
2387 if isinstance( getResponses[ i ], list):
2388 current = set( getResponses[ i ] )
2389 if len( current ) == len( getResponses[ i ] ):
2390 # no repeats
2391 if onosSet != current:
2392 main.log.error( "ONOS" + str( i + 1 ) +
2393 " has incorrect view" +
2394 " of set " + onosSetName + ":\n" +
2395 str( getResponses[ i ] ) )
2396 main.log.debug( "Expected: " + str( onosSet ) )
2397 main.log.debug( "Actual: " + str( current ) )
2398 getResults = main.FALSE
2399 else:
2400 # error, set is not a set
2401 main.log.error( "ONOS" + str( i + 1 ) +
2402 " has repeat elements in" +
2403 " set " + onosSetName + ":\n" +
2404 str( getResponses[ i ] ) )
2405 getResults = main.FALSE
2406 elif getResponses[ i ] == main.ERROR:
2407 getResults = main.FALSE
2408 sizeResponses = []
2409 threads = []
2410 for i in range( numControllers ):
2411 t = main.Thread( target=CLIs[i].setTestSize,
2412 name="setTestSize-" + str( i ),
2413 args=[ onosSetName ] )
2414 threads.append( t )
2415 t.start()
2416 for t in threads:
2417 t.join()
2418 sizeResponses.append( t.result )
2419 sizeResults = main.TRUE
2420 for i in range( numControllers ):
2421 if size != sizeResponses[ i ]:
2422 sizeResults = main.FALSE
2423 main.log.error( "ONOS" + str( i + 1 ) +
2424 " expected a size of " + str( size ) +
2425 " for set " + onosSetName +
2426 " but got " + str( sizeResponses[ i ] ) )
2427 addAllResults = addAllResults and getResults and sizeResults
2428 utilities.assert_equals( expect=main.TRUE,
2429 actual=addAllResults,
2430 onpass="Set addAll correct",
2431 onfail="Set addAll was incorrect" )
2432
2433 main.step( "Distributed Set contains()" )
2434 containsResponses = []
2435 threads = []
2436 for i in range( numControllers ):
2437 t = main.Thread( target=CLIs[i].setTestGet,
2438 name="setContains-" + str( i ),
2439 args=[ onosSetName ],
2440 kwargs={ "values": addValue } )
2441 threads.append( t )
2442 t.start()
2443 for t in threads:
2444 t.join()
2445 # NOTE: This is the tuple
2446 containsResponses.append( t.result )
2447
2448 containsResults = main.TRUE
2449 for i in range( numControllers ):
2450 if containsResponses[ i ] == main.ERROR:
2451 containsResults = main.FALSE
2452 else:
2453 containsResults = containsResults and\
2454 containsResponses[ i ][ 1 ]
2455 utilities.assert_equals( expect=main.TRUE,
2456 actual=containsResults,
2457 onpass="Set contains is functional",
2458 onfail="Set contains failed" )
2459
2460 main.step( "Distributed Set containsAll()" )
2461 containsAllResponses = []
2462 threads = []
2463 for i in range( numControllers ):
2464 t = main.Thread( target=CLIs[i].setTestGet,
2465 name="setContainsAll-" + str( i ),
2466 args=[ onosSetName ],
2467 kwargs={ "values": addAllValue } )
2468 threads.append( t )
2469 t.start()
2470 for t in threads:
2471 t.join()
2472 # NOTE: This is the tuple
2473 containsAllResponses.append( t.result )
2474
2475 containsAllResults = main.TRUE
2476 for i in range( numControllers ):
2477 if containsResponses[ i ] == main.ERROR:
2478 containsResults = main.FALSE
2479 else:
2480 containsResults = containsResults and\
2481 containsResponses[ i ][ 1 ]
2482 utilities.assert_equals( expect=main.TRUE,
2483 actual=containsAllResults,
2484 onpass="Set containsAll is functional",
2485 onfail="Set containsAll failed" )
2486
2487 main.step( "Distributed Set remove()" )
2488 onosSet.remove( addValue )
2489 removeResponses = []
2490 threads = []
2491 for i in range( numControllers ):
2492 t = main.Thread( target=CLIs[i].setTestRemove,
2493 name="setTestRemove-" + str( i ),
2494 args=[ onosSetName, addValue ] )
2495 threads.append( t )
2496 t.start()
2497 for t in threads:
2498 t.join()
2499 removeResponses.append( t.result )
2500
2501 # main.TRUE = successfully changed the set
2502 # main.FALSE = action resulted in no change in set
2503 # main.ERROR - Some error in executing the function
2504 removeResults = main.TRUE
2505 for i in range( numControllers ):
2506 if removeResponses[ i ] == main.TRUE:
2507 # All is well
2508 pass
2509 elif removeResponses[ i ] == main.FALSE:
2510 # not in set, probably fine
2511 pass
2512 elif removeResponses[ i ] == main.ERROR:
2513 # Error in execution
2514 removeResults = main.FALSE
2515 else:
2516 # unexpected result
2517 removeResults = main.FALSE
2518 if removeResults != main.TRUE:
2519 main.log.error( "Error executing set remove" )
2520
2521 # Check if set is still correct
2522 size = len( onosSet )
2523 getResponses = []
2524 threads = []
2525 for i in range( numControllers ):
2526 t = main.Thread( target=CLIs[i].setTestGet,
2527 name="setTestGet-" + str( i ),
2528 args=[ onosSetName ] )
2529 threads.append( t )
2530 t.start()
2531 for t in threads:
2532 t.join()
2533 getResponses.append( t.result )
2534 getResults = main.TRUE
2535 for i in range( numControllers ):
2536 if isinstance( getResponses[ i ], list):
2537 current = set( getResponses[ i ] )
2538 if len( current ) == len( getResponses[ i ] ):
2539 # no repeats
2540 if onosSet != current:
2541 main.log.error( "ONOS" + str( i + 1 ) +
2542 " has incorrect view" +
2543 " of set " + onosSetName + ":\n" +
2544 str( getResponses[ i ] ) )
2545 main.log.debug( "Expected: " + str( onosSet ) )
2546 main.log.debug( "Actual: " + str( current ) )
2547 getResults = main.FALSE
2548 else:
2549 # error, set is not a set
2550 main.log.error( "ONOS" + str( i + 1 ) +
2551 " has repeat elements in" +
2552 " set " + onosSetName + ":\n" +
2553 str( getResponses[ i ] ) )
2554 getResults = main.FALSE
2555 elif getResponses[ i ] == main.ERROR:
2556 getResults = main.FALSE
2557 sizeResponses = []
2558 threads = []
2559 for i in range( numControllers ):
2560 t = main.Thread( target=CLIs[i].setTestSize,
2561 name="setTestSize-" + str( i ),
2562 args=[ onosSetName ] )
2563 threads.append( t )
2564 t.start()
2565 for t in threads:
2566 t.join()
2567 sizeResponses.append( t.result )
2568 sizeResults = main.TRUE
2569 for i in range( numControllers ):
2570 if size != sizeResponses[ i ]:
2571 sizeResults = main.FALSE
2572 main.log.error( "ONOS" + str( i + 1 ) +
2573 " expected a size of " + str( size ) +
2574 " for set " + onosSetName +
2575 " but got " + str( sizeResponses[ i ] ) )
2576 removeResults = removeResults and getResults and sizeResults
2577 utilities.assert_equals( expect=main.TRUE,
2578 actual=removeResults,
2579 onpass="Set remove correct",
2580 onfail="Set remove was incorrect" )
2581
2582 main.step( "Distributed Set removeAll()" )
2583 onosSet.difference_update( addAllValue.split() )
2584 removeAllResponses = []
2585 threads = []
2586 try:
2587 for i in range( numControllers ):
2588 t = main.Thread( target=CLIs[i].setTestRemove,
2589 name="setTestRemoveAll-" + str( i ),
2590 args=[ onosSetName, addAllValue ] )
2591 threads.append( t )
2592 t.start()
2593 for t in threads:
2594 t.join()
2595 removeAllResponses.append( t.result )
2596 except Exception, e:
2597 main.log.exception(e)
2598
2599 # main.TRUE = successfully changed the set
2600 # main.FALSE = action resulted in no change in set
2601 # main.ERROR - Some error in executing the function
2602 removeAllResults = main.TRUE
2603 for i in range( numControllers ):
2604 if removeAllResponses[ i ] == main.TRUE:
2605 # All is well
2606 pass
2607 elif removeAllResponses[ i ] == main.FALSE:
2608 # not in set, probably fine
2609 pass
2610 elif removeAllResponses[ i ] == main.ERROR:
2611 # Error in execution
2612 removeAllResults = main.FALSE
2613 else:
2614 # unexpected result
2615 removeAllResults = main.FALSE
2616 if removeAllResults != main.TRUE:
2617 main.log.error( "Error executing set removeAll" )
2618
2619 # Check if set is still correct
2620 size = len( onosSet )
2621 getResponses = []
2622 threads = []
2623 for i in range( numControllers ):
2624 t = main.Thread( target=CLIs[i].setTestGet,
2625 name="setTestGet-" + str( i ),
2626 args=[ onosSetName ] )
2627 threads.append( t )
2628 t.start()
2629 for t in threads:
2630 t.join()
2631 getResponses.append( t.result )
2632 getResults = main.TRUE
2633 for i in range( numControllers ):
2634 if isinstance( getResponses[ i ], list):
2635 current = set( getResponses[ i ] )
2636 if len( current ) == len( getResponses[ i ] ):
2637 # no repeats
2638 if onosSet != current:
2639 main.log.error( "ONOS" + str( i + 1 ) +
2640 " has incorrect view" +
2641 " of set " + onosSetName + ":\n" +
2642 str( getResponses[ i ] ) )
2643 main.log.debug( "Expected: " + str( onosSet ) )
2644 main.log.debug( "Actual: " + str( current ) )
2645 getResults = main.FALSE
2646 else:
2647 # error, set is not a set
2648 main.log.error( "ONOS" + str( i + 1 ) +
2649 " has repeat elements in" +
2650 " set " + onosSetName + ":\n" +
2651 str( getResponses[ i ] ) )
2652 getResults = main.FALSE
2653 elif getResponses[ i ] == main.ERROR:
2654 getResults = main.FALSE
2655 sizeResponses = []
2656 threads = []
2657 for i in range( numControllers ):
2658 t = main.Thread( target=CLIs[i].setTestSize,
2659 name="setTestSize-" + str( i ),
2660 args=[ onosSetName ] )
2661 threads.append( t )
2662 t.start()
2663 for t in threads:
2664 t.join()
2665 sizeResponses.append( t.result )
2666 sizeResults = main.TRUE
2667 for i in range( numControllers ):
2668 if size != sizeResponses[ i ]:
2669 sizeResults = main.FALSE
2670 main.log.error( "ONOS" + str( i + 1 ) +
2671 " expected a size of " + str( size ) +
2672 " for set " + onosSetName +
2673 " but got " + str( sizeResponses[ i ] ) )
2674 removeAllResults = removeAllResults and getResults and sizeResults
2675 utilities.assert_equals( expect=main.TRUE,
2676 actual=removeAllResults,
2677 onpass="Set removeAll correct",
2678 onfail="Set removeAll was incorrect" )
2679
2680 main.step( "Distributed Set addAll()" )
2681 onosSet.update( addAllValue.split() )
2682 addResponses = []
2683 threads = []
2684 for i in range( numControllers ):
2685 t = main.Thread( target=CLIs[i].setTestAdd,
2686 name="setTestAddAll-" + str( i ),
2687 args=[ onosSetName, addAllValue ] )
2688 threads.append( t )
2689 t.start()
2690 for t in threads:
2691 t.join()
2692 addResponses.append( t.result )
2693
2694 # main.TRUE = successfully changed the set
2695 # main.FALSE = action resulted in no change in set
2696 # main.ERROR - Some error in executing the function
2697 addAllResults = main.TRUE
2698 for i in range( numControllers ):
2699 if addResponses[ i ] == main.TRUE:
2700 # All is well
2701 pass
2702 elif addResponses[ i ] == main.FALSE:
2703 # Already in set, probably fine
2704 pass
2705 elif addResponses[ i ] == main.ERROR:
2706 # Error in execution
2707 addAllResults = main.FALSE
2708 else:
2709 # unexpected result
2710 addAllResults = main.FALSE
2711 if addAllResults != main.TRUE:
2712 main.log.error( "Error executing set addAll" )
2713
2714 # Check if set is still correct
2715 size = len( onosSet )
2716 getResponses = []
2717 threads = []
2718 for i in range( numControllers ):
2719 t = main.Thread( target=CLIs[i].setTestGet,
2720 name="setTestGet-" + str( i ),
2721 args=[ onosSetName ] )
2722 threads.append( t )
2723 t.start()
2724 for t in threads:
2725 t.join()
2726 getResponses.append( t.result )
2727 getResults = main.TRUE
2728 for i in range( numControllers ):
2729 if isinstance( getResponses[ i ], list):
2730 current = set( getResponses[ i ] )
2731 if len( current ) == len( getResponses[ i ] ):
2732 # no repeats
2733 if onosSet != current:
2734 main.log.error( "ONOS" + str( i + 1 ) +
2735 " has incorrect view" +
2736 " of set " + onosSetName + ":\n" +
2737 str( getResponses[ i ] ) )
2738 main.log.debug( "Expected: " + str( onosSet ) )
2739 main.log.debug( "Actual: " + str( current ) )
2740 getResults = main.FALSE
2741 else:
2742 # error, set is not a set
2743 main.log.error( "ONOS" + str( i + 1 ) +
2744 " has repeat elements in" +
2745 " set " + onosSetName + ":\n" +
2746 str( getResponses[ i ] ) )
2747 getResults = main.FALSE
2748 elif getResponses[ i ] == main.ERROR:
2749 getResults = main.FALSE
2750 sizeResponses = []
2751 threads = []
2752 for i in range( numControllers ):
2753 t = main.Thread( target=CLIs[i].setTestSize,
2754 name="setTestSize-" + str( i ),
2755 args=[ onosSetName ] )
2756 threads.append( t )
2757 t.start()
2758 for t in threads:
2759 t.join()
2760 sizeResponses.append( t.result )
2761 sizeResults = main.TRUE
2762 for i in range( numControllers ):
2763 if size != sizeResponses[ i ]:
2764 sizeResults = main.FALSE
2765 main.log.error( "ONOS" + str( i + 1 ) +
2766 " expected a size of " + str( size ) +
2767 " for set " + onosSetName +
2768 " but got " + str( sizeResponses[ i ] ) )
2769 addAllResults = addAllResults and getResults and sizeResults
2770 utilities.assert_equals( expect=main.TRUE,
2771 actual=addAllResults,
2772 onpass="Set addAll correct",
2773 onfail="Set addAll was incorrect" )
2774
2775 main.step( "Distributed Set clear()" )
2776 onosSet.clear()
2777 clearResponses = []
2778 threads = []
2779 for i in range( numControllers ):
2780 t = main.Thread( target=CLIs[i].setTestRemove,
2781 name="setTestClear-" + str( i ),
2782 args=[ onosSetName, " "], # Values doesn't matter
2783 kwargs={ "clear": True } )
2784 threads.append( t )
2785 t.start()
2786 for t in threads:
2787 t.join()
2788 clearResponses.append( t.result )
2789
2790 # main.TRUE = successfully changed the set
2791 # main.FALSE = action resulted in no change in set
2792 # main.ERROR - Some error in executing the function
2793 clearResults = main.TRUE
2794 for i in range( numControllers ):
2795 if clearResponses[ i ] == main.TRUE:
2796 # All is well
2797 pass
2798 elif clearResponses[ i ] == main.FALSE:
2799 # Nothing set, probably fine
2800 pass
2801 elif clearResponses[ i ] == main.ERROR:
2802 # Error in execution
2803 clearResults = main.FALSE
2804 else:
2805 # unexpected result
2806 clearResults = main.FALSE
2807 if clearResults != main.TRUE:
2808 main.log.error( "Error executing set clear" )
2809
2810 # Check if set is still correct
2811 size = len( onosSet )
2812 getResponses = []
2813 threads = []
2814 for i in range( numControllers ):
2815 t = main.Thread( target=CLIs[i].setTestGet,
2816 name="setTestGet-" + str( i ),
2817 args=[ onosSetName ] )
2818 threads.append( t )
2819 t.start()
2820 for t in threads:
2821 t.join()
2822 getResponses.append( t.result )
2823 getResults = main.TRUE
2824 for i in range( numControllers ):
2825 if isinstance( getResponses[ i ], list):
2826 current = set( getResponses[ i ] )
2827 if len( current ) == len( getResponses[ i ] ):
2828 # no repeats
2829 if onosSet != current:
2830 main.log.error( "ONOS" + str( i + 1 ) +
2831 " has incorrect view" +
2832 " of set " + onosSetName + ":\n" +
2833 str( getResponses[ i ] ) )
2834 main.log.debug( "Expected: " + str( onosSet ) )
2835 main.log.debug( "Actual: " + str( current ) )
2836 getResults = main.FALSE
2837 else:
2838 # error, set is not a set
2839 main.log.error( "ONOS" + str( i + 1 ) +
2840 " has repeat elements in" +
2841 " set " + onosSetName + ":\n" +
2842 str( getResponses[ i ] ) )
2843 getResults = main.FALSE
2844 elif getResponses[ i ] == main.ERROR:
2845 getResults = main.FALSE
2846 sizeResponses = []
2847 threads = []
2848 for i in range( numControllers ):
2849 t = main.Thread( target=CLIs[i].setTestSize,
2850 name="setTestSize-" + str( i ),
2851 args=[ onosSetName ] )
2852 threads.append( t )
2853 t.start()
2854 for t in threads:
2855 t.join()
2856 sizeResponses.append( t.result )
2857 sizeResults = main.TRUE
2858 for i in range( numControllers ):
2859 if size != sizeResponses[ i ]:
2860 sizeResults = main.FALSE
2861 main.log.error( "ONOS" + str( i + 1 ) +
2862 " expected a size of " + str( size ) +
2863 " for set " + onosSetName +
2864 " but got " + str( sizeResponses[ i ] ) )
2865 clearResults = clearResults and getResults and sizeResults
2866 utilities.assert_equals( expect=main.TRUE,
2867 actual=clearResults,
2868 onpass="Set clear correct",
2869 onfail="Set clear was incorrect" )
2870
2871 main.step( "Distributed Set addAll()" )
2872 onosSet.update( addAllValue.split() )
2873 addResponses = []
2874 threads = []
2875 for i in range( numControllers ):
2876 t = main.Thread( target=CLIs[i].setTestAdd,
2877 name="setTestAddAll-" + str( i ),
2878 args=[ onosSetName, addAllValue ] )
2879 threads.append( t )
2880 t.start()
2881 for t in threads:
2882 t.join()
2883 addResponses.append( t.result )
2884
2885 # main.TRUE = successfully changed the set
2886 # main.FALSE = action resulted in no change in set
2887 # main.ERROR - Some error in executing the function
2888 addAllResults = main.TRUE
2889 for i in range( numControllers ):
2890 if addResponses[ i ] == main.TRUE:
2891 # All is well
2892 pass
2893 elif addResponses[ i ] == main.FALSE:
2894 # Already in set, probably fine
2895 pass
2896 elif addResponses[ i ] == main.ERROR:
2897 # Error in execution
2898 addAllResults = main.FALSE
2899 else:
2900 # unexpected result
2901 addAllResults = main.FALSE
2902 if addAllResults != main.TRUE:
2903 main.log.error( "Error executing set addAll" )
2904
2905 # Check if set is still correct
2906 size = len( onosSet )
2907 getResponses = []
2908 threads = []
2909 for i in range( numControllers ):
2910 t = main.Thread( target=CLIs[i].setTestGet,
2911 name="setTestGet-" + str( i ),
2912 args=[ onosSetName ] )
2913 threads.append( t )
2914 t.start()
2915 for t in threads:
2916 t.join()
2917 getResponses.append( t.result )
2918 getResults = main.TRUE
2919 for i in range( numControllers ):
2920 if isinstance( getResponses[ i ], list):
2921 current = set( getResponses[ i ] )
2922 if len( current ) == len( getResponses[ i ] ):
2923 # no repeats
2924 if onosSet != current:
2925 main.log.error( "ONOS" + str( i + 1 ) +
2926 " has incorrect view" +
2927 " of set " + onosSetName + ":\n" +
2928 str( getResponses[ i ] ) )
2929 main.log.debug( "Expected: " + str( onosSet ) )
2930 main.log.debug( "Actual: " + str( current ) )
2931 getResults = main.FALSE
2932 else:
2933 # error, set is not a set
2934 main.log.error( "ONOS" + str( i + 1 ) +
2935 " has repeat elements in" +
2936 " set " + onosSetName + ":\n" +
2937 str( getResponses[ i ] ) )
2938 getResults = main.FALSE
2939 elif getResponses[ i ] == main.ERROR:
2940 getResults = main.FALSE
2941 sizeResponses = []
2942 threads = []
2943 for i in range( numControllers ):
2944 t = main.Thread( target=CLIs[i].setTestSize,
2945 name="setTestSize-" + str( i ),
2946 args=[ onosSetName ] )
2947 threads.append( t )
2948 t.start()
2949 for t in threads:
2950 t.join()
2951 sizeResponses.append( t.result )
2952 sizeResults = main.TRUE
2953 for i in range( numControllers ):
2954 if size != sizeResponses[ i ]:
2955 sizeResults = main.FALSE
2956 main.log.error( "ONOS" + str( i + 1 ) +
2957 " expected a size of " + str( size ) +
2958 " for set " + onosSetName +
2959 " but got " + str( sizeResponses[ i ] ) )
2960 addAllResults = addAllResults and getResults and sizeResults
2961 utilities.assert_equals( expect=main.TRUE,
2962 actual=addAllResults,
2963 onpass="Set addAll correct",
2964 onfail="Set addAll was incorrect" )
2965
2966 main.step( "Distributed Set retain()" )
2967 onosSet.intersection_update( retainValue.split() )
2968 retainResponses = []
2969 threads = []
2970 for i in range( numControllers ):
2971 t = main.Thread( target=CLIs[i].setTestRemove,
2972 name="setTestRetain-" + str( i ),
2973 args=[ onosSetName, retainValue ],
2974 kwargs={ "retain": True } )
2975 threads.append( t )
2976 t.start()
2977 for t in threads:
2978 t.join()
2979 retainResponses.append( t.result )
2980
2981 # main.TRUE = successfully changed the set
2982 # main.FALSE = action resulted in no change in set
2983 # main.ERROR - Some error in executing the function
2984 retainResults = main.TRUE
2985 for i in range( numControllers ):
2986 if retainResponses[ i ] == main.TRUE:
2987 # All is well
2988 pass
2989 elif retainResponses[ i ] == main.FALSE:
2990 # Already in set, probably fine
2991 pass
2992 elif retainResponses[ i ] == main.ERROR:
2993 # Error in execution
2994 retainResults = main.FALSE
2995 else:
2996 # unexpected result
2997 retainResults = main.FALSE
2998 if retainResults != main.TRUE:
2999 main.log.error( "Error executing set retain" )
3000
3001 # Check if set is still correct
3002 size = len( onosSet )
3003 getResponses = []
3004 threads = []
3005 for i in range( numControllers ):
3006 t = main.Thread( target=CLIs[i].setTestGet,
3007 name="setTestGet-" + str( i ),
3008 args=[ onosSetName ] )
3009 threads.append( t )
3010 t.start()
3011 for t in threads:
3012 t.join()
3013 getResponses.append( t.result )
3014 getResults = main.TRUE
3015 for i in range( numControllers ):
3016 if isinstance( getResponses[ i ], list):
3017 current = set( getResponses[ i ] )
3018 if len( current ) == len( getResponses[ i ] ):
3019 # no repeats
3020 if onosSet != current:
3021 main.log.error( "ONOS" + str( i + 1 ) +
3022 " has incorrect view" +
3023 " of set " + onosSetName + ":\n" +
3024 str( getResponses[ i ] ) )
3025 main.log.debug( "Expected: " + str( onosSet ) )
3026 main.log.debug( "Actual: " + str( current ) )
3027 getResults = main.FALSE
3028 else:
3029 # error, set is not a set
3030 main.log.error( "ONOS" + str( i + 1 ) +
3031 " has repeat elements in" +
3032 " set " + onosSetName + ":\n" +
3033 str( getResponses[ i ] ) )
3034 getResults = main.FALSE
3035 elif getResponses[ i ] == main.ERROR:
3036 getResults = main.FALSE
3037 sizeResponses = []
3038 threads = []
3039 for i in range( numControllers ):
3040 t = main.Thread( target=CLIs[i].setTestSize,
3041 name="setTestSize-" + str( i ),
3042 args=[ onosSetName ] )
3043 threads.append( t )
3044 t.start()
3045 for t in threads:
3046 t.join()
3047 sizeResponses.append( t.result )
3048 sizeResults = main.TRUE
3049 for i in range( numControllers ):
3050 if size != sizeResponses[ i ]:
3051 sizeResults = main.FALSE
3052 main.log.error( "ONOS" + str( i + 1 ) +
3053 " expected a size of " +
3054 str( size ) + " for set " + onosSetName +
3055 " but got " + str( sizeResponses[ i ] ) )
3056 retainResults = retainResults and getResults and sizeResults
3057 utilities.assert_equals( expect=main.TRUE,
3058 actual=retainResults,
3059 onpass="Set retain correct",
3060 onfail="Set retain was incorrect" )
3061