blob: e68ecda335d66341b484f55b6a0fef91910879a4 [file] [log] [blame]
Jon Hall85794ff2015-07-08 14:12:30 -07001"""
2Description: 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
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: 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
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
Jon Hall85794ff2015-07-08 14:12:30 -070025class HAsingleInstanceRestart:
26
27 def __init__( self ):
28 self.default = ''
29
30 def CASE1( self, main ):
31 """
32 CASE1 is to compile ONOS and push it to the test machines
33
34 Startup sequence:
35 cell <name>
36 onos-verify-cell
37 NOTE: temporary - onos-remove-raft-logs
38 onos-uninstall
39 start mininet
40 git pull
41 mvn clean install
42 onos-package
43 onos-install -f
44 onos-wait-for-start
45 start cli sessions
46 start tcpdump
47 """
Jon Halle1a3b752015-07-22 13:02:46 -070048 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080049 import time
Jon Halla440e872016-03-31 15:15:50 -070050 import json
Jon Hall85794ff2015-07-08 14:12:30 -070051 main.log.info( "ONOS Single node cluster restart " +
52 "HA test - initialization" )
53 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070054 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -070055 "installing ONOS, starting Mininet and ONOS" +\
56 "cli sessions."
Jon Hall85794ff2015-07-08 14:12:30 -070057
58 # load some variables from the params file
59 PULLCODE = False
60 if main.params[ 'Git' ] == 'True':
61 PULLCODE = True
62 gitBranch = main.params[ 'branch' ]
63 cellName = main.params[ 'ENV' ][ 'cellName' ]
64
Jon Halle1a3b752015-07-22 13:02:46 -070065 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070066 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070067 if main.ONOSbench.maxNodes < main.numCtrls:
68 main.numCtrls = int( main.ONOSbench.maxNodes )
Jon Hall85794ff2015-07-08 14:12:30 -070069
Jon Halle1a3b752015-07-22 13:02:46 -070070 try:
Jon Hall53c5e662016-04-13 16:06:56 -070071 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070072 main.HA = HA()
Jon Halle1a3b752015-07-22 13:02:46 -070073 except Exception as e:
74 main.log.exception( e )
75 main.cleanup()
76 main.exit()
77
78 main.CLIs = []
79 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070080 ipList = []
81 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
82 try:
Jon Halle1a3b752015-07-22 13:02:46 -070083 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
84 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
85 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -070086 except AttributeError:
87 break
Jon Hall85794ff2015-07-08 14:12:30 -070088
Jon Hall5cf14d52015-07-16 12:15:19 -070089 main.step( "Create cell file" )
90 cellAppString = main.params[ 'ENV' ][ 'appString' ]
91 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
92 main.Mininet1.ip_address,
Devin Lim461f0872017-06-05 16:49:33 -070093 cellAppString, ipList, main.ONOScli1.user_name )
Jon Hall85794ff2015-07-08 14:12:30 -070094 main.step( "Applying cell variable to environment" )
95 cellResult = main.ONOSbench.setCell( cellName )
96 verifyResult = main.ONOSbench.verifyCell()
97
98 # FIXME:this is short term fix
99 main.log.info( "Removing raft logs" )
100 main.ONOSbench.onosRemoveRaftLogs()
101
102 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700103 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700104 main.ONOSbench.onosUninstall( node.ip_address )
105
106 # Make sure ONOS is DEAD
107 main.log.info( "Killing any ONOS processes" )
108 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700109 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700110 killed = main.ONOSbench.onosKill( node.ip_address )
111 killResults = killResults and killed
112
113 cleanInstallResult = main.TRUE
114 gitPullResult = main.TRUE
115
116 main.step( "Starting Mininet" )
117 # scp topo file to mininet
118 # TODO: move to params?
119 topoName = "obelisk.py"
120 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700121 main.ONOSbench.scp( main.Mininet1,
122 filePath + topoName,
123 main.Mininet1.home,
124 direction="to" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700125 mnResult = main.Mininet1.startNet()
Jon Hall85794ff2015-07-08 14:12:30 -0700126 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
127 onpass="Mininet Started",
128 onfail="Error starting Mininet" )
129
130 main.step( "Git checkout and pull " + gitBranch )
131 if PULLCODE:
132 main.ONOSbench.gitCheckout( gitBranch )
133 gitPullResult = main.ONOSbench.gitPull()
134 # values of 1 or 3 are good
135 utilities.assert_lesser( expect=0, actual=gitPullResult,
136 onpass="Git pull successful",
137 onfail="Git pull failed" )
138 main.ONOSbench.getVersion( report=True )
139
140 main.step( "Using mvn clean install" )
141 cleanInstallResult = main.TRUE
142 if PULLCODE and gitPullResult == main.TRUE:
143 cleanInstallResult = main.ONOSbench.cleanInstall()
144 else:
145 main.log.warn( "Did not pull new code so skipping mvn " +
146 "clean install" )
147 utilities.assert_equals( expect=main.TRUE,
148 actual=cleanInstallResult,
149 onpass="MCI successful",
150 onfail="MCI failed" )
151 # GRAPHS
152 # NOTE: important params here:
153 # job = name of Jenkins job
154 # Plot Name = Plot-HA, only can be used if multiple plots
155 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700156 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700157 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700158 index = "2"
Jon Hall85794ff2015-07-08 14:12:30 -0700159 graphs = '<ac:structured-macro ac:name="html">\n'
160 graphs += '<ac:plain-text-body><![CDATA[\n'
161 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800162 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall85794ff2015-07-08 14:12:30 -0700163 '&width=500&height=300"' +\
164 'noborder="0" width="500" height="300" scrolling="yes" ' +\
165 'seamless="seamless"></iframe>\n'
166 graphs += ']]></ac:plain-text-body>\n'
167 graphs += '</ac:structured-macro>\n'
Jon Hallf37d44d2017-05-24 10:37:30 -0700168 main.log.wiki( graphs )
Jon Hall85794ff2015-07-08 14:12:30 -0700169
Jon Halle1a3b752015-07-22 13:02:46 -0700170 main.CLIs = []
171 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700172 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700173 for i in range( 1, main.numCtrls + 1 ):
174 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
175 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
176 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700177
178 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
179 main.Mininet1.ip_address,
Devin Lim461f0872017-06-05 16:49:33 -0700180 cellAppString, ipList[ 0 ], main.ONOScli1.user_name )
Jon Hall85794ff2015-07-08 14:12:30 -0700181 cellResult = main.ONOSbench.setCell( "SingleHA" )
182 verifyResult = main.ONOSbench.verifyCell()
183 main.step( "Creating ONOS package" )
Jon Hallbd60ea02016-08-23 10:03:59 -0700184 packageResult = main.ONOSbench.buckBuild()
Jon Hall85794ff2015-07-08 14:12:30 -0700185 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
186 onpass="ONOS package successful",
187 onfail="ONOS package failed" )
188
189 main.step( "Installing ONOS package" )
Jon Halla440e872016-03-31 15:15:50 -0700190 onosInstallResult = main.TRUE
191 for node in main.nodes:
192 tmpResult = main.ONOSbench.onosInstall( options="-f",
193 node=node.ip_address )
194 onosInstallResult = onosInstallResult and tmpResult
Jon Hall85794ff2015-07-08 14:12:30 -0700195 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
196 onpass="ONOS install successful",
197 onfail="ONOS install failed" )
198
You Wangf5de25b2017-01-06 15:13:01 -0800199 main.step( "Set up ONOS secure SSH" )
200 secureSshResult = main.TRUE
201 for node in main.nodes:
202 secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
203 utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
204 onpass="Test step PASS",
205 onfail="Test step FAIL" )
206
Jon Hall85794ff2015-07-08 14:12:30 -0700207 main.step( "Checking if ONOS is up yet" )
208 for i in range( 2 ):
Jon Halla440e872016-03-31 15:15:50 -0700209 onosIsupResult = main.TRUE
210 for node in main.nodes:
211 started = main.ONOSbench.isup( node.ip_address )
212 if not started:
213 main.log.error( node.name + " hasn't started" )
214 onosIsupResult = onosIsupResult and started
215 if onosIsupResult == main.TRUE:
Jon Hall85794ff2015-07-08 14:12:30 -0700216 break
Jon Halla440e872016-03-31 15:15:50 -0700217 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
Jon Hall85794ff2015-07-08 14:12:30 -0700218 onpass="ONOS startup successful",
219 onfail="ONOS startup failed" )
220
Jon Hall6509dbf2016-06-21 17:01:17 -0700221 main.step( "Starting ONOS CLI sessions" )
Jon Halla440e872016-03-31 15:15:50 -0700222 cliResults = main.TRUE
223 threads = []
224 for i in range( main.numCtrls ):
Jon Hallf37d44d2017-05-24 10:37:30 -0700225 t = main.Thread( target=main.CLIs[ i ].startOnosCli,
Jon Halla440e872016-03-31 15:15:50 -0700226 name="startOnosCli-" + str( i ),
Jon Hallf37d44d2017-05-24 10:37:30 -0700227 args=[ main.nodes[ i ].ip_address ] )
Jon Halla440e872016-03-31 15:15:50 -0700228 threads.append( t )
229 t.start()
230
231 for t in threads:
232 t.join()
233 cliResults = cliResults and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700234 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
235 onpass="ONOS cli startup successful",
236 onfail="ONOS cli startup failed" )
237
Jon Halla440e872016-03-31 15:15:50 -0700238 # Create a list of active nodes for use when some nodes are stopped
239 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
240
Jon Hall85794ff2015-07-08 14:12:30 -0700241 if main.params[ 'tcpdump' ].lower() == "true":
242 main.step( "Start Packet Capture MN" )
243 main.Mininet2.startTcpdump(
244 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
245 + "-MN.pcap",
246 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
247 port=main.params[ 'MNtcpdump' ][ 'port' ] )
248
Jon Halla440e872016-03-31 15:15:50 -0700249 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -0700250 nodeResults = utilities.retry( main.HA.nodesCheck,
251 False,
Jon Hallf37d44d2017-05-24 10:37:30 -0700252 args=[ main.activeNodes ],
Jon Hall41d39f12016-04-11 22:54:35 -0700253 attempts=5 )
Jon Halla440e872016-03-31 15:15:50 -0700254
Jon Hall41d39f12016-04-11 22:54:35 -0700255 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Halla440e872016-03-31 15:15:50 -0700256 onpass="Nodes check successful",
257 onfail="Nodes check NOT successful" )
258
259 if not nodeResults:
Jon Hall7ac7bc32016-05-05 10:57:02 -0700260 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700261 cli = main.CLIs[ i ]
Jon Halla440e872016-03-31 15:15:50 -0700262 main.log.debug( "{} components not ACTIVE: \n{}".format(
263 cli.name,
264 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700265 main.log.error( "Failed to start ONOS, stopping test" )
266 main.cleanup()
267 main.exit()
268
Jon Hall172b7ba2016-04-07 18:12:20 -0700269 main.step( "Activate apps defined in the params file" )
270 # get data from the params
271 apps = main.params.get( 'apps' )
272 if apps:
Jon Hallf37d44d2017-05-24 10:37:30 -0700273 apps = apps.split( ',' )
Jon Hall172b7ba2016-04-07 18:12:20 -0700274 main.log.warn( apps )
275 activateResult = True
276 for app in apps:
277 main.CLIs[ 0 ].app( app, "Activate" )
278 # TODO: check this worked
279 time.sleep( 10 ) # wait for apps to activate
280 for app in apps:
281 state = main.CLIs[ 0 ].appStatus( app )
282 if state == "ACTIVE":
Jon Hall937bc812017-01-31 16:44:10 -0800283 activateResult = activateResult and True
Jon Hall172b7ba2016-04-07 18:12:20 -0700284 else:
285 main.log.error( "{} is in {} state".format( app, state ) )
Jon Hall937bc812017-01-31 16:44:10 -0800286 activateResult = False
Jon Hall172b7ba2016-04-07 18:12:20 -0700287 utilities.assert_equals( expect=True,
288 actual=activateResult,
289 onpass="Successfully activated apps",
290 onfail="Failed to activate apps" )
291 else:
292 main.log.warn( "No apps were specified to be loaded after startup" )
293
294 main.step( "Set ONOS configurations" )
295 config = main.params.get( 'ONOS_Configuration' )
296 if config:
297 main.log.debug( config )
298 checkResult = main.TRUE
299 for component in config:
Jon Hallf37d44d2017-05-24 10:37:30 -0700300 for setting in config[ component ]:
301 value = config[ component ][ setting ]
Jon Hall172b7ba2016-04-07 18:12:20 -0700302 check = main.CLIs[ 0 ].setCfg( component, setting, value )
303 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
304 checkResult = check and checkResult
305 utilities.assert_equals( expect=main.TRUE,
306 actual=checkResult,
307 onpass="Successfully set config",
308 onfail="Failed to set config" )
309 else:
310 main.log.warn( "No configurations were specified to be changed after startup" )
311
Jon Hall9d2dcad2016-04-08 10:15:20 -0700312 main.step( "App Ids check" )
313 appCheck = main.TRUE
314 threads = []
315 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700316 t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
Jon Hall9d2dcad2016-04-08 10:15:20 -0700317 name="appToIDCheck-" + str( i ),
318 args=[] )
319 threads.append( t )
320 t.start()
321
322 for t in threads:
323 t.join()
324 appCheck = appCheck and t.result
325 if appCheck != main.TRUE:
Jon Hallf37d44d2017-05-24 10:37:30 -0700326 node = main.activeNodes[ 0 ]
327 main.log.warn( main.CLIs[ node ].apps() )
328 main.log.warn( main.CLIs[ node ].appIDs() )
Jon Hall9d2dcad2016-04-08 10:15:20 -0700329 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
330 onpass="App Ids seem to be correct",
331 onfail="Something is wrong with app Ids" )
332
Jon Hall85794ff2015-07-08 14:12:30 -0700333 def CASE2( self, main ):
334 """
335 Assign devices to controllers
336 """
337 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700338 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700339 assert main, "main not defined"
340 assert utilities.assert_equals, "utilities.assert_equals not defined"
341
342 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700343 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700344 "and check that an ONOS node becomes the " +\
345 "master of the device."
346 main.step( "Assign switches to controllers" )
347
348 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700349 for i in range( main.numCtrls ):
350 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700351 swList = []
352 for i in range( 1, 29 ):
353 swList.append( "s" + str( i ) )
354 main.Mininet1.assignSwController( sw=swList, ip=ipList )
355
356 mastershipCheck = main.TRUE
357 for i in range( 1, 29 ):
358 response = main.Mininet1.getSwController( "s" + str( i ) )
359 try:
360 main.log.info( str( response ) )
361 except Exception:
362 main.log.info( repr( response ) )
Jon Halla440e872016-03-31 15:15:50 -0700363 for node in main.nodes:
364 if re.search( "tcp:" + node.ip_address, response ):
365 mastershipCheck = mastershipCheck and main.TRUE
366 else:
367 main.log.error( "Error, node " + node.ip_address + " is " +
368 "not in the list of controllers s" +
369 str( i ) + " is connecting to." )
370 mastershipCheck = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700371 utilities.assert_equals(
372 expect=main.TRUE,
373 actual=mastershipCheck,
374 onpass="Switch mastership assigned correctly",
375 onfail="Switches not assigned correctly to controllers" )
376
377 def CASE21( self, main ):
378 """
379 Assign mastership to controllers
380 """
Jon Halle1a3b752015-07-22 13:02:46 -0700381 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700382 assert main, "main not defined"
383 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700384 assert main.CLIs, "main.CLIs not defined"
385 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700386
387 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700388 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700389 "device. Then manually assign" +\
390 " mastership to specific ONOS nodes using" +\
391 " 'device-role'"
392 main.step( "Assign mastership of switches to specific controllers" )
Jon Halla440e872016-03-31 15:15:50 -0700393 # Manually assign mastership to the controller we want
Jon Hall85794ff2015-07-08 14:12:30 -0700394 roleCall = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700395
Jon Hallf37d44d2017-05-24 10:37:30 -0700396 ipList = []
Jon Halla440e872016-03-31 15:15:50 -0700397 deviceList = []
Jon Hallf37d44d2017-05-24 10:37:30 -0700398 onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700399 try:
Jon Halla440e872016-03-31 15:15:50 -0700400 # Assign mastership to specific controllers. This assignment was
401 # determined for a 7 node cluser, but will work with any sized
402 # cluster
Jon Hall85794ff2015-07-08 14:12:30 -0700403 for i in range( 1, 29 ): # switches 1 through 28
Jon Hall85794ff2015-07-08 14:12:30 -0700404 # set up correct variables:
405 if i == 1:
Jon Halla440e872016-03-31 15:15:50 -0700406 c = 0
407 ip = main.nodes[ c ].ip_address # ONOS1
408 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700409 elif i == 2:
Jon Halla440e872016-03-31 15:15:50 -0700410 c = 1 % main.numCtrls
411 ip = main.nodes[ c ].ip_address # ONOS2
412 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700413 elif i == 3:
Jon Halla440e872016-03-31 15:15:50 -0700414 c = 1 % main.numCtrls
415 ip = main.nodes[ c ].ip_address # ONOS2
416 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700417 elif i == 4:
Jon Halla440e872016-03-31 15:15:50 -0700418 c = 3 % main.numCtrls
419 ip = main.nodes[ c ].ip_address # ONOS4
420 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700421 elif i == 5:
Jon Halla440e872016-03-31 15:15:50 -0700422 c = 2 % main.numCtrls
423 ip = main.nodes[ c ].ip_address # ONOS3
424 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700425 elif i == 6:
Jon Halla440e872016-03-31 15:15:50 -0700426 c = 2 % main.numCtrls
427 ip = main.nodes[ c ].ip_address # ONOS3
428 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700429 elif i == 7:
Jon Halla440e872016-03-31 15:15:50 -0700430 c = 5 % main.numCtrls
431 ip = main.nodes[ c ].ip_address # ONOS6
432 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700433 elif i >= 8 and i <= 17:
Jon Halla440e872016-03-31 15:15:50 -0700434 c = 4 % main.numCtrls
435 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall85794ff2015-07-08 14:12:30 -0700436 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700437 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700438 elif i >= 18 and i <= 27:
Jon Halla440e872016-03-31 15:15:50 -0700439 c = 6 % main.numCtrls
440 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall85794ff2015-07-08 14:12:30 -0700441 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700442 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700443 elif i == 28:
Jon Halla440e872016-03-31 15:15:50 -0700444 c = 0
445 ip = main.nodes[ c ].ip_address # ONOS1
446 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700447 else:
448 main.log.error( "You didn't write an else statement for " +
449 "switch s" + str( i ) )
Jon Halla440e872016-03-31 15:15:50 -0700450 roleCall = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700451 # Assign switch
452 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
453 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700454 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
455 ipList.append( ip )
456 deviceList.append( deviceId )
Jon Hall85794ff2015-07-08 14:12:30 -0700457 except ( AttributeError, AssertionError ):
458 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700459 main.log.info( onosCli.devices() )
Jon Hall85794ff2015-07-08 14:12:30 -0700460 utilities.assert_equals(
461 expect=main.TRUE,
462 actual=roleCall,
463 onpass="Re-assigned switch mastership to designated controller",
464 onfail="Something wrong with deviceRole calls" )
465
466 main.step( "Check mastership was correctly assigned" )
Jon Halla440e872016-03-31 15:15:50 -0700467 roleCheck = main.TRUE
468 # NOTE: This is due to the fact that device mastership change is not
469 # atomic and is actually a multi step process
470 time.sleep( 5 )
471 for i in range( len( ipList ) ):
Jon Hallf37d44d2017-05-24 10:37:30 -0700472 ip = ipList[ i ]
473 deviceId = deviceList[ i ]
Jon Halla440e872016-03-31 15:15:50 -0700474 # Check assignment
475 master = onosCli.getRole( deviceId ).get( 'master' )
476 if ip in master:
477 roleCheck = roleCheck and main.TRUE
478 else:
479 roleCheck = roleCheck and main.FALSE
480 main.log.error( "Error, controller " + ip + " is not" +
481 " master " + "of device " +
482 str( deviceId ) + ". Master is " +
483 repr( master ) + "." )
Jon Hall85794ff2015-07-08 14:12:30 -0700484 utilities.assert_equals(
485 expect=main.TRUE,
486 actual=roleCheck,
487 onpass="Switches were successfully reassigned to designated " +
488 "controller",
489 onfail="Switches were not successfully reassigned" )
490
491 def CASE3( self, main ):
492 """
493 Assign intents
494 """
495 import time
496 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700497 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700498 assert main, "main not defined"
499 assert utilities.assert_equals, "utilities.assert_equals not defined"
500 # NOTE: we must reinstall intents until we have a persistant intent
501 # datastore!
502 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700503 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700504 "assign predetermined host-to-host intents." +\
505 " After installation, check that the intent" +\
506 " is distributed to all nodes and the state" +\
507 " is INSTALLED"
508
509 # install onos-app-fwd
510 main.step( "Install reactive forwarding app" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700511 onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
Jon Halla440e872016-03-31 15:15:50 -0700512 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700513 utilities.assert_equals( expect=main.TRUE, actual=installResults,
514 onpass="Install fwd successful",
515 onfail="Install fwd failed" )
516
517 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700518 appCheck = main.TRUE
519 threads = []
520 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700521 t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
Jon Halla440e872016-03-31 15:15:50 -0700522 name="appToIDCheck-" + str( i ),
523 args=[] )
524 threads.append( t )
525 t.start()
526
527 for t in threads:
528 t.join()
529 appCheck = appCheck and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700530 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700531 main.log.warn( onosCli.apps() )
532 main.log.warn( onosCli.appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700533 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
534 onpass="App Ids seem to be correct",
535 onfail="Something is wrong with app Ids" )
536
537 main.step( "Discovering Hosts( Via pingall for now )" )
538 # FIXME: Once we have a host discovery mechanism, use that instead
539 # REACTIVE FWD test
540 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700541 passMsg = "Reactive Pingall test passed"
542 time1 = time.time()
543 pingResult = main.Mininet1.pingall()
544 time2 = time.time()
545 if not pingResult:
Jon Hallf37d44d2017-05-24 10:37:30 -0700546 main.log.warn( "First pingall failed. Trying again..." )
Jon Hall85794ff2015-07-08 14:12:30 -0700547 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700548 passMsg += " on the second try"
549 utilities.assert_equals(
550 expect=main.TRUE,
551 actual=pingResult,
Jon Hallf37d44d2017-05-24 10:37:30 -0700552 onpass=passMsg,
Jon Hall96091e62015-09-21 17:34:17 -0700553 onfail="Reactive Pingall failed, " +
554 "one or more ping pairs failed" )
555 main.log.info( "Time for pingall: %2f seconds" %
556 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700557 # timeout for fwd flows
558 time.sleep( 11 )
559 # uninstall onos-app-fwd
560 main.step( "Uninstall reactive forwarding app" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700561 node = main.activeNodes[ 0 ]
562 uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700563 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
564 onpass="Uninstall fwd successful",
565 onfail="Uninstall fwd failed" )
566
567 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700568 threads = []
569 appCheck2 = main.TRUE
570 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700571 t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
Jon Halla440e872016-03-31 15:15:50 -0700572 name="appToIDCheck-" + str( i ),
573 args=[] )
574 threads.append( t )
575 t.start()
576
577 for t in threads:
578 t.join()
579 appCheck2 = appCheck2 and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700580 if appCheck2 != main.TRUE:
Jon Hallf37d44d2017-05-24 10:37:30 -0700581 node = main.activeNodes[ 0 ]
582 main.log.warn( main.CLIs[ node ].apps() )
583 main.log.warn( main.CLIs[ node ].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700584 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
585 onpass="App Ids seem to be correct",
586 onfail="Something is wrong with app Ids" )
587
588 main.step( "Add host intents via cli" )
589 intentIds = []
Jon Halla440e872016-03-31 15:15:50 -0700590 # TODO: move the host numbers to params
591 # Maybe look at all the paths we ping?
Jon Hall85794ff2015-07-08 14:12:30 -0700592 intentAddResult = True
593 hostResult = main.TRUE
594 for i in range( 8, 18 ):
595 main.log.info( "Adding host intent between h" + str( i ) +
596 " and h" + str( i + 10 ) )
597 host1 = "00:00:00:00:00:" + \
598 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
599 host2 = "00:00:00:00:00:" + \
600 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
601 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700602 host1Dict = onosCli.getHost( host1 )
603 host2Dict = onosCli.getHost( host2 )
Jon Hall85794ff2015-07-08 14:12:30 -0700604 host1Id = None
605 host2Id = None
606 if host1Dict and host2Dict:
607 host1Id = host1Dict.get( 'id', None )
608 host2Id = host2Dict.get( 'id', None )
609 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700610 nodeNum = ( i % len( main.activeNodes ) )
Jon Hallf37d44d2017-05-24 10:37:30 -0700611 node = main.activeNodes[ nodeNum ]
612 tmpId = main.CLIs[ node ].addHostIntent( host1Id, host2Id )
Jon Hall85794ff2015-07-08 14:12:30 -0700613 if tmpId:
614 main.log.info( "Added intent with id: " + tmpId )
615 intentIds.append( tmpId )
616 else:
617 main.log.error( "addHostIntent returned: " +
618 repr( tmpId ) )
619 else:
620 main.log.error( "Error, getHost() failed for h" + str( i ) +
621 " and/or h" + str( i + 10 ) )
Jon Hallf37d44d2017-05-24 10:37:30 -0700622 node = main.activeNodes[ 0 ]
623 hosts = main.CLIs[ node ].hosts()
Jon Hall85794ff2015-07-08 14:12:30 -0700624 main.log.warn( "Hosts output: " )
625 try:
626 main.log.warn( json.dumps( json.loads( hosts ),
627 sort_keys=True,
628 indent=4,
629 separators=( ',', ': ' ) ) )
630 except ( ValueError, TypeError ):
631 main.log.warn( repr( hosts ) )
632 hostResult = main.FALSE
633 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
634 onpass="Found a host id for each host",
635 onfail="Error looking up host ids" )
636
637 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700638 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700639 main.log.info( "Submitted intents: " + str( intentIds ) )
640 main.log.info( "Intents in ONOS: " + str( onosIds ) )
641 for intent in intentIds:
642 if intent in onosIds:
643 pass # intent submitted is in onos
644 else:
645 intentAddResult = False
646 if intentAddResult:
647 intentStop = time.time()
648 else:
649 intentStop = None
650 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700651 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700652 intentStates = []
653 installedCheck = True
654 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
655 count = 0
656 try:
657 for intent in json.loads( intents ):
658 state = intent.get( 'state', None )
659 if "INSTALLED" not in state:
660 installedCheck = False
661 intentId = intent.get( 'id', None )
662 intentStates.append( ( intentId, state ) )
663 except ( ValueError, TypeError ):
664 main.log.exception( "Error parsing intents" )
665 # add submitted intents not in the store
666 tmplist = [ i for i, s in intentStates ]
667 missingIntents = False
668 for i in intentIds:
669 if i not in tmplist:
670 intentStates.append( ( i, " - " ) )
671 missingIntents = True
672 intentStates.sort()
673 for i, s in intentStates:
674 count += 1
675 main.log.info( "%-6s%-15s%-15s" %
676 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700677 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700678 try:
679 missing = False
680 if leaders:
681 parsedLeaders = json.loads( leaders )
682 main.log.warn( json.dumps( parsedLeaders,
683 sort_keys=True,
684 indent=4,
685 separators=( ',', ': ' ) ) )
686 # check for all intent partitions
687 topics = []
688 for i in range( 14 ):
Jon Hall8dafdcc2016-09-16 10:21:25 -0700689 topics.append( "work-partition-" + str( i ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700690 main.log.debug( topics )
Jon Hallf37d44d2017-05-24 10:37:30 -0700691 ONOStopics = [ j[ 'topic' ] for j in parsedLeaders ]
Jon Hall85794ff2015-07-08 14:12:30 -0700692 for topic in topics:
693 if topic not in ONOStopics:
694 main.log.error( "Error: " + topic +
695 " not in leaders" )
696 missing = True
697 else:
698 main.log.error( "leaders() returned None" )
699 except ( ValueError, TypeError ):
700 main.log.exception( "Error parsing leaders" )
701 main.log.error( repr( leaders ) )
702 # Check all nodes
703 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700704 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700705 response = main.CLIs[ i ].leaders( jsonFormat=False )
706 main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
Jon Halla440e872016-03-31 15:15:50 -0700707 str( response ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700708
Jon Halla440e872016-03-31 15:15:50 -0700709 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700710 try:
Jon Hallf37d44d2017-05-24 10:37:30 -0700711 if partitions:
Jon Hall85794ff2015-07-08 14:12:30 -0700712 parsedPartitions = json.loads( partitions )
713 main.log.warn( json.dumps( parsedPartitions,
714 sort_keys=True,
715 indent=4,
716 separators=( ',', ': ' ) ) )
717 # TODO check for a leader in all paritions
718 # TODO check for consistency among nodes
719 else:
720 main.log.error( "partitions() returned None" )
721 except ( ValueError, TypeError ):
722 main.log.exception( "Error parsing partitions" )
723 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700724 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700725 try:
Jon Hallf37d44d2017-05-24 10:37:30 -0700726 if pendingMap:
Jon Hall85794ff2015-07-08 14:12:30 -0700727 parsedPending = json.loads( pendingMap )
728 main.log.warn( json.dumps( parsedPending,
729 sort_keys=True,
730 indent=4,
731 separators=( ',', ': ' ) ) )
732 # TODO check something here?
733 else:
734 main.log.error( "pendingMap() returned None" )
735 except ( ValueError, TypeError ):
736 main.log.exception( "Error parsing pending map" )
737 main.log.error( repr( pendingMap ) )
738
739 intentAddResult = bool( intentAddResult and not missingIntents and
740 installedCheck )
741 if not intentAddResult:
742 main.log.error( "Error in pushing host intents to ONOS" )
743
744 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700745 for j in range( 100 ):
Jon Hall85794ff2015-07-08 14:12:30 -0700746 correct = True
747 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700748 for i in main.activeNodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700749 onosIds = []
Jon Hallf37d44d2017-05-24 10:37:30 -0700750 ids = main.CLIs[ i ].getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700751 onosIds.append( ids )
Jon Hallf37d44d2017-05-24 10:37:30 -0700752 main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
Jon Hall85794ff2015-07-08 14:12:30 -0700753 str( sorted( onosIds ) ) )
754 if sorted( ids ) != sorted( intentIds ):
755 main.log.warn( "Set of intent IDs doesn't match" )
756 correct = False
757 break
758 else:
Jon Hallf37d44d2017-05-24 10:37:30 -0700759 intents = json.loads( main.CLIs[ i ].intents() )
Jon Hall85794ff2015-07-08 14:12:30 -0700760 for intent in intents:
761 if intent[ 'state' ] != "INSTALLED":
762 main.log.warn( "Intent " + intent[ 'id' ] +
763 " is " + intent[ 'state' ] )
764 correct = False
765 break
766 if correct:
767 break
768 else:
Jon Hallf37d44d2017-05-24 10:37:30 -0700769 time.sleep( 1 )
Jon Hall85794ff2015-07-08 14:12:30 -0700770 if not intentStop:
771 intentStop = time.time()
772 global gossipTime
773 gossipTime = intentStop - intentStart
774 main.log.info( "It took about " + str( gossipTime ) +
775 " seconds for all intents to appear in each node" )
Jon Hallf37d44d2017-05-24 10:37:30 -0700776 gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
Jon Halla440e872016-03-31 15:15:50 -0700777 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700778 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700779 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700780 onpass="ECM anti-entropy for intents worked within " +
781 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700782 onfail="Intent ECM anti-entropy took too long. " +
783 "Expected time:{}, Actual time:{}".format( maxGossipTime,
784 gossipTime ) )
785 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700786 intentAddResult = True
787
788 if not intentAddResult or "key" in pendingMap:
789 import time
790 installedCheck = True
791 main.log.info( "Sleeping 60 seconds to see if intents are found" )
792 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700793 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700794 main.log.info( "Submitted intents: " + str( intentIds ) )
795 main.log.info( "Intents in ONOS: " + str( onosIds ) )
796 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700797 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700798 intentStates = []
799 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
800 count = 0
801 try:
802 for intent in json.loads( intents ):
803 # Iter through intents of a node
804 state = intent.get( 'state', None )
805 if "INSTALLED" not in state:
806 installedCheck = False
807 intentId = intent.get( 'id', None )
808 intentStates.append( ( intentId, state ) )
809 except ( ValueError, TypeError ):
810 main.log.exception( "Error parsing intents" )
811 # add submitted intents not in the store
812 tmplist = [ i for i, s in intentStates ]
813 for i in intentIds:
814 if i not in tmplist:
815 intentStates.append( ( i, " - " ) )
816 intentStates.sort()
817 for i, s in intentStates:
818 count += 1
819 main.log.info( "%-6s%-15s%-15s" %
820 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700821 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700822 try:
823 missing = False
824 if leaders:
825 parsedLeaders = json.loads( leaders )
826 main.log.warn( json.dumps( parsedLeaders,
827 sort_keys=True,
828 indent=4,
829 separators=( ',', ': ' ) ) )
830 # check for all intent partitions
831 # check for election
832 topics = []
833 for i in range( 14 ):
Jon Hall8dafdcc2016-09-16 10:21:25 -0700834 topics.append( "work-partition-" + str( i ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700835 # FIXME: this should only be after we start the app
836 topics.append( "org.onosproject.election" )
837 main.log.debug( topics )
Jon Hallf37d44d2017-05-24 10:37:30 -0700838 ONOStopics = [ j[ 'topic' ] for j in parsedLeaders ]
Jon Hall85794ff2015-07-08 14:12:30 -0700839 for topic in topics:
840 if topic not in ONOStopics:
841 main.log.error( "Error: " + topic +
842 " not in leaders" )
843 missing = True
844 else:
845 main.log.error( "leaders() returned None" )
846 except ( ValueError, TypeError ):
847 main.log.exception( "Error parsing leaders" )
848 main.log.error( repr( leaders ) )
849 # Check all nodes
850 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700851 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700852 node = main.CLIs[ i ]
853 response = node.leaders( jsonFormat=False )
Jon Halla440e872016-03-31 15:15:50 -0700854 main.log.warn( str( node.name ) + " leaders output: \n" +
855 str( response ) )
856
857 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700858 try:
Jon Hallf37d44d2017-05-24 10:37:30 -0700859 if partitions:
Jon Hall85794ff2015-07-08 14:12:30 -0700860 parsedPartitions = json.loads( partitions )
861 main.log.warn( json.dumps( parsedPartitions,
862 sort_keys=True,
863 indent=4,
864 separators=( ',', ': ' ) ) )
865 # TODO check for a leader in all paritions
866 # TODO check for consistency among nodes
867 else:
868 main.log.error( "partitions() returned None" )
869 except ( ValueError, TypeError ):
870 main.log.exception( "Error parsing partitions" )
871 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700872 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700873 try:
Jon Hallf37d44d2017-05-24 10:37:30 -0700874 if pendingMap:
Jon Hall85794ff2015-07-08 14:12:30 -0700875 parsedPending = json.loads( pendingMap )
876 main.log.warn( json.dumps( parsedPending,
877 sort_keys=True,
878 indent=4,
879 separators=( ',', ': ' ) ) )
880 # TODO check something here?
881 else:
882 main.log.error( "pendingMap() returned None" )
883 except ( ValueError, TypeError ):
884 main.log.exception( "Error parsing pending map" )
885 main.log.error( repr( pendingMap ) )
886
887 def CASE4( self, main ):
888 """
889 Ping across added host intents
890 """
891 import json
892 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700893 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700894 assert main, "main not defined"
895 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halla440e872016-03-31 15:15:50 -0700896 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700897 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700898 "functionality and check the state of " +\
899 "the intent"
Jon Hall9d2dcad2016-04-08 10:15:20 -0700900
Jon Hallf37d44d2017-05-24 10:37:30 -0700901 onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
Jon Hall9d2dcad2016-04-08 10:15:20 -0700902 main.step( "Check Intent state" )
903 installedCheck = True
904 # Print the intent states
905 intents = main.ONOScli1.intents()
906 intentStates = []
907 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
908 count = 0
909 # Iter through intents of a node
910 try:
911 for intent in json.loads( intents ):
912 state = intent.get( 'state', None )
913 if "INSTALLED" not in state:
914 installedCheck = False
915 intentId = intent.get( 'id', None )
916 intentStates.append( ( intentId, state ) )
917 except ( ValueError, TypeError ):
918 main.log.exception( "Error parsing intents." )
919 # Print states
920 intentStates.sort()
921 for i, s in intentStates:
922 count += 1
923 main.log.info( "%-6s%-15s%-15s" %
924 ( str( count ), str( i ), str( s ) ) )
925 utilities.assert_equals( expect=True, actual=installedCheck,
926 onpass="Intents are all INSTALLED",
927 onfail="Intents are not all in " +
928 "INSTALLED state" )
929
Jon Hall85794ff2015-07-08 14:12:30 -0700930 main.step( "Ping across added host intents" )
931 PingResult = main.TRUE
932 for i in range( 8, 18 ):
933 ping = main.Mininet1.pingHost( src="h" + str( i ),
934 target="h" + str( i + 10 ) )
935 PingResult = PingResult and ping
936 if ping == main.FALSE:
937 main.log.warn( "Ping failed between h" + str( i ) +
938 " and h" + str( i + 10 ) )
939 elif ping == main.TRUE:
940 main.log.info( "Ping test passed!" )
941 # Don't set PingResult or you'd override failures
942 if PingResult == main.FALSE:
943 main.log.error(
944 "Intents have not been installed correctly, pings failed." )
945 # TODO: pretty print
946 main.log.warn( "ONOS1 intents: " )
947 try:
Jon Halla440e872016-03-31 15:15:50 -0700948 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700949 main.log.warn( json.dumps( json.loads( tmpIntents ),
950 sort_keys=True,
951 indent=4,
952 separators=( ',', ': ' ) ) )
953 except ( ValueError, TypeError ):
954 main.log.warn( repr( tmpIntents ) )
955 utilities.assert_equals(
956 expect=main.TRUE,
957 actual=PingResult,
958 onpass="Intents have been installed correctly and pings work",
959 onfail="Intents have not been installed correctly, pings failed." )
960
Jon Hall85794ff2015-07-08 14:12:30 -0700961 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700962 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700963 topicCheck = main.TRUE
964 try:
965 if leaders:
966 parsedLeaders = json.loads( leaders )
967 main.log.warn( json.dumps( parsedLeaders,
968 sort_keys=True,
969 indent=4,
970 separators=( ',', ': ' ) ) )
971 # check for all intent partitions
972 # check for election
973 # TODO: Look at Devices as topics now that it uses this system
974 topics = []
975 for i in range( 14 ):
Jon Hall8dafdcc2016-09-16 10:21:25 -0700976 topics.append( "work-partition-" + str( i ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700977 # FIXME: this should only be after we start the app
978 # FIXME: topics.append( "org.onosproject.election" )
979 # Print leaders output
980 main.log.debug( topics )
Jon Hallf37d44d2017-05-24 10:37:30 -0700981 ONOStopics = [ j[ 'topic' ] for j in parsedLeaders ]
Jon Hall85794ff2015-07-08 14:12:30 -0700982 for topic in topics:
983 if topic not in ONOStopics:
984 main.log.error( "Error: " + topic +
985 " not in leaders" )
986 topicCheck = main.FALSE
987 else:
988 main.log.error( "leaders() returned None" )
989 topicCheck = main.FALSE
990 except ( ValueError, TypeError ):
991 topicCheck = main.FALSE
992 main.log.exception( "Error parsing leaders" )
993 main.log.error( repr( leaders ) )
994 # TODO: Check for a leader of these topics
Jon Halla440e872016-03-31 15:15:50 -0700995 # Check all nodes
996 if topicCheck:
997 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -0700998 node = main.CLIs[ i ]
999 response = node.leaders( jsonFormat=False )
Jon Halla440e872016-03-31 15:15:50 -07001000 main.log.warn( str( node.name ) + " leaders output: \n" +
1001 str( response ) )
1002
Jon Hall85794ff2015-07-08 14:12:30 -07001003 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1004 onpass="intent Partitions is in leaders",
1005 onfail="Some topics were lost " )
1006 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001007 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001008 try:
Jon Hallf37d44d2017-05-24 10:37:30 -07001009 if partitions:
Jon Hall85794ff2015-07-08 14:12:30 -07001010 parsedPartitions = json.loads( partitions )
1011 main.log.warn( json.dumps( parsedPartitions,
1012 sort_keys=True,
1013 indent=4,
1014 separators=( ',', ': ' ) ) )
1015 # TODO check for a leader in all paritions
1016 # TODO check for consistency among nodes
1017 else:
1018 main.log.error( "partitions() returned None" )
1019 except ( ValueError, TypeError ):
1020 main.log.exception( "Error parsing partitions" )
1021 main.log.error( repr( partitions ) )
1022 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001023 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001024 try:
Jon Hallf37d44d2017-05-24 10:37:30 -07001025 if pendingMap:
Jon Hall85794ff2015-07-08 14:12:30 -07001026 parsedPending = json.loads( pendingMap )
1027 main.log.warn( json.dumps( parsedPending,
1028 sort_keys=True,
1029 indent=4,
1030 separators=( ',', ': ' ) ) )
1031 # TODO check something here?
1032 else:
1033 main.log.error( "pendingMap() returned None" )
1034 except ( ValueError, TypeError ):
1035 main.log.exception( "Error parsing pending map" )
1036 main.log.error( repr( pendingMap ) )
1037
1038 if not installedCheck:
1039 main.log.info( "Waiting 60 seconds to see if the state of " +
1040 "intents change" )
1041 time.sleep( 60 )
1042 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001043 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001044 intentStates = []
1045 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1046 count = 0
1047 # Iter through intents of a node
1048 try:
1049 for intent in json.loads( intents ):
1050 state = intent.get( 'state', None )
1051 if "INSTALLED" not in state:
1052 installedCheck = False
1053 intentId = intent.get( 'id', None )
1054 intentStates.append( ( intentId, state ) )
1055 except ( ValueError, TypeError ):
1056 main.log.exception( "Error parsing intents." )
1057 intentStates.sort()
1058 for i, s in intentStates:
1059 count += 1
1060 main.log.info( "%-6s%-15s%-15s" %
1061 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001062 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -07001063 try:
1064 missing = False
1065 if leaders:
1066 parsedLeaders = json.loads( leaders )
1067 main.log.warn( json.dumps( parsedLeaders,
1068 sort_keys=True,
1069 indent=4,
1070 separators=( ',', ': ' ) ) )
1071 # check for all intent partitions
1072 # check for election
1073 topics = []
1074 for i in range( 14 ):
Jon Hall8dafdcc2016-09-16 10:21:25 -07001075 topics.append( "work-partition-" + str( i ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001076 # FIXME: this should only be after we start the app
1077 topics.append( "org.onosproject.election" )
1078 main.log.debug( topics )
Jon Hallf37d44d2017-05-24 10:37:30 -07001079 ONOStopics = [ j[ 'topic' ] for j in parsedLeaders ]
Jon Hall85794ff2015-07-08 14:12:30 -07001080 for topic in topics:
1081 if topic not in ONOStopics:
1082 main.log.error( "Error: " + topic +
1083 " not in leaders" )
1084 missing = True
1085 else:
1086 main.log.error( "leaders() returned None" )
1087 except ( ValueError, TypeError ):
1088 main.log.exception( "Error parsing leaders" )
1089 main.log.error( repr( leaders ) )
1090 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001091 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -07001092 node = main.CLIs[ i ]
1093 response = node.leaders( jsonFormat=False )
Jon Halla440e872016-03-31 15:15:50 -07001094 main.log.warn( str( node.name ) + " leaders output: \n" +
1095 str( response ) )
1096
1097 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001098 try:
Jon Hallf37d44d2017-05-24 10:37:30 -07001099 if partitions:
Jon Hall85794ff2015-07-08 14:12:30 -07001100 parsedPartitions = json.loads( partitions )
1101 main.log.warn( json.dumps( parsedPartitions,
1102 sort_keys=True,
1103 indent=4,
1104 separators=( ',', ': ' ) ) )
1105 # TODO check for a leader in all paritions
1106 # TODO check for consistency among nodes
1107 else:
1108 main.log.error( "partitions() returned None" )
1109 except ( ValueError, TypeError ):
1110 main.log.exception( "Error parsing partitions" )
1111 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001112 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001113 try:
Jon Hallf37d44d2017-05-24 10:37:30 -07001114 if pendingMap:
Jon Hall85794ff2015-07-08 14:12:30 -07001115 parsedPending = json.loads( pendingMap )
1116 main.log.warn( json.dumps( parsedPending,
1117 sort_keys=True,
1118 indent=4,
1119 separators=( ',', ': ' ) ) )
1120 # TODO check something here?
1121 else:
1122 main.log.error( "pendingMap() returned None" )
1123 except ( ValueError, TypeError ):
1124 main.log.exception( "Error parsing pending map" )
1125 main.log.error( repr( pendingMap ) )
1126 # Print flowrules
Jon Hallf37d44d2017-05-24 10:37:30 -07001127 node = main.activeNodes[ 0 ]
1128 main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001129 main.step( "Wait a minute then ping again" )
1130 # the wait is above
1131 PingResult = main.TRUE
1132 for i in range( 8, 18 ):
1133 ping = main.Mininet1.pingHost( src="h" + str( i ),
1134 target="h" + str( i + 10 ) )
1135 PingResult = PingResult and ping
1136 if ping == main.FALSE:
1137 main.log.warn( "Ping failed between h" + str( i ) +
1138 " and h" + str( i + 10 ) )
1139 elif ping == main.TRUE:
1140 main.log.info( "Ping test passed!" )
1141 # Don't set PingResult or you'd override failures
1142 if PingResult == main.FALSE:
1143 main.log.error(
1144 "Intents have not been installed correctly, pings failed." )
1145 # TODO: pretty print
1146 main.log.warn( "ONOS1 intents: " )
1147 try:
Jon Halla440e872016-03-31 15:15:50 -07001148 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001149 main.log.warn( json.dumps( json.loads( tmpIntents ),
1150 sort_keys=True,
1151 indent=4,
1152 separators=( ',', ': ' ) ) )
1153 except ( ValueError, TypeError ):
1154 main.log.warn( repr( tmpIntents ) )
1155 utilities.assert_equals(
1156 expect=main.TRUE,
1157 actual=PingResult,
1158 onpass="Intents have been installed correctly and pings work",
1159 onfail="Intents have not been installed correctly, pings failed." )
1160
1161 def CASE5( self, main ):
1162 """
1163 Reading state of ONOS
1164 """
1165 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001166 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001167 assert main, "main not defined"
1168 assert utilities.assert_equals, "utilities.assert_equals not defined"
1169
1170 main.case( "Setting up and gathering data for current state" )
1171 # The general idea for this test case is to pull the state of
1172 # ( intents,flows, topology,... ) from each ONOS node
1173 # We can then compare them with each other and also with past states
1174
1175 main.step( "Check that each switch has a master" )
1176 global mastershipState
1177 mastershipState = '[]'
1178
1179 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001180 rolesNotNull = main.TRUE
1181 threads = []
1182 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -07001183 t = main.Thread( target=main.CLIs[ i ].rolesNotNull,
Jon Halla440e872016-03-31 15:15:50 -07001184 name="rolesNotNull-" + str( i ),
1185 args=[] )
1186 threads.append( t )
1187 t.start()
1188
1189 for t in threads:
1190 t.join()
1191 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001192 utilities.assert_equals(
1193 expect=main.TRUE,
1194 actual=rolesNotNull,
1195 onpass="Each device has a master",
1196 onfail="Some devices don't have a master assigned" )
1197
1198 main.step( "Get the Mastership of each switch" )
1199 ONOS1Mastership = main.ONOScli1.roles()
1200 # TODO: Make this a meaningful check
1201 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1202 main.log.error( "Error in getting ONOS roles" )
1203 main.log.warn(
1204 "ONOS1 mastership response: " +
1205 repr( ONOS1Mastership ) )
1206 consistentMastership = main.FALSE
1207 else:
1208 mastershipState = ONOS1Mastership
1209 consistentMastership = main.TRUE
1210
1211 main.step( "Get the intents from each controller" )
1212 global intentState
1213 intentState = []
1214 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1215 intentCheck = main.FALSE
1216 if "Error" in ONOS1Intents or not ONOS1Intents:
1217 main.log.error( "Error in getting ONOS intents" )
1218 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1219 else:
1220 intentCheck = main.TRUE
1221
1222 main.step( "Get the flows from each controller" )
1223 global flowState
1224 flowState = []
1225 flowCheck = main.FALSE
1226 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1227 if "Error" in ONOS1Flows or not ONOS1Flows:
1228 main.log.error( "Error in getting ONOS flows" )
1229 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1230 else:
1231 # TODO: Do a better check, maybe compare flows on switches?
1232 flowState = ONOS1Flows
1233 flowCheck = main.TRUE
1234
1235 main.step( "Get the OF Table entries" )
1236 global flows
1237 flows = []
1238 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001239 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001240 if flowCheck == main.FALSE:
1241 for table in flows:
1242 main.log.warn( table )
1243 # TODO: Compare switch flow tables with ONOS flow tables
1244
1245 main.step( "Collecting topology information from ONOS" )
1246 devices = []
1247 devices.append( main.ONOScli1.devices() )
1248 hosts = []
1249 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1250 ports = []
1251 ports.append( main.ONOScli1.ports() )
1252 links = []
1253 links.append( main.ONOScli1.links() )
1254 clusters = []
1255 clusters.append( main.ONOScli1.clusters() )
1256
1257 main.step( "Each host has an IP address" )
1258 ipResult = main.TRUE
1259 for controller in range( 0, len( hosts ) ):
Jon Hallf37d44d2017-05-24 10:37:30 -07001260 controllerStr = str( main.activeNodes[ controller ] + 1 )
Jon Halla440e872016-03-31 15:15:50 -07001261 if hosts[ controller ]:
1262 for host in hosts[ controller ]:
Jon Hallf37d44d2017-05-24 10:37:30 -07001263 if not host.get( 'ipAddresses', [] ):
Jon Halla440e872016-03-31 15:15:50 -07001264 main.log.error( "Error with host ips on controller" +
1265 controllerStr + ": " + str( host ) )
1266 ipResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001267 utilities.assert_equals(
1268 expect=main.TRUE,
1269 actual=ipResult,
1270 onpass="The ips of the hosts aren't empty",
1271 onfail="The ip of at least one host is missing" )
1272
1273 # there should always only be one cluster
1274 main.step( "There is only one dataplane cluster" )
1275 try:
1276 numClusters = len( json.loads( clusters[ 0 ] ) )
1277 except ( ValueError, TypeError ):
1278 main.log.exception( "Error parsing clusters[0]: " +
1279 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001280 numClusters = "ERROR"
Jon Hall85794ff2015-07-08 14:12:30 -07001281 clusterResults = main.FALSE
1282 if numClusters == 1:
1283 clusterResults = main.TRUE
1284 utilities.assert_equals(
1285 expect=1,
1286 actual=numClusters,
1287 onpass="ONOS shows 1 SCC",
1288 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1289
1290 main.step( "Comparing ONOS topology to MN" )
1291 devicesResults = main.TRUE
1292 linksResults = main.TRUE
1293 hostsResults = main.TRUE
1294 mnSwitches = main.Mininet1.getSwitches()
1295 mnLinks = main.Mininet1.getLinks()
1296 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001297 for controller in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -07001298 controllerStr = str( main.activeNodes[ controller ] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07001299 if devices[ controller ] and ports[ controller ] and\
Jon Hallf37d44d2017-05-24 10:37:30 -07001300 "Error" not in devices[ controller ] and\
1301 "Error" not in ports[ controller ]:
1302 currentDevicesResult = main.Mininet1.compareSwitches(
1303 mnSwitches,
1304 json.loads( devices[ controller ] ),
1305 json.loads( ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001306 else:
1307 currentDevicesResult = main.FALSE
1308 utilities.assert_equals( expect=main.TRUE,
1309 actual=currentDevicesResult,
1310 onpass="ONOS" + controllerStr +
1311 " Switches view is correct",
1312 onfail="ONOS" + controllerStr +
1313 " Switches view is incorrect" )
1314 if links[ controller ] and "Error" not in links[ controller ]:
1315 currentLinksResult = main.Mininet1.compareLinks(
1316 mnSwitches, mnLinks,
1317 json.loads( links[ controller ] ) )
1318 else:
1319 currentLinksResult = main.FALSE
1320 utilities.assert_equals( expect=main.TRUE,
1321 actual=currentLinksResult,
1322 onpass="ONOS" + controllerStr +
1323 " links view is correct",
1324 onfail="ONOS" + controllerStr +
1325 " links view is incorrect" )
1326
Jon Halla440e872016-03-31 15:15:50 -07001327 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall85794ff2015-07-08 14:12:30 -07001328 currentHostsResult = main.Mininet1.compareHosts(
1329 mnHosts,
1330 hosts[ controller ] )
1331 else:
1332 currentHostsResult = main.FALSE
1333 utilities.assert_equals( expect=main.TRUE,
1334 actual=currentHostsResult,
1335 onpass="ONOS" + controllerStr +
1336 " hosts exist in Mininet",
1337 onfail="ONOS" + controllerStr +
1338 " hosts don't match Mininet" )
1339
1340 devicesResults = devicesResults and currentDevicesResult
1341 linksResults = linksResults and currentLinksResult
1342 hostsResults = hostsResults and currentHostsResult
1343
1344 main.step( "Device information is correct" )
1345 utilities.assert_equals(
1346 expect=main.TRUE,
1347 actual=devicesResults,
1348 onpass="Device information is correct",
1349 onfail="Device information is incorrect" )
1350
1351 main.step( "Links are correct" )
1352 utilities.assert_equals(
1353 expect=main.TRUE,
1354 actual=linksResults,
1355 onpass="Link are correct",
1356 onfail="Links are incorrect" )
1357
1358 main.step( "Hosts are correct" )
1359 utilities.assert_equals(
1360 expect=main.TRUE,
1361 actual=hostsResults,
1362 onpass="Hosts are correct",
1363 onfail="Hosts are incorrect" )
1364
1365 def CASE6( self, main ):
1366 """
1367 The Failure case.
1368 """
1369 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001370 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001371 assert main, "main not defined"
1372 assert utilities.assert_equals, "utilities.assert_equals not defined"
1373
1374 # Reset non-persistent variables
1375 try:
1376 iCounterValue = 0
1377 except NameError:
1378 main.log.error( "iCounterValue not defined, setting to 0" )
1379 iCounterValue = 0
1380
1381 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001382 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001383 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001384
1385 main.step( "Checking ONOS Logs for errors" )
1386 for node in main.nodes:
1387 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1388 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1389
Jon Hall85794ff2015-07-08 14:12:30 -07001390 main.step( "Killing ONOS processes" )
Jon Hallf37d44d2017-05-24 10:37:30 -07001391 killResult = main.ONOSbench.onosKill( main.nodes[ 0 ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001392 start = time.time()
1393 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1394 onpass="ONOS Killed",
1395 onfail="Error killing ONOS" )
1396
1397 main.step( "Checking if ONOS is up yet" )
1398 count = 0
1399 while count < 10:
Jon Hallf37d44d2017-05-24 10:37:30 -07001400 onos1Isup = main.ONOSbench.isup( main.nodes[ 0 ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001401 if onos1Isup == main.TRUE:
1402 elapsed = time.time() - start
1403 break
1404 else:
1405 count = count + 1
1406 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1407 onpass="ONOS is back up",
1408 onfail="ONOS failed to start" )
1409
Jon Hall6509dbf2016-06-21 17:01:17 -07001410 main.step( "Starting ONOS CLI sessions" )
Jon Hallf37d44d2017-05-24 10:37:30 -07001411 cliResults = main.ONOScli1.startOnosCli( main.nodes[ 0 ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001412 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1413 onpass="ONOS cli startup successful",
1414 onfail="ONOS cli startup failed" )
1415
1416 if elapsed:
1417 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1418 str( elapsed ) )
1419 main.restartTime = elapsed
1420 else:
1421 main.restartTime = -1
1422 time.sleep( 5 )
1423 # rerun on election apps
1424 main.ONOScli1.electionTestRun()
1425
1426 def CASE7( self, main ):
1427 """
1428 Check state after ONOS failure
1429 """
1430 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001431 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001432 assert main, "main not defined"
1433 assert utilities.assert_equals, "utilities.assert_equals not defined"
1434 main.case( "Running ONOS Constant State Tests" )
Jon Hall6e709752016-02-01 13:38:46 -08001435
Jon Hall85794ff2015-07-08 14:12:30 -07001436 main.step( "Check that each switch has a master" )
1437 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001438 rolesNotNull = main.TRUE
1439 threads = []
1440 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -07001441 t = main.Thread( target=main.CLIs[ i ].rolesNotNull,
Jon Halla440e872016-03-31 15:15:50 -07001442 name="rolesNotNull-" + str( i ),
Jon Hallf37d44d2017-05-24 10:37:30 -07001443 args=[] )
Jon Halla440e872016-03-31 15:15:50 -07001444 threads.append( t )
1445 t.start()
1446
1447 for t in threads:
1448 t.join()
1449 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001450 utilities.assert_equals(
1451 expect=main.TRUE,
1452 actual=rolesNotNull,
1453 onpass="Each device has a master",
1454 onfail="Some devices don't have a master assigned" )
1455
1456 main.step( "Check if switch roles are consistent across all nodes" )
1457 ONOS1Mastership = main.ONOScli1.roles()
1458 # FIXME: Refactor this whole case for single instance
1459 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1460 main.log.error( "Error in getting ONOS mastership" )
1461 main.log.warn( "ONOS1 mastership response: " +
1462 repr( ONOS1Mastership ) )
1463 consistentMastership = main.FALSE
1464 else:
1465 consistentMastership = main.TRUE
1466 utilities.assert_equals(
1467 expect=main.TRUE,
1468 actual=consistentMastership,
1469 onpass="Switch roles are consistent across all ONOS nodes",
1470 onfail="ONOS nodes have different views of switch roles" )
1471
1472 description2 = "Compare switch roles from before failure"
1473 main.step( description2 )
1474
1475 currentJson = json.loads( ONOS1Mastership )
1476 oldJson = json.loads( mastershipState )
1477 mastershipCheck = main.TRUE
1478 for i in range( 1, 29 ):
1479 switchDPID = str(
1480 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1481
1482 current = [ switch[ 'master' ] for switch in currentJson
1483 if switchDPID in switch[ 'id' ] ]
1484 old = [ switch[ 'master' ] for switch in oldJson
1485 if switchDPID in switch[ 'id' ] ]
1486 if current == old:
1487 mastershipCheck = mastershipCheck and main.TRUE
1488 else:
1489 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1490 mastershipCheck = main.FALSE
1491 utilities.assert_equals(
1492 expect=main.TRUE,
1493 actual=mastershipCheck,
1494 onpass="Mastership of Switches was not changed",
1495 onfail="Mastership of some switches changed" )
1496 mastershipCheck = mastershipCheck and consistentMastership
1497
1498 main.step( "Get the intents and compare across all nodes" )
1499 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1500 intentCheck = main.FALSE
1501 if "Error" in ONOS1Intents or not ONOS1Intents:
1502 main.log.error( "Error in getting ONOS intents" )
1503 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1504 else:
1505 intentCheck = main.TRUE
1506 utilities.assert_equals(
1507 expect=main.TRUE,
1508 actual=intentCheck,
1509 onpass="Intents are consistent across all ONOS nodes",
1510 onfail="ONOS nodes have different views of intents" )
1511 # Print the intent states
1512 intents = []
1513 intents.append( ONOS1Intents )
1514 intentStates = []
1515 for node in intents: # Iter through ONOS nodes
1516 nodeStates = []
1517 # Iter through intents of a node
1518 for intent in json.loads( node ):
1519 nodeStates.append( intent[ 'state' ] )
1520 intentStates.append( nodeStates )
Jon Hallf37d44d2017-05-24 10:37:30 -07001521 out = [ ( i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
Jon Hall85794ff2015-07-08 14:12:30 -07001522 main.log.info( dict( out ) )
1523
1524 # NOTE: Store has no durability, so intents are lost across system
1525 # restarts
1526 """
1527 main.step( "Compare current intents with intents before the failure" )
1528 # NOTE: this requires case 5 to pass for intentState to be set.
1529 # maybe we should stop the test if that fails?
1530 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001531 try:
1532 intentState
1533 except NameError:
1534 main.log.warn( "No previous intent state was saved" )
1535 else:
1536 if intentState and intentState == ONOSIntents[ 0 ]:
1537 sameIntents = main.TRUE
1538 main.log.info( "Intents are consistent with before failure" )
1539 # TODO: possibly the states have changed? we may need to figure out
1540 # what the acceptable states are
1541 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1542 sameIntents = main.TRUE
1543 try:
1544 before = json.loads( intentState )
1545 after = json.loads( ONOSIntents[ 0 ] )
1546 for intent in before:
1547 if intent not in after:
1548 sameIntents = main.FALSE
1549 main.log.debug( "Intent is not currently in ONOS " +
1550 "(at least in the same form):" )
1551 main.log.debug( json.dumps( intent ) )
1552 except ( ValueError, TypeError ):
1553 main.log.exception( "Exception printing intents" )
Jon Hallf37d44d2017-05-24 10:37:30 -07001554 main.log.debug( repr( ONOSIntents[ 0 ] ) )
Jon Halla440e872016-03-31 15:15:50 -07001555 main.log.debug( repr( intentState ) )
1556 if sameIntents == main.FALSE:
1557 try:
1558 main.log.debug( "ONOS intents before: " )
1559 main.log.debug( json.dumps( json.loads( intentState ),
1560 sort_keys=True, indent=4,
1561 separators=( ',', ': ' ) ) )
1562 main.log.debug( "Current ONOS intents: " )
1563 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1564 sort_keys=True, indent=4,
1565 separators=( ',', ': ' ) ) )
1566 except ( ValueError, TypeError ):
1567 main.log.exception( "Exception printing intents" )
Jon Hallf37d44d2017-05-24 10:37:30 -07001568 main.log.debug( repr( ONOSIntents[ 0 ] ) )
Jon Halla440e872016-03-31 15:15:50 -07001569 main.log.debug( repr( intentState ) )
1570 utilities.assert_equals(
1571 expect=main.TRUE,
1572 actual=sameIntents,
1573 onpass="Intents are consistent with before failure",
1574 onfail="The Intents changed during failure" )
Jon Hall85794ff2015-07-08 14:12:30 -07001575 intentCheck = intentCheck and sameIntents
1576 """
1577 main.step( "Get the OF Table entries and compare to before " +
1578 "component failure" )
1579 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001580 for i in range( 28 ):
1581 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001582 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
Jon Hallf37d44d2017-05-24 10:37:30 -07001583 curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
Jon Hall41d39f12016-04-11 22:54:35 -07001584 FlowTables = FlowTables and curSwitch
1585 if curSwitch == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001586 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001587 utilities.assert_equals(
1588 expect=main.TRUE,
1589 actual=FlowTables,
1590 onpass="No changes were found in the flow tables",
1591 onfail="Changes were found in the flow tables" )
1592
1593 main.step( "Leadership Election is still functional" )
1594 # Test of LeadershipElection
1595
Jon Halla440e872016-03-31 15:15:50 -07001596 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001597 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001598 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001599 # loop through ONOScli handlers
1600 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1601 leaderN = node.electionTestLeader()
1602 # verify leader is ONOS1
1603 # NOTE even though we restarted ONOS, it is the only one so onos 1
1604 # must be leader
1605 if leaderN == leader:
1606 # all is well
1607 pass
1608 elif leaderN == main.FALSE:
1609 # error in response
1610 main.log.error( "Something is wrong with " +
1611 "electionTestLeader function, check the" +
1612 " error logs" )
1613 leaderResult = main.FALSE
1614 elif leader != leaderN:
1615 leaderResult = main.FALSE
1616 main.log.error( "ONOS" + str( controller ) + " sees " +
1617 str( leaderN ) +
1618 " as the leader of the election app. " +
1619 "Leader should be " + str( leader ) )
1620 utilities.assert_equals(
1621 expect=main.TRUE,
1622 actual=leaderResult,
1623 onpass="Leadership election passed",
1624 onfail="Something went wrong with Leadership election" )
1625
1626 def CASE8( self, main ):
1627 """
1628 Compare topo
1629 """
1630 import json
1631 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001632 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001633 assert main, "main not defined"
1634 assert utilities.assert_equals, "utilities.assert_equals not defined"
1635
1636 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001637 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001638 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001639 topoResult = main.FALSE
1640 elapsed = 0
1641 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001642 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001643 startTime = time.time()
1644 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001645 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001646 devicesResults = main.TRUE
1647 linksResults = main.TRUE
1648 hostsResults = main.TRUE
1649 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001650 count += 1
1651 cliStart = time.time()
1652 devices = []
1653 devices.append( main.ONOScli1.devices() )
1654 hosts = []
1655 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1656 ipResult = main.TRUE
1657 for controller in range( 0, len( hosts ) ):
1658 controllerStr = str( controller + 1 )
1659 for host in hosts[ controller ]:
1660 if host is None or host.get( 'ipAddresses', [] ) == []:
1661 main.log.error(
1662 "DEBUG:Error with host ips on controller" +
1663 controllerStr + ": " + str( host ) )
1664 ipResult = main.FALSE
1665 ports = []
1666 ports.append( main.ONOScli1.ports() )
1667 links = []
1668 links.append( main.ONOScli1.links() )
1669 clusters = []
1670 clusters.append( main.ONOScli1.clusters() )
1671
1672 elapsed = time.time() - startTime
1673 cliTime = time.time() - cliStart
1674 print "CLI time: " + str( cliTime )
1675
1676 mnSwitches = main.Mininet1.getSwitches()
1677 mnLinks = main.Mininet1.getLinks()
1678 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001679 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001680 controllerStr = str( controller + 1 )
1681 if devices[ controller ] and ports[ controller ] and\
Jon Hallf37d44d2017-05-24 10:37:30 -07001682 "Error" not in devices[ controller ] and\
1683 "Error" not in ports[ controller ]:
Jon Hall85794ff2015-07-08 14:12:30 -07001684
Jon Hallc6793552016-01-19 14:18:37 -08001685 try:
1686 currentDevicesResult = main.Mininet1.compareSwitches(
1687 mnSwitches,
1688 json.loads( devices[ controller ] ),
1689 json.loads( ports[ controller ] ) )
1690 except ( TypeError, ValueError ) as e:
1691 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
1692 devices[ controller ], ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001693 else:
1694 currentDevicesResult = main.FALSE
1695 utilities.assert_equals( expect=main.TRUE,
1696 actual=currentDevicesResult,
1697 onpass="ONOS" + controllerStr +
1698 " Switches view is correct",
1699 onfail="ONOS" + controllerStr +
1700 " Switches view is incorrect" )
1701
1702 if links[ controller ] and "Error" not in links[ controller ]:
1703 currentLinksResult = main.Mininet1.compareLinks(
1704 mnSwitches, mnLinks,
1705 json.loads( links[ controller ] ) )
1706 else:
1707 currentLinksResult = main.FALSE
1708 utilities.assert_equals( expect=main.TRUE,
1709 actual=currentLinksResult,
1710 onpass="ONOS" + controllerStr +
1711 " links view is correct",
1712 onfail="ONOS" + controllerStr +
1713 " links view is incorrect" )
1714
1715 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1716 currentHostsResult = main.Mininet1.compareHosts(
1717 mnHosts,
1718 hosts[ controller ] )
1719 else:
1720 currentHostsResult = main.FALSE
1721 utilities.assert_equals( expect=main.TRUE,
1722 actual=currentHostsResult,
1723 onpass="ONOS" + controllerStr +
1724 " hosts exist in Mininet",
1725 onfail="ONOS" + controllerStr +
1726 " hosts don't match Mininet" )
1727 # CHECKING HOST ATTACHMENT POINTS
1728 hostAttachment = True
1729 zeroHosts = False
1730 # FIXME: topo-HA/obelisk specific mappings:
1731 # key is mac and value is dpid
1732 mappings = {}
1733 for i in range( 1, 29 ): # hosts 1 through 28
1734 # set up correct variables:
Jon Hallf37d44d2017-05-24 10:37:30 -07001735 macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
Jon Hall85794ff2015-07-08 14:12:30 -07001736 if i == 1:
Jon Hallf37d44d2017-05-24 10:37:30 -07001737 deviceId = "1000".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001738 elif i == 2:
Jon Hallf37d44d2017-05-24 10:37:30 -07001739 deviceId = "2000".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001740 elif i == 3:
Jon Hallf37d44d2017-05-24 10:37:30 -07001741 deviceId = "3000".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001742 elif i == 4:
Jon Hallf37d44d2017-05-24 10:37:30 -07001743 deviceId = "3004".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001744 elif i == 5:
Jon Hallf37d44d2017-05-24 10:37:30 -07001745 deviceId = "5000".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001746 elif i == 6:
Jon Hallf37d44d2017-05-24 10:37:30 -07001747 deviceId = "6000".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001748 elif i == 7:
Jon Hallf37d44d2017-05-24 10:37:30 -07001749 deviceId = "6007".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001750 elif i >= 8 and i <= 17:
1751 dpid = '3' + str( i ).zfill( 3 )
Jon Hallf37d44d2017-05-24 10:37:30 -07001752 deviceId = dpid.zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001753 elif i >= 18 and i <= 27:
1754 dpid = '6' + str( i ).zfill( 3 )
Jon Hallf37d44d2017-05-24 10:37:30 -07001755 deviceId = dpid.zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001756 elif i == 28:
Jon Hallf37d44d2017-05-24 10:37:30 -07001757 deviceId = "2800".zfill( 16 )
Jon Hall85794ff2015-07-08 14:12:30 -07001758 mappings[ macId ] = deviceId
1759 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1760 if hosts[ controller ] == []:
1761 main.log.warn( "There are no hosts discovered" )
1762 zeroHosts = True
1763 else:
1764 for host in hosts[ controller ]:
1765 mac = None
1766 location = None
1767 device = None
1768 port = None
1769 try:
1770 mac = host.get( 'mac' )
1771 assert mac, "mac field could not be found for this host object"
1772
1773 location = host.get( 'location' )
1774 assert location, "location field could not be found for this host object"
1775
1776 # Trim the protocol identifier off deviceId
Jon Hallf37d44d2017-05-24 10:37:30 -07001777 device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
Jon Hall85794ff2015-07-08 14:12:30 -07001778 assert device, "elementId field could not be found for this host location object"
1779
1780 port = location.get( 'port' )
1781 assert port, "port field could not be found for this host location object"
1782
1783 # Now check if this matches where they should be
1784 if mac and device and port:
1785 if str( port ) != "1":
1786 main.log.error( "The attachment port is incorrect for " +
1787 "host " + str( mac ) +
Jon Hallf37d44d2017-05-24 10:37:30 -07001788 ". Expected: 1 Actual: " + str( port ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001789 hostAttachment = False
1790 if device != mappings[ str( mac ) ]:
1791 main.log.error( "The attachment device is incorrect for " +
1792 "host " + str( mac ) +
1793 ". Expected: " + mappings[ str( mac ) ] +
1794 " Actual: " + device )
1795 hostAttachment = False
1796 else:
1797 hostAttachment = False
1798 except AssertionError:
1799 main.log.exception( "Json object not as expected" )
1800 main.log.error( repr( host ) )
1801 hostAttachment = False
1802 else:
1803 main.log.error( "No hosts json output or \"Error\"" +
1804 " in output. hosts = " +
1805 repr( hosts[ controller ] ) )
1806 if zeroHosts is False:
1807 hostAttachment = True
1808
Jon Hall85794ff2015-07-08 14:12:30 -07001809 devicesResults = devicesResults and currentDevicesResult
1810 linksResults = linksResults and currentLinksResult
1811 hostsResults = hostsResults and currentHostsResult
1812 hostAttachmentResults = hostAttachmentResults and\
1813 hostAttachment
1814
Jon Halla440e872016-03-31 15:15:50 -07001815 # "consistent" results don't make sense for single instance
Jon Hall85794ff2015-07-08 14:12:30 -07001816 # there should always only be one cluster
Jon Hall85794ff2015-07-08 14:12:30 -07001817 clusterResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001818 try:
1819 numClusters = len( json.loads( clusters[ 0 ] ) )
1820 except ( ValueError, TypeError ):
1821 main.log.exception( "Error parsing clusters[0]: " +
Jon Hallf37d44d2017-05-24 10:37:30 -07001822 repr( clusters[ 0 ] ) )
Jon Halla440e872016-03-31 15:15:50 -07001823 numClusters = "ERROR"
1824 clusterResults = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001825 if numClusters == 1:
1826 clusterResults = main.TRUE
1827 utilities.assert_equals(
1828 expect=1,
1829 actual=numClusters,
1830 onpass="ONOS shows 1 SCC",
1831 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1832
1833 topoResult = ( devicesResults and linksResults
1834 and hostsResults and ipResult and clusterResults and
1835 hostAttachmentResults )
1836
1837 topoResult = topoResult and int( count <= 2 )
1838 note = "note it takes about " + str( int( cliTime ) ) + \
1839 " seconds for the test to make all the cli calls to fetch " +\
1840 "the topology from each ONOS instance"
1841 main.log.info(
1842 "Very crass estimate for topology discovery/convergence( " +
1843 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1844 str( count ) + " tries" )
1845 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1846 onpass="Topology Check Test successful",
1847 onfail="Topology Check Test NOT successful" )
Jon Hall41d39f12016-04-11 22:54:35 -07001848 main.step( "Checking ONOS nodes" )
1849 nodeResults = utilities.retry( main.HA.nodesCheck,
1850 False,
Jon Hallf37d44d2017-05-24 10:37:30 -07001851 args=[ main.activeNodes ],
Jon Hall41d39f12016-04-11 22:54:35 -07001852 attempts=5 )
1853
1854 utilities.assert_equals( expect=True, actual=nodeResults,
1855 onpass="Nodes check successful",
1856 onfail="Nodes check NOT successful" )
1857 if not nodeResults:
1858 for i in main.activeNodes:
1859 main.log.debug( "{} components not ACTIVE: \n{}".format(
Jon Hallf37d44d2017-05-24 10:37:30 -07001860 main.CLIs[ i ].name,
1861 main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001862
Jon Halld2871c22016-07-26 11:01:14 -07001863 if not topoResult:
1864 main.cleanup()
1865 main.exit()
1866
Jon Hall85794ff2015-07-08 14:12:30 -07001867 def CASE9( self, main ):
1868 """
1869 Link s3-s28 down
1870 """
1871 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001872 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001873 assert main, "main not defined"
1874 assert utilities.assert_equals, "utilities.assert_equals not defined"
1875 # NOTE: You should probably run a topology check after this
1876
1877 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1878
1879 description = "Turn off a link to ensure that Link Discovery " +\
1880 "is working properly"
1881 main.case( description )
1882
1883 main.step( "Kill Link between s3 and s28" )
1884 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1885 main.log.info( "Waiting " + str( linkSleep ) +
1886 " seconds for link down to be discovered" )
1887 time.sleep( linkSleep )
1888 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1889 onpass="Link down successful",
1890 onfail="Failed to bring link down" )
1891 # TODO do some sort of check here
1892
1893 def CASE10( self, main ):
1894 """
1895 Link s3-s28 up
1896 """
1897 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001898 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001899 assert main, "main not defined"
1900 assert utilities.assert_equals, "utilities.assert_equals not defined"
1901 # NOTE: You should probably run a topology check after this
1902
1903 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1904
1905 description = "Restore a link to ensure that Link Discovery is " + \
1906 "working properly"
1907 main.case( description )
1908
1909 main.step( "Bring link between s3 and s28 back up" )
1910 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1911 main.log.info( "Waiting " + str( linkSleep ) +
1912 " seconds for link up to be discovered" )
1913 time.sleep( linkSleep )
1914 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1915 onpass="Link up successful",
1916 onfail="Failed to bring link up" )
1917 # TODO do some sort of check here
1918
1919 def CASE11( self, main ):
1920 """
1921 Switch Down
1922 """
1923 # NOTE: You should probably run a topology check after this
1924 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001925 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001926 assert main, "main not defined"
1927 assert utilities.assert_equals, "utilities.assert_equals not defined"
1928
1929 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1930
1931 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallf37d44d2017-05-24 10:37:30 -07001932 onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001933 main.case( description )
1934 switch = main.params[ 'kill' ][ 'switch' ]
1935 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1936
1937 # TODO: Make this switch parameterizable
1938 main.step( "Kill " + switch )
1939 main.log.info( "Deleting " + switch )
1940 main.Mininet1.delSwitch( switch )
1941 main.log.info( "Waiting " + str( switchSleep ) +
1942 " seconds for switch down to be discovered" )
1943 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001944 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001945 # Peek at the deleted switch
1946 main.log.warn( str( device ) )
1947 result = main.FALSE
1948 if device and device[ 'available' ] is False:
1949 result = main.TRUE
1950 utilities.assert_equals( expect=main.TRUE, actual=result,
1951 onpass="Kill switch successful",
1952 onfail="Failed to kill switch?" )
1953
1954 def CASE12( self, main ):
1955 """
1956 Switch Up
1957 """
1958 # NOTE: You should probably run a topology check after this
1959 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001960 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001961 assert main, "main not defined"
1962 assert utilities.assert_equals, "utilities.assert_equals not defined"
1963
1964 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1965 switch = main.params[ 'kill' ][ 'switch' ]
1966 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1967 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallf37d44d2017-05-24 10:37:30 -07001968 onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001969 description = "Adding a switch to ensure it is discovered correctly"
1970 main.case( description )
1971
1972 main.step( "Add back " + switch )
1973 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1974 for peer in links:
1975 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07001976 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall85794ff2015-07-08 14:12:30 -07001977 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1978 main.log.info( "Waiting " + str( switchSleep ) +
1979 " seconds for switch up to be discovered" )
1980 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001981 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001982 # Peek at the deleted switch
1983 main.log.warn( str( device ) )
1984 result = main.FALSE
1985 if device and device[ 'available' ]:
1986 result = main.TRUE
1987 utilities.assert_equals( expect=main.TRUE, actual=result,
1988 onpass="add switch successful",
1989 onfail="Failed to add switch?" )
1990
1991 def CASE13( self, main ):
1992 """
1993 Clean up
1994 """
1995 import os
1996 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001997 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001998 assert main, "main not defined"
1999 assert utilities.assert_equals, "utilities.assert_equals not defined"
2000 # printing colors to terminal
2001 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2002 'blue': '\033[94m', 'green': '\033[92m',
2003 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2004 main.case( "Test Cleanup" )
2005 main.step( "Killing tcpdumps" )
2006 main.Mininet2.stopTcpdump()
2007
2008 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002009 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07002010 main.step( "Copying MN pcap and ONOS log files to test station" )
2011 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2012 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002013 # NOTE: MN Pcap file is being saved to logdir.
2014 # We scp this file as MN and TestON aren't necessarily the same vm
2015
2016 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07002017 # TODO: Load these from params
2018 # NOTE: must end in /
2019 logFolder = "/opt/onos/log/"
2020 logFiles = [ "karaf.log", "karaf.log.1" ]
2021 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002022 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002023 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002024 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002025 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2026 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07002027 # std*.log's
2028 # NOTE: must end in /
2029 logFolder = "/opt/onos/var/"
2030 logFiles = [ "stderr.log", "stdout.log" ]
2031 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002032 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002033 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002034 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002035 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2036 logFolder + f, dstName )
2037 else:
2038 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07002039
Jon Hall85794ff2015-07-08 14:12:30 -07002040 main.step( "Stopping Mininet" )
2041 mnResult = main.Mininet1.stopNet()
2042 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2043 onpass="Mininet stopped",
2044 onfail="MN cleanup NOT successful" )
2045
2046 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07002047 for node in main.nodes:
2048 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2049 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07002050
2051 try:
Jon Hallf37d44d2017-05-24 10:37:30 -07002052 timerLog = open( main.logdir + "/Timers.csv", 'w' )
Jon Hall85794ff2015-07-08 14:12:30 -07002053 # Overwrite with empty line and close
2054 labels = "Gossip Intents, Restart"
2055 data = str( gossipTime ) + ", " + str( main.restartTime )
2056 timerLog.write( labels + "\n" + data )
2057 timerLog.close()
Jon Hallf37d44d2017-05-24 10:37:30 -07002058 except NameError as e:
2059 main.log.exception( e )
Jon Hall85794ff2015-07-08 14:12:30 -07002060
2061 def CASE14( self, main ):
2062 """
2063 start election app on all onos nodes
2064 """
Jon Halle1a3b752015-07-22 13:02:46 -07002065 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002066 assert main, "main not defined"
2067 assert utilities.assert_equals, "utilities.assert_equals not defined"
2068
Jon Hallf37d44d2017-05-24 10:37:30 -07002069 main.case( "Start Leadership Election app" )
Jon Hall85794ff2015-07-08 14:12:30 -07002070 main.step( "Install leadership election app" )
Jon Hallf37d44d2017-05-24 10:37:30 -07002071 onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
Jon Halla440e872016-03-31 15:15:50 -07002072 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002073 utilities.assert_equals(
2074 expect=main.TRUE,
2075 actual=appResult,
2076 onpass="Election app installed",
2077 onfail="Something went wrong with installing Leadership election" )
2078
2079 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002080 for i in main.activeNodes:
Jon Hallf37d44d2017-05-24 10:37:30 -07002081 main.CLIs[ i ].electionTestRun()
2082 time.sleep( 5 )
2083 activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
Jon Hall25463a82016-04-13 14:03:52 -07002084 sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall85794ff2015-07-08 14:12:30 -07002085 utilities.assert_equals(
Jon Hall25463a82016-04-13 14:03:52 -07002086 expect=True,
2087 actual=sameResult,
2088 onpass="All nodes see the same leaderboards",
2089 onfail="Inconsistent leaderboards" )
2090
2091 if sameResult:
2092 leader = leaders[ 0 ][ 0 ]
Jon Hallf37d44d2017-05-24 10:37:30 -07002093 if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
Jon Hall25463a82016-04-13 14:03:52 -07002094 correctLeader = True
2095 else:
2096 correctLeader = False
2097 main.step( "First node was elected leader" )
2098 utilities.assert_equals(
2099 expect=True,
2100 actual=correctLeader,
2101 onpass="Correct leader was elected",
2102 onfail="Incorrect leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002103
2104 def CASE15( self, main ):
2105 """
2106 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002107 15.1 Run election on each node
2108 15.2 Check that each node has the same leaders and candidates
2109 15.3 Find current leader and withdraw
2110 15.4 Check that a new node was elected leader
2111 15.5 Check that that new leader was the candidate of old leader
2112 15.6 Run for election on old leader
2113 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2114 15.8 Make sure that the old leader was added to the candidate list
2115
2116 old and new variable prefixes refer to data from before vs after
2117 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07002118 """
acsmars71adceb2015-08-31 15:09:26 -07002119 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002120 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002121 assert main, "main not defined"
2122 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07002123 assert main.CLIs, "main.CLIs not defined"
2124 assert main.nodes, "main.nodes not defined"
2125
Jon Hall85794ff2015-07-08 14:12:30 -07002126 description = "Check that Leadership Election is still functional"
2127 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002128 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars2c2fcdd2015-08-25 17:14:13 -07002129
Jon Halla440e872016-03-31 15:15:50 -07002130 oldLeaders = [] # list of lists of each nodes' candidates before
2131 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002132 oldLeader = '' # the old leader from oldLeaders, None if not same
2133 newLeader = '' # the new leaders fron newLoeaders, None if not same
2134 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2135 expectNoLeader = False # True when there is only one leader
2136 if main.numCtrls == 1:
2137 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07002138
acsmars71adceb2015-08-31 15:09:26 -07002139 main.step( "Run for election on each node" )
2140 electionResult = main.TRUE
2141
Jon Halla440e872016-03-31 15:15:50 -07002142 for i in main.activeNodes: # run test election on each node
Jon Hallf37d44d2017-05-24 10:37:30 -07002143 if main.CLIs[ i ].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002144 electionResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002145 utilities.assert_equals(
2146 expect=main.TRUE,
2147 actual=electionResult,
2148 onpass="All nodes successfully ran for leadership",
2149 onfail="At least one node failed to run for leadership" )
2150
acsmars3a72bde2015-09-02 14:16:22 -07002151 if electionResult == main.FALSE:
2152 main.log.error(
2153 "Skipping Test Case because Election Test App isn't loaded" )
2154 main.skipCase()
2155
acsmars71adceb2015-08-31 15:09:26 -07002156 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002157 failMessage = "Nodes have different leaderboards"
Jon Hallf37d44d2017-05-24 10:37:30 -07002158 activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
Jon Hall41d39f12016-04-11 22:54:35 -07002159 sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Halla440e872016-03-31 15:15:50 -07002160 if sameResult:
2161 oldLeader = oldLeaders[ 0 ][ 0 ]
2162 main.log.warn( oldLeader )
Jon Hall85794ff2015-07-08 14:12:30 -07002163 else:
Jon Halla440e872016-03-31 15:15:50 -07002164 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002165 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002166 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002167 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002168 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002169 onfail=failMessage )
2170
2171 main.step( "Find current leader and withdraw" )
2172 withdrawResult = main.TRUE
2173 # do some sanity checking on leader before using it
2174 if oldLeader is None:
2175 main.log.error( "Leadership isn't consistent." )
2176 withdrawResult = main.FALSE
2177 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002178 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002179 if oldLeader == main.nodes[ i ].ip_address:
2180 oldLeaderCLI = main.CLIs[ i ]
2181 break
2182 else: # FOR/ELSE statement
2183 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002184 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002185 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07002186 utilities.assert_equals(
2187 expect=main.TRUE,
2188 actual=withdrawResult,
2189 onpass="Node was withdrawn from election",
2190 onfail="Node was not withdrawn from election" )
2191
acsmars71adceb2015-08-31 15:09:26 -07002192 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002193 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002194 # Get new leaders and candidates
Jon Hall41d39f12016-04-11 22:54:35 -07002195 newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall3a7843a2016-04-12 03:01:09 -07002196 newLeader = None
Jon Halla440e872016-03-31 15:15:50 -07002197 if newLeaderResult:
Jon Hall3a7843a2016-04-12 03:01:09 -07002198 if newLeaders[ 0 ][ 0 ] == 'none':
2199 main.log.error( "No leader was elected on at least 1 node" )
2200 if not expectNoLeader:
2201 newLeaderResult = False
Jon Hall25463a82016-04-13 14:03:52 -07002202 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002203
2204 # Check that the new leader is not the older leader, which was withdrawn
2205 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002206 newLeaderResult = False
2207 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
Jon Hallf37d44d2017-05-24 10:37:30 -07002208 " as the current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002209 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002210 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002211 actual=newLeaderResult,
2212 onpass="Leadership election passed",
2213 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002214
Jon Halla440e872016-03-31 15:15:50 -07002215 main.step( "Check that that new leader was the candidate of old leader" )
2216 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002217 correctCandidateResult = main.TRUE
2218 if expectNoLeader:
2219 if newLeader == 'none':
2220 main.log.info( "No leader expected. None found. Pass" )
2221 correctCandidateResult = main.TRUE
2222 else:
2223 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2224 correctCandidateResult = main.FALSE
Jon Hallf37d44d2017-05-24 10:37:30 -07002225 elif len( oldLeaders[ 0 ] ) >= 3:
Jon Halla440e872016-03-31 15:15:50 -07002226 if newLeader == oldLeaders[ 0 ][ 2 ]:
2227 # correct leader was elected
2228 correctCandidateResult = main.TRUE
2229 else:
2230 correctCandidateResult = main.FALSE
2231 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
2232 newLeader, oldLeaders[ 0 ][ 2 ] ) )
2233 else:
2234 main.log.warn( "Could not determine who should be the correct leader" )
2235 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07002236 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002237 utilities.assert_equals(
2238 expect=main.TRUE,
2239 actual=correctCandidateResult,
2240 onpass="Correct Candidate Elected",
2241 onfail="Incorrect Candidate Elected" )
2242
Jon Hall85794ff2015-07-08 14:12:30 -07002243 main.step( "Run for election on old leader( just so everyone " +
2244 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002245 if oldLeaderCLI is not None:
2246 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002247 else:
acsmars71adceb2015-08-31 15:09:26 -07002248 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002249 runResult = main.FALSE
2250 utilities.assert_equals(
2251 expect=main.TRUE,
2252 actual=runResult,
2253 onpass="App re-ran for election",
2254 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07002255
acsmars71adceb2015-08-31 15:09:26 -07002256 main.step(
2257 "Check that oldLeader is a candidate, and leader if only 1 node" )
2258 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07002259 # Get new leaders and candidates
2260 reRunLeaders = []
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002261 time.sleep( 5 ) # Paremterize
Jon Hall41d39f12016-04-11 22:54:35 -07002262 positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07002263
2264 # Check that the re-elected node is last on the candidate List
Jon Hallf37d44d2017-05-24 10:37:30 -07002265 if not reRunLeaders[ 0 ]:
Jon Hall3a7843a2016-04-12 03:01:09 -07002266 positionResult = main.FALSE
2267 elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
Jon Hallf37d44d2017-05-24 10:37:30 -07002268 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
Jon Halla440e872016-03-31 15:15:50 -07002269 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07002270 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002271 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002272 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002273 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002274 onpass="Old leader successfully re-ran for election",
2275 onfail="Something went wrong with Leadership election after " +
2276 "the old leader re-ran for election" )
2277
2278 def CASE16( self, main ):
2279 """
2280 Install Distributed Primitives app
2281 """
Jon Halla440e872016-03-31 15:15:50 -07002282 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002283 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002284 assert main, "main not defined"
2285 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002286 assert main.CLIs, "main.CLIs not defined"
2287 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002288
2289 # Variables for the distributed primitives tests
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002290 main.pCounterName = "TestON-Partitions"
2291 main.pCounterValue = 0
Jon Hallf37d44d2017-05-24 10:37:30 -07002292 main.onosSet = set( [] )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002293 main.onosSetName = "TestON-set"
Jon Hall85794ff2015-07-08 14:12:30 -07002294
2295 description = "Install Primitives app"
2296 main.case( description )
2297 main.step( "Install Primitives app" )
2298 appName = "org.onosproject.distributedprimitives"
Jon Hallf37d44d2017-05-24 10:37:30 -07002299 node = main.activeNodes[ 0 ]
2300 appResults = main.CLIs[ node ].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002301 utilities.assert_equals( expect=main.TRUE,
2302 actual=appResults,
2303 onpass="Primitives app activated",
2304 onfail="Primitives app not activated" )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002305 # TODO check on all nodes instead of sleeping
Jon Halla440e872016-03-31 15:15:50 -07002306 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall85794ff2015-07-08 14:12:30 -07002307
2308 def CASE17( self, main ):
2309 """
2310 Check for basic functionality with distributed primitives
2311 """
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002312 main.HA.CASE17( main )