blob: 6bb32e234ad6ca76bb3fcececf7096e779ce56fd [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
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"""
25
26
27class HAclusterRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Halla440e872016-03-31 15:15:50 -070052 import json
Jon Hall5cf14d52015-07-16 12:15:19 -070053 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
54 "initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall5cf14d52015-07-16 12:15:19 -070059
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
71 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79 # These are for csv plotting in jenkins
80 global labels
81 global data
82 labels = []
83 data = []
84
85 # FIXME: just get controller port from params?
86 # TODO: do we really need all these?
87 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
88 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
89 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
90 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
91 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
92 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
93 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
94
Jon Halle1a3b752015-07-22 13:02:46 -070095 try:
Jon Hall53c5e662016-04-13 16:06:56 -070096 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070097 main.HA = HA()
Jon Halle1a3b752015-07-22 13:02:46 -070098 except Exception as e:
99 main.log.exception( e )
100 main.cleanup()
101 main.exit()
102
103 main.CLIs = []
104 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700105 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700106 for i in range( 1, main.numCtrls + 1 ):
107 try:
108 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
109 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
110 ipList.append( main.nodes[ -1 ].ip_address )
111 except AttributeError:
112 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700113
114 main.step( "Create cell file" )
115 cellAppString = main.params[ 'ENV' ][ 'appString' ]
116 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
117 main.Mininet1.ip_address,
118 cellAppString, ipList )
119 main.step( "Applying cell variable to environment" )
120 cellResult = main.ONOSbench.setCell( cellName )
121 verifyResult = main.ONOSbench.verifyCell()
122
123 # FIXME:this is short term fix
124 main.log.info( "Removing raft logs" )
125 main.ONOSbench.onosRemoveRaftLogs()
126
127 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700128 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700129 main.ONOSbench.onosUninstall( node.ip_address )
130
131 # Make sure ONOS is DEAD
132 main.log.info( "Killing any ONOS processes" )
133 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700134 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700135 killed = main.ONOSbench.onosKill( node.ip_address )
136 killResults = killResults and killed
137
138 cleanInstallResult = main.TRUE
139 gitPullResult = main.TRUE
140
141 main.step( "Starting Mininet" )
142 # scp topo file to mininet
143 # TODO: move to params?
144 topoName = "obelisk.py"
145 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700146 main.ONOSbench.scp( main.Mininet1,
147 filePath + topoName,
148 main.Mininet1.home,
149 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700150 mnResult = main.Mininet1.startNet( )
151 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
152 onpass="Mininet Started",
153 onfail="Error starting Mininet" )
154
155 main.step( "Git checkout and pull " + gitBranch )
156 if PULLCODE:
157 main.ONOSbench.gitCheckout( gitBranch )
158 gitPullResult = main.ONOSbench.gitPull()
159 # values of 1 or 3 are good
160 utilities.assert_lesser( expect=0, actual=gitPullResult,
161 onpass="Git pull successful",
162 onfail="Git pull failed" )
163 main.ONOSbench.getVersion( report=True )
164
165 main.step( "Using mvn clean install" )
166 cleanInstallResult = main.TRUE
167 if PULLCODE and gitPullResult == main.TRUE:
168 cleanInstallResult = main.ONOSbench.cleanInstall()
169 else:
170 main.log.warn( "Did not pull new code so skipping mvn " +
171 "clean install" )
172 utilities.assert_equals( expect=main.TRUE,
173 actual=cleanInstallResult,
174 onpass="MCI successful",
175 onfail="MCI failed" )
176 # GRAPHS
177 # NOTE: important params here:
178 # job = name of Jenkins job
179 # Plot Name = Plot-HA, only can be used if multiple plots
180 # index = The number of the graph under plot name
181 job = "HAclusterRestart"
182 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700183 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700184 graphs = '<ac:structured-macro ac:name="html">\n'
185 graphs += '<ac:plain-text-body><![CDATA[\n'
186 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800187 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700188 '&width=500&height=300"' +\
189 'noborder="0" width="500" height="300" scrolling="yes" ' +\
190 'seamless="seamless"></iframe>\n'
191 graphs += ']]></ac:plain-text-body>\n'
192 graphs += '</ac:structured-macro>\n'
193 main.log.wiki(graphs)
194
195 main.step( "Creating ONOS package" )
196 packageResult = main.ONOSbench.onosPackage()
197 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
198 onpass="ONOS package successful",
199 onfail="ONOS package failed" )
200
201 main.step( "Installing ONOS package" )
202 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700203 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700204 tmpResult = main.ONOSbench.onosInstall( options="-f",
205 node=node.ip_address )
206 onosInstallResult = onosInstallResult and tmpResult
207 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
208 onpass="ONOS install successful",
209 onfail="ONOS install failed" )
210
211 main.step( "Checking if ONOS is up yet" )
212 for i in range( 2 ):
213 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700214 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 started = main.ONOSbench.isup( node.ip_address )
216 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800217 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700218 onosIsupResult = onosIsupResult and started
219 if onosIsupResult == main.TRUE:
220 break
221 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
222 onpass="ONOS startup successful",
223 onfail="ONOS startup failed" )
224
225 main.log.step( "Starting ONOS CLI sessions" )
226 cliResults = main.TRUE
227 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700228 for i in range( main.numCtrls ):
229 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700230 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700231 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 threads.append( t )
233 t.start()
234
235 for t in threads:
236 t.join()
237 cliResults = cliResults and t.result
238 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
239 onpass="ONOS cli startup successful",
240 onfail="ONOS cli startup failed" )
241
Jon Halla440e872016-03-31 15:15:50 -0700242 # Create a list of active nodes for use when some nodes are stopped
243 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
244
Jon Hall5cf14d52015-07-16 12:15:19 -0700245 if main.params[ 'tcpdump' ].lower() == "true":
246 main.step( "Start Packet Capture MN" )
247 main.Mininet2.startTcpdump(
248 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
249 + "-MN.pcap",
250 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
251 port=main.params[ 'MNtcpdump' ][ 'port' ] )
252
Jon Halla440e872016-03-31 15:15:50 -0700253 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -0700254 nodeResults = utilities.retry( main.HA.nodesCheck,
255 False,
256 args=[main.activeNodes],
257 attempts=5 )
Jon Halla440e872016-03-31 15:15:50 -0700258
Jon Hall41d39f12016-04-11 22:54:35 -0700259 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Halla440e872016-03-31 15:15:50 -0700260 onpass="Nodes check successful",
261 onfail="Nodes check NOT successful" )
262
263 if not nodeResults:
Jon Hall7ac7bc32016-05-05 10:57:02 -0700264 for i in main.activeNodes:
265 cli = main.CLIs[i]
Jon Halla440e872016-03-31 15:15:50 -0700266 main.log.debug( "{} components not ACTIVE: \n{}".format(
267 cli.name,
268 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
269
Jon Hall5cf14d52015-07-16 12:15:19 -0700270 if cliResults == main.FALSE:
271 main.log.error( "Failed to start ONOS, stopping test" )
272 main.cleanup()
273 main.exit()
274
Jon Hall172b7ba2016-04-07 18:12:20 -0700275 main.step( "Activate apps defined in the params file" )
276 # get data from the params
277 apps = main.params.get( 'apps' )
278 if apps:
279 apps = apps.split(',')
280 main.log.warn( apps )
281 activateResult = True
282 for app in apps:
283 main.CLIs[ 0 ].app( app, "Activate" )
284 # TODO: check this worked
285 time.sleep( 10 ) # wait for apps to activate
286 for app in apps:
287 state = main.CLIs[ 0 ].appStatus( app )
288 if state == "ACTIVE":
289 activateResult = activeResult and True
290 else:
291 main.log.error( "{} is in {} state".format( app, state ) )
292 activeResult = False
293 utilities.assert_equals( expect=True,
294 actual=activateResult,
295 onpass="Successfully activated apps",
296 onfail="Failed to activate apps" )
297 else:
298 main.log.warn( "No apps were specified to be loaded after startup" )
299
300 main.step( "Set ONOS configurations" )
301 config = main.params.get( 'ONOS_Configuration' )
302 if config:
303 main.log.debug( config )
304 checkResult = main.TRUE
305 for component in config:
306 for setting in config[component]:
307 value = config[component][setting]
308 check = main.CLIs[ 0 ].setCfg( component, setting, value )
309 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
310 checkResult = check and checkResult
311 utilities.assert_equals( expect=main.TRUE,
312 actual=checkResult,
313 onpass="Successfully set config",
314 onfail="Failed to set config" )
315 else:
316 main.log.warn( "No configurations were specified to be changed after startup" )
317
Jon Hall9d2dcad2016-04-08 10:15:20 -0700318 main.step( "App Ids check" )
319 appCheck = main.TRUE
320 threads = []
321 for i in main.activeNodes:
322 t = main.Thread( target=main.CLIs[i].appToIDCheck,
323 name="appToIDCheck-" + str( i ),
324 args=[] )
325 threads.append( t )
326 t.start()
327
328 for t in threads:
329 t.join()
330 appCheck = appCheck and t.result
331 if appCheck != main.TRUE:
332 node = main.activeNodes[0]
333 main.log.warn( main.CLIs[node].apps() )
334 main.log.warn( main.CLIs[node].appIDs() )
335 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
336 onpass="App Ids seem to be correct",
337 onfail="Something is wrong with app Ids" )
338
Jon Hall5cf14d52015-07-16 12:15:19 -0700339 def CASE2( self, main ):
340 """
341 Assign devices to controllers
342 """
343 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700344 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700345 assert main, "main not defined"
346 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700347 assert main.CLIs, "main.CLIs not defined"
348 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700349 assert ONOS1Port, "ONOS1Port not defined"
350 assert ONOS2Port, "ONOS2Port not defined"
351 assert ONOS3Port, "ONOS3Port not defined"
352 assert ONOS4Port, "ONOS4Port not defined"
353 assert ONOS5Port, "ONOS5Port not defined"
354 assert ONOS6Port, "ONOS6Port not defined"
355 assert ONOS7Port, "ONOS7Port not defined"
356
357 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700358 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700359 "and check that an ONOS node becomes the " +\
360 "master of the device."
361 main.step( "Assign switches to controllers" )
362
363 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700364 for i in range( main.numCtrls ):
365 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700366 swList = []
367 for i in range( 1, 29 ):
368 swList.append( "s" + str( i ) )
369 main.Mininet1.assignSwController( sw=swList, ip=ipList )
370
371 mastershipCheck = main.TRUE
372 for i in range( 1, 29 ):
373 response = main.Mininet1.getSwController( "s" + str( i ) )
374 try:
375 main.log.info( str( response ) )
376 except Exception:
377 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700378 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700379 if re.search( "tcp:" + node.ip_address, response ):
380 mastershipCheck = mastershipCheck and main.TRUE
381 else:
382 main.log.error( "Error, node " + node.ip_address + " is " +
383 "not in the list of controllers s" +
384 str( i ) + " is connecting to." )
385 mastershipCheck = main.FALSE
386 utilities.assert_equals(
387 expect=main.TRUE,
388 actual=mastershipCheck,
389 onpass="Switch mastership assigned correctly",
390 onfail="Switches not assigned correctly to controllers" )
391
392 def CASE21( self, main ):
393 """
394 Assign mastership to controllers
395 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700396 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700397 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700398 assert main, "main not defined"
399 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700400 assert main.CLIs, "main.CLIs not defined"
401 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700402 assert ONOS1Port, "ONOS1Port not defined"
403 assert ONOS2Port, "ONOS2Port not defined"
404 assert ONOS3Port, "ONOS3Port not defined"
405 assert ONOS4Port, "ONOS4Port not defined"
406 assert ONOS5Port, "ONOS5Port not defined"
407 assert ONOS6Port, "ONOS6Port not defined"
408 assert ONOS7Port, "ONOS7Port not defined"
409
410 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700411 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700412 "device. Then manually assign" +\
413 " mastership to specific ONOS nodes using" +\
414 " 'device-role'"
415 main.step( "Assign mastership of switches to specific controllers" )
416 # Manually assign mastership to the controller we want
417 roleCall = main.TRUE
418
419 ipList = [ ]
420 deviceList = []
Jon Halla440e872016-03-31 15:15:50 -0700421 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700422 try:
423 # Assign mastership to specific controllers. This assignment was
424 # determined for a 7 node cluser, but will work with any sized
425 # cluster
426 for i in range( 1, 29 ): # switches 1 through 28
427 # set up correct variables:
428 if i == 1:
429 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700430 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700431 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700432 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700433 c = 1 % main.numCtrls
434 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700435 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700436 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700437 c = 1 % main.numCtrls
438 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700439 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700440 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700441 c = 3 % main.numCtrls
442 ip = main.nodes[ c ].ip_address # ONOS4
Jon Halla440e872016-03-31 15:15:50 -0700443 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700444 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700445 c = 2 % main.numCtrls
446 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700447 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700448 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700449 c = 2 % main.numCtrls
450 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700451 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700452 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700453 c = 5 % main.numCtrls
454 ip = main.nodes[ c ].ip_address # ONOS6
Jon Halla440e872016-03-31 15:15:50 -0700455 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700456 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700457 c = 4 % main.numCtrls
458 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700460 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700461 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700462 c = 6 % main.numCtrls
463 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700464 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700465 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700466 elif i == 28:
467 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700468 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700469 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700470 else:
471 main.log.error( "You didn't write an else statement for " +
472 "switch s" + str( i ) )
473 roleCall = main.FALSE
474 # Assign switch
475 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
476 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700477 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700478 ipList.append( ip )
479 deviceList.append( deviceId )
480 except ( AttributeError, AssertionError ):
481 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700482 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700483 utilities.assert_equals(
484 expect=main.TRUE,
485 actual=roleCall,
486 onpass="Re-assigned switch mastership to designated controller",
487 onfail="Something wrong with deviceRole calls" )
488
489 main.step( "Check mastership was correctly assigned" )
490 roleCheck = main.TRUE
491 # NOTE: This is due to the fact that device mastership change is not
492 # atomic and is actually a multi step process
493 time.sleep( 5 )
494 for i in range( len( ipList ) ):
495 ip = ipList[i]
496 deviceId = deviceList[i]
497 # Check assignment
Jon Halla440e872016-03-31 15:15:50 -0700498 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700499 if ip in master:
500 roleCheck = roleCheck and main.TRUE
501 else:
502 roleCheck = roleCheck and main.FALSE
503 main.log.error( "Error, controller " + ip + " is not" +
504 " master " + "of device " +
505 str( deviceId ) + ". Master is " +
506 repr( master ) + "." )
507 utilities.assert_equals(
508 expect=main.TRUE,
509 actual=roleCheck,
510 onpass="Switches were successfully reassigned to designated " +
511 "controller",
512 onfail="Switches were not successfully reassigned" )
513
514 def CASE3( self, main ):
515 """
516 Assign intents
517 """
518 import time
519 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700520 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700521 assert main, "main not defined"
522 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700523 assert main.CLIs, "main.CLIs not defined"
524 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700525 try:
526 labels
527 except NameError:
528 main.log.error( "labels not defined, setting to []" )
529 labels = []
530 try:
531 data
532 except NameError:
533 main.log.error( "data not defined, setting to []" )
534 data = []
535 # NOTE: we must reinstall intents until we have a persistant intent
536 # datastore!
537 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700538 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700539 "assign predetermined host-to-host intents." +\
540 " After installation, check that the intent" +\
541 " is distributed to all nodes and the state" +\
542 " is INSTALLED"
543
544 # install onos-app-fwd
545 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700546 onosCli = main.CLIs[ main.activeNodes[0] ]
547 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700548 utilities.assert_equals( expect=main.TRUE, actual=installResults,
549 onpass="Install fwd successful",
550 onfail="Install fwd failed" )
551
552 main.step( "Check app ids" )
553 appCheck = main.TRUE
554 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700555 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700556 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700557 name="appToIDCheck-" + str( i ),
558 args=[] )
559 threads.append( t )
560 t.start()
561
562 for t in threads:
563 t.join()
564 appCheck = appCheck and t.result
565 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700566 main.log.warn( onosCli.apps() )
567 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700568 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
569 onpass="App Ids seem to be correct",
570 onfail="Something is wrong with app Ids" )
571
572 main.step( "Discovering Hosts( Via pingall for now )" )
573 # FIXME: Once we have a host discovery mechanism, use that instead
574 # REACTIVE FWD test
575 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700576 passMsg = "Reactive Pingall test passed"
577 time1 = time.time()
578 pingResult = main.Mininet1.pingall()
579 time2 = time.time()
580 if not pingResult:
581 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700583 passMsg += " on the second try"
584 utilities.assert_equals(
585 expect=main.TRUE,
586 actual=pingResult,
587 onpass= passMsg,
588 onfail="Reactive Pingall failed, " +
589 "one or more ping pairs failed" )
590 main.log.info( "Time for pingall: %2f seconds" %
591 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700592 # timeout for fwd flows
593 time.sleep( 11 )
594 # uninstall onos-app-fwd
595 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700596 node = main.activeNodes[0]
597 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700598 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
599 onpass="Uninstall fwd successful",
600 onfail="Uninstall fwd failed" )
601
602 main.step( "Check app ids" )
603 threads = []
604 appCheck2 = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700605 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700606 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700607 name="appToIDCheck-" + str( i ),
608 args=[] )
609 threads.append( t )
610 t.start()
611
612 for t in threads:
613 t.join()
614 appCheck2 = appCheck2 and t.result
615 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700616 node = main.activeNodes[0]
617 main.log.warn( main.CLIs[node].apps() )
618 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700619 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
620 onpass="App Ids seem to be correct",
621 onfail="Something is wrong with app Ids" )
622
623 main.step( "Add host intents via cli" )
624 intentIds = []
Jon Hall6e709752016-02-01 13:38:46 -0800625 # TODO: move the host numbers to params
626 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700627 intentAddResult = True
628 hostResult = main.TRUE
629 for i in range( 8, 18 ):
630 main.log.info( "Adding host intent between h" + str( i ) +
631 " and h" + str( i + 10 ) )
632 host1 = "00:00:00:00:00:" + \
633 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
634 host2 = "00:00:00:00:00:" + \
635 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
636 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700637 host1Dict = onosCli.getHost( host1 )
638 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700639 host1Id = None
640 host2Id = None
641 if host1Dict and host2Dict:
642 host1Id = host1Dict.get( 'id', None )
643 host2Id = host2Dict.get( 'id', None )
644 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700645 nodeNum = ( i % len( main.activeNodes ) )
646 node = main.activeNodes[nodeNum]
647 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700648 if tmpId:
649 main.log.info( "Added intent with id: " + tmpId )
650 intentIds.append( tmpId )
651 else:
652 main.log.error( "addHostIntent returned: " +
653 repr( tmpId ) )
654 else:
655 main.log.error( "Error, getHost() failed for h" + str( i ) +
656 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700657 node = main.activeNodes[0]
658 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700659 main.log.warn( "Hosts output: " )
660 try:
661 main.log.warn( json.dumps( json.loads( hosts ),
662 sort_keys=True,
663 indent=4,
664 separators=( ',', ': ' ) ) )
665 except ( ValueError, TypeError ):
666 main.log.warn( repr( hosts ) )
667 hostResult = main.FALSE
668 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
669 onpass="Found a host id for each host",
670 onfail="Error looking up host ids" )
671
672 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700673 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700674 main.log.info( "Submitted intents: " + str( intentIds ) )
675 main.log.info( "Intents in ONOS: " + str( onosIds ) )
676 for intent in intentIds:
677 if intent in onosIds:
678 pass # intent submitted is in onos
679 else:
680 intentAddResult = False
681 if intentAddResult:
682 intentStop = time.time()
683 else:
684 intentStop = None
685 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700686 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700687 intentStates = []
688 installedCheck = True
689 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
690 count = 0
691 try:
692 for intent in json.loads( intents ):
693 state = intent.get( 'state', None )
694 if "INSTALLED" not in state:
695 installedCheck = False
696 intentId = intent.get( 'id', None )
697 intentStates.append( ( intentId, state ) )
698 except ( ValueError, TypeError ):
699 main.log.exception( "Error parsing intents" )
700 # add submitted intents not in the store
701 tmplist = [ i for i, s in intentStates ]
702 missingIntents = False
703 for i in intentIds:
704 if i not in tmplist:
705 intentStates.append( ( i, " - " ) )
706 missingIntents = True
707 intentStates.sort()
708 for i, s in intentStates:
709 count += 1
710 main.log.info( "%-6s%-15s%-15s" %
711 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700712 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700713 try:
714 missing = False
715 if leaders:
716 parsedLeaders = json.loads( leaders )
717 main.log.warn( json.dumps( parsedLeaders,
718 sort_keys=True,
719 indent=4,
720 separators=( ',', ': ' ) ) )
721 # check for all intent partitions
722 topics = []
723 for i in range( 14 ):
724 topics.append( "intent-partition-" + str( i ) )
725 main.log.debug( topics )
726 ONOStopics = [ j['topic'] for j in parsedLeaders ]
727 for topic in topics:
728 if topic not in ONOStopics:
729 main.log.error( "Error: " + topic +
730 " not in leaders" )
731 missing = True
732 else:
733 main.log.error( "leaders() returned None" )
734 except ( ValueError, TypeError ):
735 main.log.exception( "Error parsing leaders" )
736 main.log.error( repr( leaders ) )
737 # Check all nodes
738 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700739 for i in main.activeNodes:
740 response = main.CLIs[i].leaders( jsonFormat=False)
741 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700742 str( response ) )
743
Jon Halla440e872016-03-31 15:15:50 -0700744 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700745 try:
746 if partitions :
747 parsedPartitions = json.loads( partitions )
748 main.log.warn( json.dumps( parsedPartitions,
749 sort_keys=True,
750 indent=4,
751 separators=( ',', ': ' ) ) )
752 # TODO check for a leader in all paritions
753 # TODO check for consistency among nodes
754 else:
755 main.log.error( "partitions() returned None" )
756 except ( ValueError, TypeError ):
757 main.log.exception( "Error parsing partitions" )
758 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700759 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700760 try:
761 if pendingMap :
762 parsedPending = json.loads( pendingMap )
763 main.log.warn( json.dumps( parsedPending,
764 sort_keys=True,
765 indent=4,
766 separators=( ',', ': ' ) ) )
767 # TODO check something here?
768 else:
769 main.log.error( "pendingMap() returned None" )
770 except ( ValueError, TypeError ):
771 main.log.exception( "Error parsing pending map" )
772 main.log.error( repr( pendingMap ) )
773
774 intentAddResult = bool( intentAddResult and not missingIntents and
775 installedCheck )
776 if not intentAddResult:
777 main.log.error( "Error in pushing host intents to ONOS" )
778
779 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700780 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700781 correct = True
782 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700783 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700784 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700785 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700786 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700787 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700788 str( sorted( onosIds ) ) )
789 if sorted( ids ) != sorted( intentIds ):
790 main.log.warn( "Set of intent IDs doesn't match" )
791 correct = False
792 break
793 else:
Jon Halla440e872016-03-31 15:15:50 -0700794 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700795 for intent in intents:
796 if intent[ 'state' ] != "INSTALLED":
797 main.log.warn( "Intent " + intent[ 'id' ] +
798 " is " + intent[ 'state' ] )
799 correct = False
800 break
801 if correct:
802 break
803 else:
804 time.sleep(1)
805 if not intentStop:
806 intentStop = time.time()
807 global gossipTime
808 gossipTime = intentStop - intentStart
809 main.log.info( "It took about " + str( gossipTime ) +
810 " seconds for all intents to appear in each node" )
811 append = False
812 title = "Gossip Intents"
813 count = 1
814 while append is False:
815 curTitle = title + str( count )
816 if curTitle not in labels:
817 labels.append( curTitle )
818 data.append( str( gossipTime ) )
819 append = True
820 else:
821 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700822 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700823 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700824 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700825 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700826 onpass="ECM anti-entropy for intents worked within " +
827 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700828 onfail="Intent ECM anti-entropy took too long. " +
829 "Expected time:{}, Actual time:{}".format( maxGossipTime,
830 gossipTime ) )
831 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700832 intentAddResult = True
833
834 if not intentAddResult or "key" in pendingMap:
835 import time
836 installedCheck = True
837 main.log.info( "Sleeping 60 seconds to see if intents are found" )
838 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700839 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700840 main.log.info( "Submitted intents: " + str( intentIds ) )
841 main.log.info( "Intents in ONOS: " + str( onosIds ) )
842 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700843 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700844 intentStates = []
845 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
846 count = 0
847 try:
848 for intent in json.loads( intents ):
849 # Iter through intents of a node
850 state = intent.get( 'state', None )
851 if "INSTALLED" not in state:
852 installedCheck = False
853 intentId = intent.get( 'id', None )
854 intentStates.append( ( intentId, state ) )
855 except ( ValueError, TypeError ):
856 main.log.exception( "Error parsing intents" )
857 # add submitted intents not in the store
858 tmplist = [ i for i, s in intentStates ]
859 for i in intentIds:
860 if i not in tmplist:
861 intentStates.append( ( i, " - " ) )
862 intentStates.sort()
863 for i, s in intentStates:
864 count += 1
865 main.log.info( "%-6s%-15s%-15s" %
866 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700867 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700868 try:
869 missing = False
870 if leaders:
871 parsedLeaders = json.loads( leaders )
872 main.log.warn( json.dumps( parsedLeaders,
873 sort_keys=True,
874 indent=4,
875 separators=( ',', ': ' ) ) )
876 # check for all intent partitions
877 # check for election
878 topics = []
879 for i in range( 14 ):
880 topics.append( "intent-partition-" + str( i ) )
881 # FIXME: this should only be after we start the app
882 topics.append( "org.onosproject.election" )
883 main.log.debug( topics )
884 ONOStopics = [ j['topic'] for j in parsedLeaders ]
885 for topic in topics:
886 if topic not in ONOStopics:
887 main.log.error( "Error: " + topic +
888 " not in leaders" )
889 missing = True
890 else:
891 main.log.error( "leaders() returned None" )
892 except ( ValueError, TypeError ):
893 main.log.exception( "Error parsing leaders" )
894 main.log.error( repr( leaders ) )
895 # Check all nodes
896 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700897 for i in main.activeNodes:
898 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700899 response = node.leaders( jsonFormat=False)
900 main.log.warn( str( node.name ) + " leaders output: \n" +
901 str( response ) )
902
Jon Halla440e872016-03-31 15:15:50 -0700903 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700904 try:
905 if partitions :
906 parsedPartitions = json.loads( partitions )
907 main.log.warn( json.dumps( parsedPartitions,
908 sort_keys=True,
909 indent=4,
910 separators=( ',', ': ' ) ) )
911 # TODO check for a leader in all paritions
912 # TODO check for consistency among nodes
913 else:
914 main.log.error( "partitions() returned None" )
915 except ( ValueError, TypeError ):
916 main.log.exception( "Error parsing partitions" )
917 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700918 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700919 try:
920 if pendingMap :
921 parsedPending = json.loads( pendingMap )
922 main.log.warn( json.dumps( parsedPending,
923 sort_keys=True,
924 indent=4,
925 separators=( ',', ': ' ) ) )
926 # TODO check something here?
927 else:
928 main.log.error( "pendingMap() returned None" )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing pending map" )
931 main.log.error( repr( pendingMap ) )
932
933 def CASE4( self, main ):
934 """
935 Ping across added host intents
936 """
937 import json
938 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700939 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700940 assert main, "main not defined"
941 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700942 assert main.CLIs, "main.CLIs not defined"
943 assert main.nodes, "main.nodes not defined"
Jon Hall6e709752016-02-01 13:38:46 -0800944 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700945 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700946 "functionality and check the state of " +\
947 "the intent"
Jon Hall5cf14d52015-07-16 12:15:19 -0700948
Jon Hall41d39f12016-04-11 22:54:35 -0700949 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700950 main.step( "Check Intent state" )
951 installedCheck = False
952 loopCount = 0
953 while not installedCheck and loopCount < 40:
954 installedCheck = True
955 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700956 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700957 intentStates = []
958 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700959 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700960 # Iter through intents of a node
961 try:
962 for intent in json.loads( intents ):
963 state = intent.get( 'state', None )
964 if "INSTALLED" not in state:
965 installedCheck = False
966 intentId = intent.get( 'id', None )
967 intentStates.append( ( intentId, state ) )
968 except ( ValueError, TypeError ):
969 main.log.exception( "Error parsing intents." )
970 # Print states
971 intentStates.sort()
972 for i, s in intentStates:
973 count += 1
974 main.log.info( "%-6s%-15s%-15s" %
975 ( str( count ), str( i ), str( s ) ) )
976 if not installedCheck:
977 time.sleep( 1 )
978 loopCount += 1
979 utilities.assert_equals( expect=True, actual=installedCheck,
980 onpass="Intents are all INSTALLED",
981 onfail="Intents are not all in " +
982 "INSTALLED state" )
983
Jon Hall9d2dcad2016-04-08 10:15:20 -0700984 main.step( "Ping across added host intents" )
Jon Hall9d2dcad2016-04-08 10:15:20 -0700985 PingResult = main.TRUE
986 for i in range( 8, 18 ):
987 ping = main.Mininet1.pingHost( src="h" + str( i ),
988 target="h" + str( i + 10 ) )
989 PingResult = PingResult and ping
990 if ping == main.FALSE:
991 main.log.warn( "Ping failed between h" + str( i ) +
992 " and h" + str( i + 10 ) )
993 elif ping == main.TRUE:
994 main.log.info( "Ping test passed!" )
995 # Don't set PingResult or you'd override failures
996 if PingResult == main.FALSE:
997 main.log.error(
998 "Intents have not been installed correctly, pings failed." )
999 # TODO: pretty print
1000 main.log.warn( "ONOS1 intents: " )
1001 try:
1002 tmpIntents = onosCli.intents()
1003 main.log.warn( json.dumps( json.loads( tmpIntents ),
1004 sort_keys=True,
1005 indent=4,
1006 separators=( ',', ': ' ) ) )
1007 except ( ValueError, TypeError ):
1008 main.log.warn( repr( tmpIntents ) )
1009 utilities.assert_equals(
1010 expect=main.TRUE,
1011 actual=PingResult,
1012 onpass="Intents have been installed correctly and pings work",
1013 onfail="Intents have not been installed correctly, pings failed." )
1014
Jon Hall5cf14d52015-07-16 12:15:19 -07001015 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -07001016 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001017 topicCheck = main.TRUE
1018 try:
1019 if leaders:
1020 parsedLeaders = json.loads( leaders )
1021 main.log.warn( json.dumps( parsedLeaders,
1022 sort_keys=True,
1023 indent=4,
1024 separators=( ',', ': ' ) ) )
1025 # check for all intent partitions
1026 # check for election
1027 # TODO: Look at Devices as topics now that it uses this system
1028 topics = []
1029 for i in range( 14 ):
1030 topics.append( "intent-partition-" + str( i ) )
1031 # FIXME: this should only be after we start the app
1032 # FIXME: topics.append( "org.onosproject.election" )
1033 # Print leaders output
1034 main.log.debug( topics )
1035 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1036 for topic in topics:
1037 if topic not in ONOStopics:
1038 main.log.error( "Error: " + topic +
1039 " not in leaders" )
1040 topicCheck = main.FALSE
1041 else:
1042 main.log.error( "leaders() returned None" )
1043 topicCheck = main.FALSE
1044 except ( ValueError, TypeError ):
1045 topicCheck = main.FALSE
1046 main.log.exception( "Error parsing leaders" )
1047 main.log.error( repr( leaders ) )
1048 # TODO: Check for a leader of these topics
1049 # Check all nodes
1050 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001051 for i in main.activeNodes:
1052 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001053 response = node.leaders( jsonFormat=False)
1054 main.log.warn( str( node.name ) + " leaders output: \n" +
1055 str( response ) )
1056
1057 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1058 onpass="intent Partitions is in leaders",
1059 onfail="Some topics were lost " )
1060 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001061 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001062 try:
1063 if partitions :
1064 parsedPartitions = json.loads( partitions )
1065 main.log.warn( json.dumps( parsedPartitions,
1066 sort_keys=True,
1067 indent=4,
1068 separators=( ',', ': ' ) ) )
1069 # TODO check for a leader in all paritions
1070 # TODO check for consistency among nodes
1071 else:
1072 main.log.error( "partitions() returned None" )
1073 except ( ValueError, TypeError ):
1074 main.log.exception( "Error parsing partitions" )
1075 main.log.error( repr( partitions ) )
1076 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001077 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001078 try:
1079 if pendingMap :
1080 parsedPending = json.loads( pendingMap )
1081 main.log.warn( json.dumps( parsedPending,
1082 sort_keys=True,
1083 indent=4,
1084 separators=( ',', ': ' ) ) )
1085 # TODO check something here?
1086 else:
1087 main.log.error( "pendingMap() returned None" )
1088 except ( ValueError, TypeError ):
1089 main.log.exception( "Error parsing pending map" )
1090 main.log.error( repr( pendingMap ) )
1091
1092 if not installedCheck:
1093 main.log.info( "Waiting 60 seconds to see if the state of " +
1094 "intents change" )
1095 time.sleep( 60 )
1096 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001097 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001098 intentStates = []
1099 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1100 count = 0
1101 # Iter through intents of a node
1102 try:
1103 for intent in json.loads( intents ):
1104 state = intent.get( 'state', None )
1105 if "INSTALLED" not in state:
1106 installedCheck = False
1107 intentId = intent.get( 'id', None )
1108 intentStates.append( ( intentId, state ) )
1109 except ( ValueError, TypeError ):
1110 main.log.exception( "Error parsing intents." )
1111 intentStates.sort()
1112 for i, s in intentStates:
1113 count += 1
1114 main.log.info( "%-6s%-15s%-15s" %
1115 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001116 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001117 try:
1118 missing = False
1119 if leaders:
1120 parsedLeaders = json.loads( leaders )
1121 main.log.warn( json.dumps( parsedLeaders,
1122 sort_keys=True,
1123 indent=4,
1124 separators=( ',', ': ' ) ) )
1125 # check for all intent partitions
1126 # check for election
1127 topics = []
1128 for i in range( 14 ):
1129 topics.append( "intent-partition-" + str( i ) )
1130 # FIXME: this should only be after we start the app
1131 topics.append( "org.onosproject.election" )
1132 main.log.debug( topics )
1133 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1134 for topic in topics:
1135 if topic not in ONOStopics:
1136 main.log.error( "Error: " + topic +
1137 " not in leaders" )
1138 missing = True
1139 else:
1140 main.log.error( "leaders() returned None" )
1141 except ( ValueError, TypeError ):
1142 main.log.exception( "Error parsing leaders" )
1143 main.log.error( repr( leaders ) )
1144 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001145 for i in main.activeNodes:
1146 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001147 response = node.leaders( jsonFormat=False)
1148 main.log.warn( str( node.name ) + " leaders output: \n" +
1149 str( response ) )
1150
Jon Halla440e872016-03-31 15:15:50 -07001151 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001152 try:
1153 if partitions :
1154 parsedPartitions = json.loads( partitions )
1155 main.log.warn( json.dumps( parsedPartitions,
1156 sort_keys=True,
1157 indent=4,
1158 separators=( ',', ': ' ) ) )
1159 # TODO check for a leader in all paritions
1160 # TODO check for consistency among nodes
1161 else:
1162 main.log.error( "partitions() returned None" )
1163 except ( ValueError, TypeError ):
1164 main.log.exception( "Error parsing partitions" )
1165 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001166 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001167 try:
1168 if pendingMap :
1169 parsedPending = json.loads( pendingMap )
1170 main.log.warn( json.dumps( parsedPending,
1171 sort_keys=True,
1172 indent=4,
1173 separators=( ',', ': ' ) ) )
1174 # TODO check something here?
1175 else:
1176 main.log.error( "pendingMap() returned None" )
1177 except ( ValueError, TypeError ):
1178 main.log.exception( "Error parsing pending map" )
1179 main.log.error( repr( pendingMap ) )
1180 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001181 node = main.activeNodes[0]
1182 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001183 main.step( "Wait a minute then ping again" )
1184 # the wait is above
1185 PingResult = main.TRUE
1186 for i in range( 8, 18 ):
1187 ping = main.Mininet1.pingHost( src="h" + str( i ),
1188 target="h" + str( i + 10 ) )
1189 PingResult = PingResult and ping
1190 if ping == main.FALSE:
1191 main.log.warn( "Ping failed between h" + str( i ) +
1192 " and h" + str( i + 10 ) )
1193 elif ping == main.TRUE:
1194 main.log.info( "Ping test passed!" )
1195 # Don't set PingResult or you'd override failures
1196 if PingResult == main.FALSE:
1197 main.log.error(
1198 "Intents have not been installed correctly, pings failed." )
1199 # TODO: pretty print
1200 main.log.warn( "ONOS1 intents: " )
1201 try:
Jon Halla440e872016-03-31 15:15:50 -07001202 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001203 main.log.warn( json.dumps( json.loads( tmpIntents ),
1204 sort_keys=True,
1205 indent=4,
1206 separators=( ',', ': ' ) ) )
1207 except ( ValueError, TypeError ):
1208 main.log.warn( repr( tmpIntents ) )
1209 utilities.assert_equals(
1210 expect=main.TRUE,
1211 actual=PingResult,
1212 onpass="Intents have been installed correctly and pings work",
1213 onfail="Intents have not been installed correctly, pings failed." )
1214
1215 def CASE5( self, main ):
1216 """
1217 Reading state of ONOS
1218 """
1219 import json
1220 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001221 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001222 assert main, "main not defined"
1223 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001224 assert main.CLIs, "main.CLIs not defined"
1225 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001226
1227 main.case( "Setting up and gathering data for current state" )
1228 # The general idea for this test case is to pull the state of
1229 # ( intents,flows, topology,... ) from each ONOS node
1230 # We can then compare them with each other and also with past states
1231
1232 main.step( "Check that each switch has a master" )
1233 global mastershipState
1234 mastershipState = '[]'
1235
1236 # Assert that each device has a master
1237 rolesNotNull = main.TRUE
1238 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001239 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001240 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001241 name="rolesNotNull-" + str( i ),
1242 args=[] )
1243 threads.append( t )
1244 t.start()
1245
1246 for t in threads:
1247 t.join()
1248 rolesNotNull = rolesNotNull and t.result
1249 utilities.assert_equals(
1250 expect=main.TRUE,
1251 actual=rolesNotNull,
1252 onpass="Each device has a master",
1253 onfail="Some devices don't have a master assigned" )
1254
1255 main.step( "Get the Mastership of each switch from each controller" )
1256 ONOSMastership = []
1257 mastershipCheck = main.FALSE
1258 consistentMastership = True
1259 rolesResults = True
1260 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001261 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001262 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001263 name="roles-" + str( i ),
1264 args=[] )
1265 threads.append( t )
1266 t.start()
1267
1268 for t in threads:
1269 t.join()
1270 ONOSMastership.append( t.result )
1271
Jon Halla440e872016-03-31 15:15:50 -07001272 for i in range( len( ONOSMastership ) ):
1273 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001274 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001275 main.log.error( "Error in getting ONOS" + node + " roles" )
1276 main.log.warn( "ONOS" + node + " mastership response: " +
1277 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001278 rolesResults = False
1279 utilities.assert_equals(
1280 expect=True,
1281 actual=rolesResults,
1282 onpass="No error in reading roles output",
1283 onfail="Error in reading roles from ONOS" )
1284
1285 main.step( "Check for consistency in roles from each controller" )
1286 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1287 main.log.info(
1288 "Switch roles are consistent across all ONOS nodes" )
1289 else:
1290 consistentMastership = False
1291 utilities.assert_equals(
1292 expect=True,
1293 actual=consistentMastership,
1294 onpass="Switch roles are consistent across all ONOS nodes",
1295 onfail="ONOS nodes have different views of switch roles" )
1296
1297 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001298 for i in range( len( main.activeNodes ) ):
1299 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001300 try:
1301 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001302 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001303 json.dumps(
1304 json.loads( ONOSMastership[ i ] ),
1305 sort_keys=True,
1306 indent=4,
1307 separators=( ',', ': ' ) ) )
1308 except ( ValueError, TypeError ):
1309 main.log.warn( repr( ONOSMastership[ i ] ) )
1310 elif rolesResults and consistentMastership:
1311 mastershipCheck = main.TRUE
1312 mastershipState = ONOSMastership[ 0 ]
1313
1314 main.step( "Get the intents from each controller" )
1315 global intentState
1316 intentState = []
1317 ONOSIntents = []
1318 intentCheck = main.FALSE
1319 consistentIntents = True
1320 intentsResults = True
1321 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001322 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001323 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001324 name="intents-" + str( i ),
1325 args=[],
1326 kwargs={ 'jsonFormat': True } )
1327 threads.append( t )
1328 t.start()
1329
1330 for t in threads:
1331 t.join()
1332 ONOSIntents.append( t.result )
1333
Jon Halla440e872016-03-31 15:15:50 -07001334 for i in range( len( ONOSIntents ) ):
1335 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001336 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall6e709752016-02-01 13:38:46 -08001337 main.log.error( "Error in getting ONOS" + node + " intents" )
1338 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001339 repr( ONOSIntents[ i ] ) )
1340 intentsResults = False
1341 utilities.assert_equals(
1342 expect=True,
1343 actual=intentsResults,
1344 onpass="No error in reading intents output",
1345 onfail="Error in reading intents from ONOS" )
1346
1347 main.step( "Check for consistency in Intents from each controller" )
1348 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1349 main.log.info( "Intents are consistent across all ONOS " +
1350 "nodes" )
1351 else:
1352 consistentIntents = False
1353 main.log.error( "Intents not consistent" )
1354 utilities.assert_equals(
1355 expect=True,
1356 actual=consistentIntents,
1357 onpass="Intents are consistent across all ONOS nodes",
1358 onfail="ONOS nodes have different views of intents" )
1359
1360 if intentsResults:
1361 # Try to make it easy to figure out what is happening
1362 #
1363 # Intent ONOS1 ONOS2 ...
1364 # 0x01 INSTALLED INSTALLING
1365 # ... ... ...
1366 # ... ... ...
1367 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001368 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001369 title += " " * 10 + "ONOS" + str( n + 1 )
1370 main.log.warn( title )
1371 # get all intent keys in the cluster
1372 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001373 try:
1374 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001375 for nodeStr in ONOSIntents:
1376 node = json.loads( nodeStr )
1377 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001378 keys.append( intent.get( 'id' ) )
1379 keys = set( keys )
1380 # For each intent key, print the state on each node
1381 for key in keys:
1382 row = "%-13s" % key
1383 for nodeStr in ONOSIntents:
1384 node = json.loads( nodeStr )
1385 for intent in node:
1386 if intent.get( 'id', "Error" ) == key:
1387 row += "%-15s" % intent.get( 'state' )
1388 main.log.warn( row )
1389 # End of intent state table
1390 except ValueError as e:
1391 main.log.exception( e )
1392 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001393
1394 if intentsResults and not consistentIntents:
1395 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001396 n = str( main.activeNodes[-1] + 1 )
1397 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001398 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1399 sort_keys=True,
1400 indent=4,
1401 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001402 for i in range( len( ONOSIntents ) ):
1403 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001404 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001405 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001406 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1407 sort_keys=True,
1408 indent=4,
1409 separators=( ',', ': ' ) ) )
1410 else:
Jon Halla440e872016-03-31 15:15:50 -07001411 main.log.debug( "ONOS" + node + " intents match ONOS" +
1412 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001413 elif intentsResults and consistentIntents:
1414 intentCheck = main.TRUE
1415 intentState = ONOSIntents[ 0 ]
1416
1417 main.step( "Get the flows from each controller" )
1418 global flowState
1419 flowState = []
1420 ONOSFlows = []
1421 ONOSFlowsJson = []
1422 flowCheck = main.FALSE
1423 consistentFlows = True
1424 flowsResults = True
1425 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001426 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001427 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001428 name="flows-" + str( i ),
1429 args=[],
1430 kwargs={ 'jsonFormat': True } )
1431 threads.append( t )
1432 t.start()
1433
1434 # NOTE: Flows command can take some time to run
1435 time.sleep(30)
1436 for t in threads:
1437 t.join()
1438 result = t.result
1439 ONOSFlows.append( result )
1440
Jon Halla440e872016-03-31 15:15:50 -07001441 for i in range( len( ONOSFlows ) ):
1442 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001443 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1444 main.log.error( "Error in getting ONOS" + num + " flows" )
1445 main.log.warn( "ONOS" + num + " flows response: " +
1446 repr( ONOSFlows[ i ] ) )
1447 flowsResults = False
1448 ONOSFlowsJson.append( None )
1449 else:
1450 try:
1451 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1452 except ( ValueError, TypeError ):
1453 # FIXME: change this to log.error?
1454 main.log.exception( "Error in parsing ONOS" + num +
1455 " response as json." )
1456 main.log.error( repr( ONOSFlows[ i ] ) )
1457 ONOSFlowsJson.append( None )
1458 flowsResults = False
1459 utilities.assert_equals(
1460 expect=True,
1461 actual=flowsResults,
1462 onpass="No error in reading flows output",
1463 onfail="Error in reading flows from ONOS" )
1464
1465 main.step( "Check for consistency in Flows from each controller" )
1466 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1467 if all( tmp ):
1468 main.log.info( "Flow count is consistent across all ONOS nodes" )
1469 else:
1470 consistentFlows = False
1471 utilities.assert_equals(
1472 expect=True,
1473 actual=consistentFlows,
1474 onpass="The flow count is consistent across all ONOS nodes",
1475 onfail="ONOS nodes have different flow counts" )
1476
1477 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001478 for i in range( len( ONOSFlows ) ):
1479 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001480 try:
1481 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001482 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001483 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1484 indent=4, separators=( ',', ': ' ) ) )
1485 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001486 main.log.warn( "ONOS" + node + " flows: " +
1487 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001488 elif flowsResults and consistentFlows:
1489 flowCheck = main.TRUE
1490 flowState = ONOSFlows[ 0 ]
1491
1492 main.step( "Get the OF Table entries" )
1493 global flows
1494 flows = []
1495 for i in range( 1, 29 ):
Jon Halla440e872016-03-31 15:15:50 -07001496 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001497 if flowCheck == main.FALSE:
1498 for table in flows:
1499 main.log.warn( table )
1500 # TODO: Compare switch flow tables with ONOS flow tables
1501
1502 main.step( "Start continuous pings" )
1503 main.Mininet2.pingLong(
1504 src=main.params[ 'PING' ][ 'source1' ],
1505 target=main.params[ 'PING' ][ 'target1' ],
1506 pingTime=500 )
1507 main.Mininet2.pingLong(
1508 src=main.params[ 'PING' ][ 'source2' ],
1509 target=main.params[ 'PING' ][ 'target2' ],
1510 pingTime=500 )
1511 main.Mininet2.pingLong(
1512 src=main.params[ 'PING' ][ 'source3' ],
1513 target=main.params[ 'PING' ][ 'target3' ],
1514 pingTime=500 )
1515 main.Mininet2.pingLong(
1516 src=main.params[ 'PING' ][ 'source4' ],
1517 target=main.params[ 'PING' ][ 'target4' ],
1518 pingTime=500 )
1519 main.Mininet2.pingLong(
1520 src=main.params[ 'PING' ][ 'source5' ],
1521 target=main.params[ 'PING' ][ 'target5' ],
1522 pingTime=500 )
1523 main.Mininet2.pingLong(
1524 src=main.params[ 'PING' ][ 'source6' ],
1525 target=main.params[ 'PING' ][ 'target6' ],
1526 pingTime=500 )
1527 main.Mininet2.pingLong(
1528 src=main.params[ 'PING' ][ 'source7' ],
1529 target=main.params[ 'PING' ][ 'target7' ],
1530 pingTime=500 )
1531 main.Mininet2.pingLong(
1532 src=main.params[ 'PING' ][ 'source8' ],
1533 target=main.params[ 'PING' ][ 'target8' ],
1534 pingTime=500 )
1535 main.Mininet2.pingLong(
1536 src=main.params[ 'PING' ][ 'source9' ],
1537 target=main.params[ 'PING' ][ 'target9' ],
1538 pingTime=500 )
1539 main.Mininet2.pingLong(
1540 src=main.params[ 'PING' ][ 'source10' ],
1541 target=main.params[ 'PING' ][ 'target10' ],
1542 pingTime=500 )
1543
1544 main.step( "Collecting topology information from ONOS" )
1545 devices = []
1546 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001547 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001548 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001549 name="devices-" + str( i ),
1550 args=[ ] )
1551 threads.append( t )
1552 t.start()
1553
1554 for t in threads:
1555 t.join()
1556 devices.append( t.result )
1557 hosts = []
1558 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001559 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001560 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001561 name="hosts-" + str( i ),
1562 args=[ ] )
1563 threads.append( t )
1564 t.start()
1565
1566 for t in threads:
1567 t.join()
1568 try:
1569 hosts.append( json.loads( t.result ) )
1570 except ( ValueError, TypeError ):
1571 # FIXME: better handling of this, print which node
1572 # Maybe use thread name?
1573 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001574 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001575 hosts.append( None )
1576
1577 ports = []
1578 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001579 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001580 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001581 name="ports-" + str( i ),
1582 args=[ ] )
1583 threads.append( t )
1584 t.start()
1585
1586 for t in threads:
1587 t.join()
1588 ports.append( t.result )
1589 links = []
1590 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001591 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001592 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001593 name="links-" + str( i ),
1594 args=[ ] )
1595 threads.append( t )
1596 t.start()
1597
1598 for t in threads:
1599 t.join()
1600 links.append( t.result )
1601 clusters = []
1602 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001603 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001604 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001605 name="clusters-" + str( i ),
1606 args=[ ] )
1607 threads.append( t )
1608 t.start()
1609
1610 for t in threads:
1611 t.join()
1612 clusters.append( t.result )
1613 # Compare json objects for hosts and dataplane clusters
1614
1615 # hosts
1616 main.step( "Host view is consistent across ONOS nodes" )
1617 consistentHostsResult = main.TRUE
1618 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001619 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001620 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001621 if hosts[ controller ] == hosts[ 0 ]:
1622 continue
1623 else: # hosts not consistent
1624 main.log.error( "hosts from ONOS" +
1625 controllerStr +
1626 " is inconsistent with ONOS1" )
1627 main.log.warn( repr( hosts[ controller ] ) )
1628 consistentHostsResult = main.FALSE
1629
1630 else:
1631 main.log.error( "Error in getting ONOS hosts from ONOS" +
1632 controllerStr )
1633 consistentHostsResult = main.FALSE
1634 main.log.warn( "ONOS" + controllerStr +
1635 " hosts response: " +
1636 repr( hosts[ controller ] ) )
1637 utilities.assert_equals(
1638 expect=main.TRUE,
1639 actual=consistentHostsResult,
1640 onpass="Hosts view is consistent across all ONOS nodes",
1641 onfail="ONOS nodes have different views of hosts" )
1642
1643 main.step( "Each host has an IP address" )
1644 ipResult = main.TRUE
1645 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001646 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001647 if hosts[ controller ]:
1648 for host in hosts[ controller ]:
1649 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001650 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001651 controllerStr + ": " + str( host ) )
1652 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001653 utilities.assert_equals(
1654 expect=main.TRUE,
1655 actual=ipResult,
1656 onpass="The ips of the hosts aren't empty",
1657 onfail="The ip of at least one host is missing" )
1658
1659 # Strongly connected clusters of devices
1660 main.step( "Cluster view is consistent across ONOS nodes" )
1661 consistentClustersResult = main.TRUE
1662 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001663 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001664 if "Error" not in clusters[ controller ]:
1665 if clusters[ controller ] == clusters[ 0 ]:
1666 continue
1667 else: # clusters not consistent
1668 main.log.error( "clusters from ONOS" + controllerStr +
1669 " is inconsistent with ONOS1" )
1670 consistentClustersResult = main.FALSE
1671
1672 else:
1673 main.log.error( "Error in getting dataplane clusters " +
1674 "from ONOS" + controllerStr )
1675 consistentClustersResult = main.FALSE
1676 main.log.warn( "ONOS" + controllerStr +
1677 " clusters response: " +
1678 repr( clusters[ controller ] ) )
1679 utilities.assert_equals(
1680 expect=main.TRUE,
1681 actual=consistentClustersResult,
1682 onpass="Clusters view is consistent across all ONOS nodes",
1683 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001684 if consistentClustersResult != main.TRUE:
1685 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001686 # there should always only be one cluster
1687 main.step( "Cluster view correct across ONOS nodes" )
1688 try:
1689 numClusters = len( json.loads( clusters[ 0 ] ) )
1690 except ( ValueError, TypeError ):
1691 main.log.exception( "Error parsing clusters[0]: " +
1692 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001693 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001694 clusterResults = main.FALSE
1695 if numClusters == 1:
1696 clusterResults = main.TRUE
1697 utilities.assert_equals(
1698 expect=1,
1699 actual=numClusters,
1700 onpass="ONOS shows 1 SCC",
1701 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1702
1703 main.step( "Comparing ONOS topology to MN" )
1704 devicesResults = main.TRUE
1705 linksResults = main.TRUE
1706 hostsResults = main.TRUE
1707 mnSwitches = main.Mininet1.getSwitches()
1708 mnLinks = main.Mininet1.getLinks()
1709 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001710 for controller in main.activeNodes:
1711 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001712 if devices[ controller ] and ports[ controller ] and\
1713 "Error" not in devices[ controller ] and\
1714 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001715 currentDevicesResult = main.Mininet1.compareSwitches(
1716 mnSwitches,
1717 json.loads( devices[ controller ] ),
1718 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001719 else:
1720 currentDevicesResult = main.FALSE
1721 utilities.assert_equals( expect=main.TRUE,
1722 actual=currentDevicesResult,
1723 onpass="ONOS" + controllerStr +
1724 " Switches view is correct",
1725 onfail="ONOS" + controllerStr +
1726 " Switches view is incorrect" )
1727 if links[ controller ] and "Error" not in links[ controller ]:
1728 currentLinksResult = main.Mininet1.compareLinks(
1729 mnSwitches, mnLinks,
1730 json.loads( links[ controller ] ) )
1731 else:
1732 currentLinksResult = main.FALSE
1733 utilities.assert_equals( expect=main.TRUE,
1734 actual=currentLinksResult,
1735 onpass="ONOS" + controllerStr +
1736 " links view is correct",
1737 onfail="ONOS" + controllerStr +
1738 " links view is incorrect" )
1739
Jon Hall657cdf62015-12-17 14:40:51 -08001740 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001741 currentHostsResult = main.Mininet1.compareHosts(
1742 mnHosts,
1743 hosts[ controller ] )
1744 else:
1745 currentHostsResult = main.FALSE
1746 utilities.assert_equals( expect=main.TRUE,
1747 actual=currentHostsResult,
1748 onpass="ONOS" + controllerStr +
1749 " hosts exist in Mininet",
1750 onfail="ONOS" + controllerStr +
1751 " hosts don't match Mininet" )
1752
1753 devicesResults = devicesResults and currentDevicesResult
1754 linksResults = linksResults and currentLinksResult
1755 hostsResults = hostsResults and currentHostsResult
1756
1757 main.step( "Device information is correct" )
1758 utilities.assert_equals(
1759 expect=main.TRUE,
1760 actual=devicesResults,
1761 onpass="Device information is correct",
1762 onfail="Device information is incorrect" )
1763
1764 main.step( "Links are correct" )
1765 utilities.assert_equals(
1766 expect=main.TRUE,
1767 actual=linksResults,
1768 onpass="Link are correct",
1769 onfail="Links are incorrect" )
1770
1771 main.step( "Hosts are correct" )
1772 utilities.assert_equals(
1773 expect=main.TRUE,
1774 actual=hostsResults,
1775 onpass="Hosts are correct",
1776 onfail="Hosts are incorrect" )
1777
1778 def CASE6( self, main ):
1779 """
1780 The Failure case.
1781 """
1782 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001783 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001784 assert main, "main not defined"
1785 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001786 assert main.CLIs, "main.CLIs not defined"
1787 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001788 try:
1789 labels
1790 except NameError:
1791 main.log.error( "labels not defined, setting to []" )
1792 global labels
1793 labels = []
1794 try:
1795 data
1796 except NameError:
1797 main.log.error( "data not defined, setting to []" )
1798 global data
1799 data = []
1800 # Reset non-persistent variables
1801 try:
1802 iCounterValue = 0
1803 except NameError:
1804 main.log.error( "iCounterValue not defined, setting to 0" )
1805 iCounterValue = 0
1806
1807 main.case( "Restart entire ONOS cluster" )
1808
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001809 main.step( "Checking ONOS Logs for errors" )
1810 for node in main.nodes:
1811 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1812 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1813
Jon Hall5cf14d52015-07-16 12:15:19 -07001814 main.step( "Killing ONOS nodes" )
1815 killResults = main.TRUE
1816 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001817 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001818 killed = main.ONOSbench.onosKill( node.ip_address )
1819 killResults = killResults and killed
1820 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1821 onpass="ONOS nodes killed",
1822 onfail="ONOS kill unsuccessful" )
1823
1824 main.step( "Checking if ONOS is up yet" )
1825 for i in range( 2 ):
1826 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001827 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001828 started = main.ONOSbench.isup( node.ip_address )
1829 if not started:
1830 main.log.error( node.name + " didn't start!" )
1831 onosIsupResult = onosIsupResult and started
1832 if onosIsupResult == main.TRUE:
1833 break
1834 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1835 onpass="ONOS restarted",
1836 onfail="ONOS restart NOT successful" )
1837
1838 main.log.step( "Starting ONOS CLI sessions" )
1839 cliResults = main.TRUE
1840 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001841 for i in range( main.numCtrls ):
1842 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001843 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001844 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001845 threads.append( t )
1846 t.start()
1847
1848 for t in threads:
1849 t.join()
1850 cliResults = cliResults and t.result
1851 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1852 onpass="ONOS cli started",
1853 onfail="ONOS clis did not restart" )
1854
Jon Hall6e709752016-02-01 13:38:46 -08001855 for i in range( 10 ):
1856 ready = True
Jon Hall7ac7bc32016-05-05 10:57:02 -07001857 for i in main.activeNodes:
1858 cli = main.CLIs[i]
Jon Hall6e709752016-02-01 13:38:46 -08001859 output = cli.summary()
1860 if not output:
1861 ready = False
1862 time.sleep( 30 )
1863 utilities.assert_equals( expect=True, actual=ready,
1864 onpass="ONOS summary command succeded",
1865 onfail="ONOS summary command failed" )
1866 if not ready:
1867 main.cleanup()
1868 main.exit()
1869
Jon Hall5cf14d52015-07-16 12:15:19 -07001870 # Grab the time of restart so we chan check how long the gossip
1871 # protocol has had time to work
1872 main.restartTime = time.time() - killTime
1873 main.log.debug( "Restart time: " + str( main.restartTime ) )
1874 labels.append( "Restart" )
1875 data.append( str( main.restartTime ) )
1876
Jon Hall5cf14d52015-07-16 12:15:19 -07001877 # Rerun for election on restarted nodes
1878 runResults = main.TRUE
Jon Hall7ac7bc32016-05-05 10:57:02 -07001879 for i in main.activeNodes:
1880 cli = main.CLIs[i]
Jon Halla440e872016-03-31 15:15:50 -07001881 run = cli.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001882 if run != main.TRUE:
1883 main.log.error( "Error running for election on " + cli.name )
1884 runResults = runResults and run
1885 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1886 onpass="Reran for election",
1887 onfail="Failed to rerun for election" )
1888
1889 # TODO: Make this configurable
1890 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -07001891 node = main.activeNodes[0]
1892 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1893 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1894 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001895
1896 def CASE7( self, main ):
1897 """
1898 Check state after ONOS failure
1899 """
1900 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001901 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001902 assert main, "main not defined"
1903 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001904 assert main.CLIs, "main.CLIs not defined"
1905 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001906 main.case( "Running ONOS Constant State Tests" )
1907
1908 main.step( "Check that each switch has a master" )
1909 # Assert that each device has a master
1910 rolesNotNull = main.TRUE
1911 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001912 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001913 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001914 name="rolesNotNull-" + str( i ),
1915 args=[ ] )
1916 threads.append( t )
1917 t.start()
1918
1919 for t in threads:
1920 t.join()
1921 rolesNotNull = rolesNotNull and t.result
1922 utilities.assert_equals(
1923 expect=main.TRUE,
1924 actual=rolesNotNull,
1925 onpass="Each device has a master",
1926 onfail="Some devices don't have a master assigned" )
1927
1928 main.step( "Read device roles from ONOS" )
1929 ONOSMastership = []
1930 mastershipCheck = main.FALSE
1931 consistentMastership = True
1932 rolesResults = True
1933 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001934 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001935 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001936 name="roles-" + str( i ),
1937 args=[] )
1938 threads.append( t )
1939 t.start()
1940
1941 for t in threads:
1942 t.join()
1943 ONOSMastership.append( t.result )
1944
Jon Halla440e872016-03-31 15:15:50 -07001945 for i in range( len( ONOSMastership ) ):
1946 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001947 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001948 main.log.error( "Error in getting ONOS" + node + " roles" )
1949 main.log.warn( "ONOS" + node + " mastership response: " +
1950 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001951 rolesResults = False
1952 utilities.assert_equals(
1953 expect=True,
1954 actual=rolesResults,
1955 onpass="No error in reading roles output",
1956 onfail="Error in reading roles from ONOS" )
1957
1958 main.step( "Check for consistency in roles from each controller" )
1959 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1960 main.log.info(
1961 "Switch roles are consistent across all ONOS nodes" )
1962 else:
1963 consistentMastership = False
1964 utilities.assert_equals(
1965 expect=True,
1966 actual=consistentMastership,
1967 onpass="Switch roles are consistent across all ONOS nodes",
1968 onfail="ONOS nodes have different views of switch roles" )
1969
1970 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001971 for i in range( len( ONOSMastership ) ):
1972 node = str( main.activeNodes[i] + 1 )
1973 main.log.warn( "ONOS" + node + " roles: ",
Jon Hall6e709752016-02-01 13:38:46 -08001974 json.dumps( json.loads( ONOSMastership[ i ] ),
1975 sort_keys=True,
1976 indent=4,
1977 separators=( ',', ': ' ) ) )
1978 elif rolesResults and consistentMastership:
Jon Hall5cf14d52015-07-16 12:15:19 -07001979 mastershipCheck = main.TRUE
1980
Jon Hall5cf14d52015-07-16 12:15:19 -07001981 # NOTE: we expect mastership to change on controller failure
1982
1983 main.step( "Get the intents and compare across all nodes" )
1984 ONOSIntents = []
1985 intentCheck = main.FALSE
1986 consistentIntents = True
1987 intentsResults = True
1988 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001989 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001990 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001991 name="intents-" + str( i ),
1992 args=[],
1993 kwargs={ 'jsonFormat': True } )
1994 threads.append( t )
1995 t.start()
1996
1997 for t in threads:
1998 t.join()
1999 ONOSIntents.append( t.result )
2000
Jon Halla440e872016-03-31 15:15:50 -07002001 for i in range( len( ONOSIntents) ):
2002 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002003 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07002004 main.log.error( "Error in getting ONOS" + node + " intents" )
2005 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002006 repr( ONOSIntents[ i ] ) )
2007 intentsResults = False
2008 utilities.assert_equals(
2009 expect=True,
2010 actual=intentsResults,
2011 onpass="No error in reading intents output",
2012 onfail="Error in reading intents from ONOS" )
2013
2014 main.step( "Check for consistency in Intents from each controller" )
2015 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2016 main.log.info( "Intents are consistent across all ONOS " +
2017 "nodes" )
2018 else:
2019 consistentIntents = False
2020
2021 # Try to make it easy to figure out what is happening
2022 #
2023 # Intent ONOS1 ONOS2 ...
2024 # 0x01 INSTALLED INSTALLING
2025 # ... ... ...
2026 # ... ... ...
2027 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07002028 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002029 title += " " * 10 + "ONOS" + str( n + 1 )
2030 main.log.warn( title )
2031 # get all intent keys in the cluster
2032 keys = []
2033 for nodeStr in ONOSIntents:
2034 node = json.loads( nodeStr )
2035 for intent in node:
2036 keys.append( intent.get( 'id' ) )
2037 keys = set( keys )
2038 for key in keys:
2039 row = "%-13s" % key
2040 for nodeStr in ONOSIntents:
2041 node = json.loads( nodeStr )
2042 for intent in node:
2043 if intent.get( 'id' ) == key:
2044 row += "%-15s" % intent.get( 'state' )
2045 main.log.warn( row )
2046 # End table view
2047
2048 utilities.assert_equals(
2049 expect=True,
2050 actual=consistentIntents,
2051 onpass="Intents are consistent across all ONOS nodes",
2052 onfail="ONOS nodes have different views of intents" )
2053 intentStates = []
2054 for node in ONOSIntents: # Iter through ONOS nodes
2055 nodeStates = []
2056 # Iter through intents of a node
2057 try:
2058 for intent in json.loads( node ):
2059 nodeStates.append( intent[ 'state' ] )
2060 except ( ValueError, TypeError ):
2061 main.log.exception( "Error in parsing intents" )
2062 main.log.error( repr( node ) )
2063 intentStates.append( nodeStates )
2064 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2065 main.log.info( dict( out ) )
2066
2067 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07002068 for i in range( len( main.activeNodes ) ):
2069 node = str( main.activeNodes[i] + 1 )
2070 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002071 main.log.warn( json.dumps(
2072 json.loads( ONOSIntents[ i ] ),
2073 sort_keys=True,
2074 indent=4,
2075 separators=( ',', ': ' ) ) )
2076 elif intentsResults and consistentIntents:
2077 intentCheck = main.TRUE
2078
2079 # NOTE: Store has no durability, so intents are lost across system
2080 # restarts
2081 """
2082 main.step( "Compare current intents with intents before the failure" )
2083 # NOTE: this requires case 5 to pass for intentState to be set.
2084 # maybe we should stop the test if that fails?
2085 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002086 try:
2087 intentState
2088 except NameError:
2089 main.log.warn( "No previous intent state was saved" )
2090 else:
2091 if intentState and intentState == ONOSIntents[ 0 ]:
2092 sameIntents = main.TRUE
2093 main.log.info( "Intents are consistent with before failure" )
2094 # TODO: possibly the states have changed? we may need to figure out
2095 # what the acceptable states are
2096 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2097 sameIntents = main.TRUE
2098 try:
2099 before = json.loads( intentState )
2100 after = json.loads( ONOSIntents[ 0 ] )
2101 for intent in before:
2102 if intent not in after:
2103 sameIntents = main.FALSE
2104 main.log.debug( "Intent is not currently in ONOS " +
2105 "(at least in the same form):" )
2106 main.log.debug( json.dumps( intent ) )
2107 except ( ValueError, TypeError ):
2108 main.log.exception( "Exception printing intents" )
2109 main.log.debug( repr( ONOSIntents[0] ) )
2110 main.log.debug( repr( intentState ) )
2111 if sameIntents == main.FALSE:
2112 try:
2113 main.log.debug( "ONOS intents before: " )
2114 main.log.debug( json.dumps( json.loads( intentState ),
2115 sort_keys=True, indent=4,
2116 separators=( ',', ': ' ) ) )
2117 main.log.debug( "Current ONOS intents: " )
2118 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2119 sort_keys=True, indent=4,
2120 separators=( ',', ': ' ) ) )
2121 except ( ValueError, TypeError ):
2122 main.log.exception( "Exception printing intents" )
2123 main.log.debug( repr( ONOSIntents[0] ) )
2124 main.log.debug( repr( intentState ) )
2125 utilities.assert_equals(
2126 expect=main.TRUE,
2127 actual=sameIntents,
2128 onpass="Intents are consistent with before failure",
2129 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002130 intentCheck = intentCheck and sameIntents
2131 """
2132 main.step( "Get the OF Table entries and compare to before " +
2133 "component failure" )
2134 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002135 for i in range( 28 ):
2136 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002137 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
Jon Hall41d39f12016-04-11 22:54:35 -07002138 curSwitch = main.Mininet1.flowTableComp( flows[i], tmpFlows )
2139 FlowTables = FlowTables and curSwitch
2140 if curSwitch == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002141 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002142 utilities.assert_equals(
2143 expect=main.TRUE,
2144 actual=FlowTables,
2145 onpass="No changes were found in the flow tables",
2146 onfail="Changes were found in the flow tables" )
2147
2148 main.Mininet2.pingLongKill()
2149 '''
2150 # main.step( "Check the continuous pings to ensure that no packets " +
2151 # "were dropped during component failure" )
2152 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2153 main.params[ 'TESTONIP' ] )
2154 LossInPings = main.FALSE
2155 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2156 for i in range( 8, 18 ):
2157 main.log.info(
2158 "Checking for a loss in pings along flow from s" +
2159 str( i ) )
2160 LossInPings = main.Mininet2.checkForLoss(
2161 "/tmp/ping.h" +
2162 str( i ) ) or LossInPings
2163 if LossInPings == main.TRUE:
2164 main.log.info( "Loss in ping detected" )
2165 elif LossInPings == main.ERROR:
2166 main.log.info( "There are multiple mininet process running" )
2167 elif LossInPings == main.FALSE:
2168 main.log.info( "No Loss in the pings" )
2169 main.log.info( "No loss of dataplane connectivity" )
2170 # utilities.assert_equals(
2171 # expect=main.FALSE,
2172 # actual=LossInPings,
2173 # onpass="No Loss of connectivity",
2174 # onfail="Loss of dataplane connectivity detected" )
2175
2176 # NOTE: Since intents are not persisted with IntnentStore,
2177 # we expect loss in dataplane connectivity
2178 LossInPings = main.FALSE
2179 '''
2180
2181 main.step( "Leadership Election is still functional" )
2182 # Test of LeadershipElection
2183 leaderList = []
2184 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002185
2186 for i in main.activeNodes:
2187 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002188 leaderN = cli.electionTestLeader()
2189 leaderList.append( leaderN )
2190 if leaderN == main.FALSE:
2191 # error in response
2192 main.log.error( "Something is wrong with " +
2193 "electionTestLeader function, check the" +
2194 " error logs" )
2195 leaderResult = main.FALSE
2196 elif leaderN is None:
2197 main.log.error( cli.name +
2198 " shows no leader for the election-app." )
2199 leaderResult = main.FALSE
2200 if len( set( leaderList ) ) != 1:
2201 leaderResult = main.FALSE
2202 main.log.error(
2203 "Inconsistent view of leader for the election test app" )
2204 # TODO: print the list
2205 utilities.assert_equals(
2206 expect=main.TRUE,
2207 actual=leaderResult,
2208 onpass="Leadership election passed",
2209 onfail="Something went wrong with Leadership election" )
2210
2211 def CASE8( self, main ):
2212 """
2213 Compare topo
2214 """
2215 import json
2216 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002217 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002218 assert main, "main not defined"
2219 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002220 assert main.CLIs, "main.CLIs not defined"
2221 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002222
2223 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002224 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002225 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002226 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002227 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002228 elapsed = 0
2229 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002230 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002231 startTime = time.time()
2232 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002233 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002234 devicesResults = main.TRUE
2235 linksResults = main.TRUE
2236 hostsResults = main.TRUE
2237 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002238 count += 1
2239 cliStart = time.time()
2240 devices = []
2241 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002242 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002243 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002244 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002245 args=[ main.CLIs[i].devices, [ None ] ],
2246 kwargs= { 'sleep': 5, 'attempts': 5,
2247 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002248 threads.append( t )
2249 t.start()
2250
2251 for t in threads:
2252 t.join()
2253 devices.append( t.result )
2254 hosts = []
2255 ipResult = main.TRUE
2256 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002257 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002258 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002259 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002260 args=[ main.CLIs[i].hosts, [ None ] ],
2261 kwargs= { 'sleep': 5, 'attempts': 5,
2262 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002263 threads.append( t )
2264 t.start()
2265
2266 for t in threads:
2267 t.join()
2268 try:
2269 hosts.append( json.loads( t.result ) )
2270 except ( ValueError, TypeError ):
2271 main.log.exception( "Error parsing hosts results" )
2272 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002273 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002274 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002275 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002276 if hosts[ controller ]:
2277 for host in hosts[ controller ]:
2278 if host is None or host.get( 'ipAddresses', [] ) == []:
2279 main.log.error(
2280 "Error with host ipAddresses on controller" +
2281 controllerStr + ": " + str( host ) )
2282 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002283 ports = []
2284 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002285 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002286 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002287 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002288 args=[ main.CLIs[i].ports, [ None ] ],
2289 kwargs= { 'sleep': 5, 'attempts': 5,
2290 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002291 threads.append( t )
2292 t.start()
2293
2294 for t in threads:
2295 t.join()
2296 ports.append( t.result )
2297 links = []
2298 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002299 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002300 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002301 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002302 args=[ main.CLIs[i].links, [ None ] ],
2303 kwargs= { 'sleep': 5, 'attempts': 5,
2304 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002305 threads.append( t )
2306 t.start()
2307
2308 for t in threads:
2309 t.join()
2310 links.append( t.result )
2311 clusters = []
2312 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002313 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002314 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002315 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002316 args=[ main.CLIs[i].clusters, [ None ] ],
2317 kwargs= { 'sleep': 5, 'attempts': 5,
2318 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002319 threads.append( t )
2320 t.start()
2321
2322 for t in threads:
2323 t.join()
2324 clusters.append( t.result )
2325
2326 elapsed = time.time() - startTime
2327 cliTime = time.time() - cliStart
2328 print "Elapsed time: " + str( elapsed )
2329 print "CLI time: " + str( cliTime )
2330
Jon Hall6e709752016-02-01 13:38:46 -08002331 if all( e is None for e in devices ) and\
2332 all( e is None for e in hosts ) and\
2333 all( e is None for e in ports ) and\
2334 all( e is None for e in links ) and\
2335 all( e is None for e in clusters ):
2336 topoFailMsg = "Could not get topology from ONOS"
2337 main.log.error( topoFailMsg )
2338 continue # Try again, No use trying to compare
2339
Jon Hall5cf14d52015-07-16 12:15:19 -07002340 mnSwitches = main.Mininet1.getSwitches()
2341 mnLinks = main.Mininet1.getLinks()
2342 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07002343 for controller in range( len( main.activeNodes ) ):
2344 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002345 if devices[ controller ] and ports[ controller ] and\
2346 "Error" not in devices[ controller ] and\
2347 "Error" not in ports[ controller ]:
2348
Jon Hallc6793552016-01-19 14:18:37 -08002349 try:
2350 currentDevicesResult = main.Mininet1.compareSwitches(
2351 mnSwitches,
2352 json.loads( devices[ controller ] ),
2353 json.loads( ports[ controller ] ) )
2354 except ( TypeError, ValueError ) as e:
2355 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2356 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002357 else:
2358 currentDevicesResult = main.FALSE
2359 utilities.assert_equals( expect=main.TRUE,
2360 actual=currentDevicesResult,
2361 onpass="ONOS" + controllerStr +
2362 " Switches view is correct",
2363 onfail="ONOS" + controllerStr +
2364 " Switches view is incorrect" )
2365
2366 if links[ controller ] and "Error" not in links[ controller ]:
2367 currentLinksResult = main.Mininet1.compareLinks(
2368 mnSwitches, mnLinks,
2369 json.loads( links[ controller ] ) )
2370 else:
2371 currentLinksResult = main.FALSE
2372 utilities.assert_equals( expect=main.TRUE,
2373 actual=currentLinksResult,
2374 onpass="ONOS" + controllerStr +
2375 " links view is correct",
2376 onfail="ONOS" + controllerStr +
2377 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002378 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002379 currentHostsResult = main.Mininet1.compareHosts(
2380 mnHosts,
2381 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002382 elif hosts[ controller ] == []:
2383 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002384 else:
2385 currentHostsResult = main.FALSE
2386 utilities.assert_equals( expect=main.TRUE,
2387 actual=currentHostsResult,
2388 onpass="ONOS" + controllerStr +
2389 " hosts exist in Mininet",
2390 onfail="ONOS" + controllerStr +
2391 " hosts don't match Mininet" )
2392 # CHECKING HOST ATTACHMENT POINTS
2393 hostAttachment = True
Jon Halla440e872016-03-31 15:15:50 -07002394 zeroHosts = False
Jon Hall5cf14d52015-07-16 12:15:19 -07002395 # FIXME: topo-HA/obelisk specific mappings:
2396 # key is mac and value is dpid
2397 mappings = {}
2398 for i in range( 1, 29 ): # hosts 1 through 28
2399 # set up correct variables:
2400 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2401 if i == 1:
2402 deviceId = "1000".zfill(16)
2403 elif i == 2:
2404 deviceId = "2000".zfill(16)
2405 elif i == 3:
2406 deviceId = "3000".zfill(16)
2407 elif i == 4:
2408 deviceId = "3004".zfill(16)
2409 elif i == 5:
2410 deviceId = "5000".zfill(16)
2411 elif i == 6:
2412 deviceId = "6000".zfill(16)
2413 elif i == 7:
2414 deviceId = "6007".zfill(16)
2415 elif i >= 8 and i <= 17:
2416 dpid = '3' + str( i ).zfill( 3 )
2417 deviceId = dpid.zfill(16)
2418 elif i >= 18 and i <= 27:
2419 dpid = '6' + str( i ).zfill( 3 )
2420 deviceId = dpid.zfill(16)
2421 elif i == 28:
2422 deviceId = "2800".zfill(16)
2423 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002424 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002425 if hosts[ controller ] == []:
2426 main.log.warn( "There are no hosts discovered" )
Jon Halla440e872016-03-31 15:15:50 -07002427 zeroHosts = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002428 else:
2429 for host in hosts[ controller ]:
2430 mac = None
2431 location = None
2432 device = None
2433 port = None
2434 try:
2435 mac = host.get( 'mac' )
2436 assert mac, "mac field could not be found for this host object"
2437
2438 location = host.get( 'location' )
2439 assert location, "location field could not be found for this host object"
2440
2441 # Trim the protocol identifier off deviceId
2442 device = str( location.get( 'elementId' ) ).split(':')[1]
2443 assert device, "elementId field could not be found for this host location object"
2444
2445 port = location.get( 'port' )
2446 assert port, "port field could not be found for this host location object"
2447
2448 # Now check if this matches where they should be
2449 if mac and device and port:
2450 if str( port ) != "1":
2451 main.log.error( "The attachment port is incorrect for " +
2452 "host " + str( mac ) +
2453 ". Expected: 1 Actual: " + str( port) )
2454 hostAttachment = False
2455 if device != mappings[ str( mac ) ]:
2456 main.log.error( "The attachment device is incorrect for " +
2457 "host " + str( mac ) +
2458 ". Expected: " + mappings[ str( mac ) ] +
2459 " Actual: " + device )
2460 hostAttachment = False
2461 else:
2462 hostAttachment = False
2463 except AssertionError:
2464 main.log.exception( "Json object not as expected" )
2465 main.log.error( repr( host ) )
2466 hostAttachment = False
2467 else:
2468 main.log.error( "No hosts json output or \"Error\"" +
2469 " in output. hosts = " +
2470 repr( hosts[ controller ] ) )
Jon Halla440e872016-03-31 15:15:50 -07002471 if zeroHosts is False:
Jon Hall5cf14d52015-07-16 12:15:19 -07002472 # TODO: Find a way to know if there should be hosts in a
2473 # given point of the test
2474 hostAttachment = True
2475
2476 # END CHECKING HOST ATTACHMENT POINTS
2477 devicesResults = devicesResults and currentDevicesResult
2478 linksResults = linksResults and currentLinksResult
2479 hostsResults = hostsResults and currentHostsResult
2480 hostAttachmentResults = hostAttachmentResults and\
2481 hostAttachment
2482 topoResult = ( devicesResults and linksResults
2483 and hostsResults and ipResult and
2484 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002485 utilities.assert_equals( expect=True,
2486 actual=topoResult,
2487 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002488 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002489 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002490
2491 # Compare json objects for hosts and dataplane clusters
2492
2493 # hosts
2494 main.step( "Hosts view is consistent across all ONOS nodes" )
2495 consistentHostsResult = main.TRUE
2496 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002497 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002498 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002499 if hosts[ controller ] == hosts[ 0 ]:
2500 continue
2501 else: # hosts not consistent
2502 main.log.error( "hosts from ONOS" + controllerStr +
2503 " is inconsistent with ONOS1" )
2504 main.log.warn( repr( hosts[ controller ] ) )
2505 consistentHostsResult = main.FALSE
2506
2507 else:
2508 main.log.error( "Error in getting ONOS hosts from ONOS" +
2509 controllerStr )
2510 consistentHostsResult = main.FALSE
2511 main.log.warn( "ONOS" + controllerStr +
2512 " hosts response: " +
2513 repr( hosts[ controller ] ) )
2514 utilities.assert_equals(
2515 expect=main.TRUE,
2516 actual=consistentHostsResult,
2517 onpass="Hosts view is consistent across all ONOS nodes",
2518 onfail="ONOS nodes have different views of hosts" )
2519
2520 main.step( "Hosts information is correct" )
2521 hostsResults = hostsResults and ipResult
2522 utilities.assert_equals(
2523 expect=main.TRUE,
2524 actual=hostsResults,
2525 onpass="Host information is correct",
2526 onfail="Host information is incorrect" )
2527
2528 main.step( "Host attachment points to the network" )
2529 utilities.assert_equals(
2530 expect=True,
2531 actual=hostAttachmentResults,
2532 onpass="Hosts are correctly attached to the network",
2533 onfail="ONOS did not correctly attach hosts to the network" )
2534
2535 # Strongly connected clusters of devices
2536 main.step( "Clusters view is consistent across all ONOS nodes" )
2537 consistentClustersResult = main.TRUE
2538 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002539 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002540 if "Error" not in clusters[ controller ]:
2541 if clusters[ controller ] == clusters[ 0 ]:
2542 continue
2543 else: # clusters not consistent
2544 main.log.error( "clusters from ONOS" +
2545 controllerStr +
2546 " is inconsistent with ONOS1" )
2547 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002548 else:
2549 main.log.error( "Error in getting dataplane clusters " +
2550 "from ONOS" + controllerStr )
2551 consistentClustersResult = main.FALSE
2552 main.log.warn( "ONOS" + controllerStr +
2553 " clusters response: " +
2554 repr( clusters[ controller ] ) )
2555 utilities.assert_equals(
2556 expect=main.TRUE,
2557 actual=consistentClustersResult,
2558 onpass="Clusters view is consistent across all ONOS nodes",
2559 onfail="ONOS nodes have different views of clusters" )
2560
2561 main.step( "There is only one SCC" )
2562 # there should always only be one cluster
2563 try:
2564 numClusters = len( json.loads( clusters[ 0 ] ) )
2565 except ( ValueError, TypeError ):
2566 main.log.exception( "Error parsing clusters[0]: " +
2567 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002568 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002569 clusterResults = main.FALSE
2570 if numClusters == 1:
2571 clusterResults = main.TRUE
2572 utilities.assert_equals(
2573 expect=1,
2574 actual=numClusters,
2575 onpass="ONOS shows 1 SCC",
2576 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2577
2578 topoResult = ( devicesResults and linksResults
2579 and hostsResults and consistentHostsResult
2580 and consistentClustersResult and clusterResults
2581 and ipResult and hostAttachmentResults )
2582
2583 topoResult = topoResult and int( count <= 2 )
2584 note = "note it takes about " + str( int( cliTime ) ) + \
2585 " seconds for the test to make all the cli calls to fetch " +\
2586 "the topology from each ONOS instance"
2587 main.log.info(
2588 "Very crass estimate for topology discovery/convergence( " +
2589 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2590 str( count ) + " tries" )
2591
2592 main.step( "Device information is correct" )
2593 utilities.assert_equals(
2594 expect=main.TRUE,
2595 actual=devicesResults,
2596 onpass="Device information is correct",
2597 onfail="Device information is incorrect" )
2598
2599 main.step( "Links are correct" )
2600 utilities.assert_equals(
2601 expect=main.TRUE,
2602 actual=linksResults,
2603 onpass="Link are correct",
2604 onfail="Links are incorrect" )
2605
Jon Halla440e872016-03-31 15:15:50 -07002606 main.step( "Hosts are correct" )
2607 utilities.assert_equals(
2608 expect=main.TRUE,
2609 actual=hostsResults,
2610 onpass="Hosts are correct",
2611 onfail="Hosts are incorrect" )
2612
Jon Hall5cf14d52015-07-16 12:15:19 -07002613 # FIXME: move this to an ONOS state case
2614 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -07002615 nodeResults = utilities.retry( main.HA.nodesCheck,
2616 False,
2617 args=[main.activeNodes],
2618 attempts=5 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002619
Jon Hall41d39f12016-04-11 22:54:35 -07002620 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Hall5cf14d52015-07-16 12:15:19 -07002621 onpass="Nodes check successful",
2622 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002623 if not nodeResults:
Jon Hall41d39f12016-04-11 22:54:35 -07002624 for i in main.activeNodes:
Jon Halla440e872016-03-31 15:15:50 -07002625 main.log.debug( "{} components not ACTIVE: \n{}".format(
Jon Hall41d39f12016-04-11 22:54:35 -07002626 main.CLIs[i].name,
2627 main.CLIs[i].sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002628
2629 def CASE9( self, main ):
2630 """
2631 Link s3-s28 down
2632 """
2633 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002634 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002635 assert main, "main not defined"
2636 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002637 assert main.CLIs, "main.CLIs not defined"
2638 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002639 # NOTE: You should probably run a topology check after this
2640
2641 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2642
2643 description = "Turn off a link to ensure that Link Discovery " +\
2644 "is working properly"
2645 main.case( description )
2646
2647 main.step( "Kill Link between s3 and s28" )
2648 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2649 main.log.info( "Waiting " + str( linkSleep ) +
2650 " seconds for link down to be discovered" )
2651 time.sleep( linkSleep )
2652 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2653 onpass="Link down successful",
2654 onfail="Failed to bring link down" )
2655 # TODO do some sort of check here
2656
2657 def CASE10( self, main ):
2658 """
2659 Link s3-s28 up
2660 """
2661 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002662 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002663 assert main, "main not defined"
2664 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002665 assert main.CLIs, "main.CLIs not defined"
2666 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002667 # NOTE: You should probably run a topology check after this
2668
2669 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2670
2671 description = "Restore a link to ensure that Link Discovery is " + \
2672 "working properly"
2673 main.case( description )
2674
2675 main.step( "Bring link between s3 and s28 back up" )
2676 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2677 main.log.info( "Waiting " + str( linkSleep ) +
2678 " seconds for link up to be discovered" )
2679 time.sleep( linkSleep )
2680 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2681 onpass="Link up successful",
2682 onfail="Failed to bring link up" )
2683 # TODO do some sort of check here
2684
2685 def CASE11( self, main ):
2686 """
2687 Switch Down
2688 """
2689 # NOTE: You should probably run a topology check after this
2690 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002691 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002692 assert main, "main not defined"
2693 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002694 assert main.CLIs, "main.CLIs not defined"
2695 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002696
2697 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2698
2699 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002700 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002701 main.case( description )
2702 switch = main.params[ 'kill' ][ 'switch' ]
2703 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2704
2705 # TODO: Make this switch parameterizable
2706 main.step( "Kill " + switch )
2707 main.log.info( "Deleting " + switch )
2708 main.Mininet1.delSwitch( switch )
2709 main.log.info( "Waiting " + str( switchSleep ) +
2710 " seconds for switch down to be discovered" )
2711 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002712 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002713 # Peek at the deleted switch
2714 main.log.warn( str( device ) )
2715 result = main.FALSE
2716 if device and device[ 'available' ] is False:
2717 result = main.TRUE
2718 utilities.assert_equals( expect=main.TRUE, actual=result,
2719 onpass="Kill switch successful",
2720 onfail="Failed to kill switch?" )
2721
2722 def CASE12( self, main ):
2723 """
2724 Switch Up
2725 """
2726 # NOTE: You should probably run a topology check after this
2727 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002728 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002729 assert main, "main not defined"
2730 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002731 assert main.CLIs, "main.CLIs not defined"
2732 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002733 assert ONOS1Port, "ONOS1Port not defined"
2734 assert ONOS2Port, "ONOS2Port not defined"
2735 assert ONOS3Port, "ONOS3Port not defined"
2736 assert ONOS4Port, "ONOS4Port not defined"
2737 assert ONOS5Port, "ONOS5Port not defined"
2738 assert ONOS6Port, "ONOS6Port not defined"
2739 assert ONOS7Port, "ONOS7Port not defined"
2740
2741 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2742 switch = main.params[ 'kill' ][ 'switch' ]
2743 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2744 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002745 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002746 description = "Adding a switch to ensure it is discovered correctly"
2747 main.case( description )
2748
2749 main.step( "Add back " + switch )
2750 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2751 for peer in links:
2752 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002753 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002754 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2755 main.log.info( "Waiting " + str( switchSleep ) +
2756 " seconds for switch up to be discovered" )
2757 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002758 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002759 # Peek at the deleted switch
2760 main.log.warn( str( device ) )
2761 result = main.FALSE
2762 if device and device[ 'available' ]:
2763 result = main.TRUE
2764 utilities.assert_equals( expect=main.TRUE, actual=result,
2765 onpass="add switch successful",
2766 onfail="Failed to add switch?" )
2767
2768 def CASE13( self, main ):
2769 """
2770 Clean up
2771 """
2772 import os
2773 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002774 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002775 assert main, "main not defined"
2776 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002777 assert main.CLIs, "main.CLIs not defined"
2778 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002779
2780 # printing colors to terminal
2781 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2782 'blue': '\033[94m', 'green': '\033[92m',
2783 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2784 main.case( "Test Cleanup" )
2785 main.step( "Killing tcpdumps" )
2786 main.Mininet2.stopTcpdump()
2787
2788 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002789 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002790 main.step( "Copying MN pcap and ONOS log files to test station" )
2791 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2792 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002793 # NOTE: MN Pcap file is being saved to logdir.
2794 # We scp this file as MN and TestON aren't necessarily the same vm
2795
2796 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002797 # TODO: Load these from params
2798 # NOTE: must end in /
2799 logFolder = "/opt/onos/log/"
2800 logFiles = [ "karaf.log", "karaf.log.1" ]
2801 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002802 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002803 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002804 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002805 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2806 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002807 # std*.log's
2808 # NOTE: must end in /
2809 logFolder = "/opt/onos/var/"
2810 logFiles = [ "stderr.log", "stdout.log" ]
2811 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002812 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002813 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002814 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002815 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2816 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002817 else:
2818 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002819
2820 main.step( "Stopping Mininet" )
2821 mnResult = main.Mininet1.stopNet()
2822 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2823 onpass="Mininet stopped",
2824 onfail="MN cleanup NOT successful" )
2825
2826 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002827 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002828 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2829 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002830
2831 try:
2832 timerLog = open( main.logdir + "/Timers.csv", 'w')
2833 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2834 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2835 timerLog.close()
2836 except NameError, e:
2837 main.log.exception(e)
2838
2839 def CASE14( self, main ):
2840 """
2841 start election app on all onos nodes
2842 """
Jon Halle1a3b752015-07-22 13:02:46 -07002843 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002844 assert main, "main not defined"
2845 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002846 assert main.CLIs, "main.CLIs not defined"
2847 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002848
2849 main.case("Start Leadership Election app")
2850 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002851 onosCli = main.CLIs[ main.activeNodes[0] ]
2852 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002853 utilities.assert_equals(
2854 expect=main.TRUE,
2855 actual=appResult,
2856 onpass="Election app installed",
2857 onfail="Something went wrong with installing Leadership election" )
2858
2859 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002860 for i in main.activeNodes:
2861 main.CLIs[i].electionTestRun()
Jon Hall25463a82016-04-13 14:03:52 -07002862 time.sleep(5)
2863 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2864 sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall5cf14d52015-07-16 12:15:19 -07002865 utilities.assert_equals(
Jon Hall25463a82016-04-13 14:03:52 -07002866 expect=True,
2867 actual=sameResult,
2868 onpass="All nodes see the same leaderboards",
2869 onfail="Inconsistent leaderboards" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002870
Jon Hall25463a82016-04-13 14:03:52 -07002871 if sameResult:
2872 leader = leaders[ 0 ][ 0 ]
2873 if main.nodes[main.activeNodes[0]].ip_address in leader:
2874 correctLeader = True
2875 else:
2876 correctLeader = False
2877 main.step( "First node was elected leader" )
2878 utilities.assert_equals(
2879 expect=True,
2880 actual=correctLeader,
2881 onpass="Correct leader was elected",
2882 onfail="Incorrect leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002883
2884 def CASE15( self, main ):
2885 """
2886 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002887 15.1 Run election on each node
2888 15.2 Check that each node has the same leaders and candidates
2889 15.3 Find current leader and withdraw
2890 15.4 Check that a new node was elected leader
2891 15.5 Check that that new leader was the candidate of old leader
2892 15.6 Run for election on old leader
2893 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2894 15.8 Make sure that the old leader was added to the candidate list
2895
2896 old and new variable prefixes refer to data from before vs after
2897 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002898 """
2899 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002900 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 assert main, "main not defined"
2902 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002903 assert main.CLIs, "main.CLIs not defined"
2904 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002905
Jon Hall5cf14d52015-07-16 12:15:19 -07002906 description = "Check that Leadership Election is still functional"
2907 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002908 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002909
Jon Halla440e872016-03-31 15:15:50 -07002910 oldLeaders = [] # list of lists of each nodes' candidates before
2911 newLeaders = [] # list of lists of each nodes' candidates after
acsmars9475b1c2015-08-28 18:02:08 -07002912 oldLeader = '' # the old leader from oldLeaders, None if not same
2913 newLeader = '' # the new leaders fron newLoeaders, None if not same
2914 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002915 expectNoLeader = False # True when there is only one leader
2916 if main.numCtrls == 1:
2917 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002918
Jon Hall5cf14d52015-07-16 12:15:19 -07002919 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002920 electionResult = main.TRUE
2921
Jon Halla440e872016-03-31 15:15:50 -07002922 for i in main.activeNodes: # run test election on each node
2923 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars9475b1c2015-08-28 18:02:08 -07002924 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002925 utilities.assert_equals(
2926 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002927 actual=electionResult,
2928 onpass="All nodes successfully ran for leadership",
2929 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002930
acsmars3a72bde2015-09-02 14:16:22 -07002931 if electionResult == main.FALSE:
2932 main.log.error(
2933 "Skipping Test Case because Election Test App isn't loaded" )
2934 main.skipCase()
2935
acsmars9475b1c2015-08-28 18:02:08 -07002936 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002937 failMessage = "Nodes have different leaderboards"
Jon Halla440e872016-03-31 15:15:50 -07002938 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
Jon Hall41d39f12016-04-11 22:54:35 -07002939 sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Halla440e872016-03-31 15:15:50 -07002940 if sameResult:
2941 oldLeader = oldLeaders[ 0 ][ 0 ]
2942 main.log.warn( oldLeader )
acsmars9475b1c2015-08-28 18:02:08 -07002943 else:
Jon Halla440e872016-03-31 15:15:50 -07002944 oldLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002945 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002946 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002947 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002948 onpass="Leaderboards are consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002949 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002950
2951 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002952 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002953 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002954 if oldLeader is None:
2955 main.log.error( "Leadership isn't consistent." )
2956 withdrawResult = main.FALSE
2957 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002958 for i in main.activeNodes:
acsmars9475b1c2015-08-28 18:02:08 -07002959 if oldLeader == main.nodes[ i ].ip_address:
2960 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002961 break
2962 else: # FOR/ELSE statement
2963 main.log.error( "Leader election, could not find current leader" )
2964 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002965 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002966 utilities.assert_equals(
2967 expect=main.TRUE,
2968 actual=withdrawResult,
2969 onpass="Node was withdrawn from election",
2970 onfail="Node was not withdrawn from election" )
2971
acsmars9475b1c2015-08-28 18:02:08 -07002972 main.step( "Check that a new node was elected leader" )
acsmars9475b1c2015-08-28 18:02:08 -07002973 failMessage = "Nodes have different leaders"
acsmars9475b1c2015-08-28 18:02:08 -07002974 # Get new leaders and candidates
Jon Hall41d39f12016-04-11 22:54:35 -07002975 newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall3a7843a2016-04-12 03:01:09 -07002976 newLeader = None
Jon Halla440e872016-03-31 15:15:50 -07002977 if newLeaderResult:
Jon Hall3a7843a2016-04-12 03:01:09 -07002978 if newLeaders[ 0 ][ 0 ] == 'none':
2979 main.log.error( "No leader was elected on at least 1 node" )
2980 if not expectNoLeader:
2981 newLeaderResult = False
Jon Hall25463a82016-04-13 14:03:52 -07002982 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002983
acsmars9475b1c2015-08-28 18:02:08 -07002984 # Check that the new leader is not the older leader, which was withdrawn
2985 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002986 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08002987 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars9475b1c2015-08-28 18:02:08 -07002988 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002989 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002990 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07002991 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002992 onpass="Leadership election passed",
2993 onfail="Something went wrong with Leadership election" )
2994
Jon Halla440e872016-03-31 15:15:50 -07002995 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08002996 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars9475b1c2015-08-28 18:02:08 -07002997 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002998 if expectNoLeader:
2999 if newLeader == 'none':
3000 main.log.info( "No leader expected. None found. Pass" )
3001 correctCandidateResult = main.TRUE
3002 else:
3003 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3004 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003005 elif len( oldLeaders[0] ) >= 3:
3006 if newLeader == oldLeaders[ 0 ][ 2 ]:
3007 # correct leader was elected
3008 correctCandidateResult = main.TRUE
3009 else:
3010 correctCandidateResult = main.FALSE
3011 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3012 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003013 else:
3014 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003015 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003016 correctCandidateResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07003017 utilities.assert_equals(
3018 expect=main.TRUE,
3019 actual=correctCandidateResult,
3020 onpass="Correct Candidate Elected",
3021 onfail="Incorrect Candidate Elected" )
3022
Jon Hall5cf14d52015-07-16 12:15:19 -07003023 main.step( "Run for election on old leader( just so everyone " +
3024 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07003025 if oldLeaderCLI is not None:
3026 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003027 else:
acsmars9475b1c2015-08-28 18:02:08 -07003028 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003029 runResult = main.FALSE
3030 utilities.assert_equals(
3031 expect=main.TRUE,
3032 actual=runResult,
3033 onpass="App re-ran for election",
3034 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003035
acsmars9475b1c2015-08-28 18:02:08 -07003036 main.step(
3037 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003038 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003039 # Get new leaders and candidates
3040 reRunLeaders = []
3041 time.sleep( 5 ) # Paremterize
Jon Hall41d39f12016-04-11 22:54:35 -07003042 positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003043
acsmars9475b1c2015-08-28 18:02:08 -07003044 # Check that the re-elected node is last on the candidate List
Jon Hall3a7843a2016-04-12 03:01:09 -07003045 if not reRunLeaders[0]:
3046 positionResult = main.FALSE
3047 elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07003048 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3049 str( reRunLeaders[ 0 ] ) ) )
acsmars9475b1c2015-08-28 18:02:08 -07003050 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003051 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003052 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003053 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003054 onpass="Old leader successfully re-ran for election",
3055 onfail="Something went wrong with Leadership election after " +
3056 "the old leader re-ran for election" )
3057
3058 def CASE16( self, main ):
3059 """
3060 Install Distributed Primitives app
3061 """
3062 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003063 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003064 assert main, "main not defined"
3065 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003066 assert main.CLIs, "main.CLIs not defined"
3067 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003068
3069 # Variables for the distributed primitives tests
3070 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003071 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003072 global onosSet
3073 global onosSetName
3074 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003075 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003076 onosSet = set([])
3077 onosSetName = "TestON-set"
3078
3079 description = "Install Primitives app"
3080 main.case( description )
3081 main.step( "Install Primitives app" )
3082 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003083 node = main.activeNodes[0]
3084 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003085 utilities.assert_equals( expect=main.TRUE,
3086 actual=appResults,
3087 onpass="Primitives app activated",
3088 onfail="Primitives app not activated" )
3089 time.sleep( 5 ) # To allow all nodes to activate
3090
3091 def CASE17( self, main ):
3092 """
3093 Check for basic functionality with distributed primitives
3094 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003095 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003096 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 assert main, "main not defined"
3098 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003099 assert main.CLIs, "main.CLIs not defined"
3100 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003101 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 assert onosSetName, "onosSetName not defined"
3103 # NOTE: assert fails if value is 0/None/Empty/False
3104 try:
3105 pCounterValue
3106 except NameError:
3107 main.log.error( "pCounterValue not defined, setting to 0" )
3108 pCounterValue = 0
3109 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003110 onosSet
3111 except NameError:
3112 main.log.error( "onosSet not defined, setting to empty Set" )
3113 onosSet = set([])
3114 # Variables for the distributed primitives tests. These are local only
3115 addValue = "a"
3116 addAllValue = "a b c d e f"
3117 retainValue = "c d e f"
3118
3119 description = "Check for basic functionality with distributed " +\
3120 "primitives"
3121 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003122 main.caseExplanation = "Test the methods of the distributed " +\
3123 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003124 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003125 # Partitioned counters
3126 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003127 pCounters = []
3128 threads = []
3129 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003130 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003131 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3132 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003133 args=[ pCounterName ] )
3134 pCounterValue += 1
3135 addedPValues.append( pCounterValue )
3136 threads.append( t )
3137 t.start()
3138
3139 for t in threads:
3140 t.join()
3141 pCounters.append( t.result )
3142 # Check that counter incremented numController times
3143 pCounterResults = True
3144 for i in addedPValues:
3145 tmpResult = i in pCounters
3146 pCounterResults = pCounterResults and tmpResult
3147 if not tmpResult:
3148 main.log.error( str( i ) + " is not in partitioned "
3149 "counter incremented results" )
3150 utilities.assert_equals( expect=True,
3151 actual=pCounterResults,
3152 onpass="Default counter incremented",
3153 onfail="Error incrementing default" +
3154 " counter" )
3155
Jon Halle1a3b752015-07-22 13:02:46 -07003156 main.step( "Get then Increment a default counter on each node" )
3157 pCounters = []
3158 threads = []
3159 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003160 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003161 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3162 name="counterGetAndAdd-" + str( i ),
3163 args=[ pCounterName ] )
3164 addedPValues.append( pCounterValue )
3165 pCounterValue += 1
3166 threads.append( t )
3167 t.start()
3168
3169 for t in threads:
3170 t.join()
3171 pCounters.append( t.result )
3172 # Check that counter incremented numController times
3173 pCounterResults = True
3174 for i in addedPValues:
3175 tmpResult = i in pCounters
3176 pCounterResults = pCounterResults and tmpResult
3177 if not tmpResult:
3178 main.log.error( str( i ) + " is not in partitioned "
3179 "counter incremented results" )
3180 utilities.assert_equals( expect=True,
3181 actual=pCounterResults,
3182 onpass="Default counter incremented",
3183 onfail="Error incrementing default" +
3184 " counter" )
3185
3186 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07003187 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07003188 utilities.assert_equals( expect=main.TRUE,
3189 actual=incrementCheck,
3190 onpass="Added counters are correct",
3191 onfail="Added counters are incorrect" )
3192
3193 main.step( "Add -8 to then get a default counter on each node" )
3194 pCounters = []
3195 threads = []
3196 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003197 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003198 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3199 name="counterIncrement-" + str( i ),
3200 args=[ pCounterName ],
3201 kwargs={ "delta": -8 } )
3202 pCounterValue += -8
3203 addedPValues.append( pCounterValue )
3204 threads.append( t )
3205 t.start()
3206
3207 for t in threads:
3208 t.join()
3209 pCounters.append( t.result )
3210 # Check that counter incremented numController times
3211 pCounterResults = True
3212 for i in addedPValues:
3213 tmpResult = i in pCounters
3214 pCounterResults = pCounterResults and tmpResult
3215 if not tmpResult:
3216 main.log.error( str( i ) + " is not in partitioned "
3217 "counter incremented results" )
3218 utilities.assert_equals( expect=True,
3219 actual=pCounterResults,
3220 onpass="Default counter incremented",
3221 onfail="Error incrementing default" +
3222 " counter" )
3223
3224 main.step( "Add 5 to then get a default counter on each node" )
3225 pCounters = []
3226 threads = []
3227 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003228 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003229 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3230 name="counterIncrement-" + str( i ),
3231 args=[ pCounterName ],
3232 kwargs={ "delta": 5 } )
3233 pCounterValue += 5
3234 addedPValues.append( pCounterValue )
3235 threads.append( t )
3236 t.start()
3237
3238 for t in threads:
3239 t.join()
3240 pCounters.append( t.result )
3241 # Check that counter incremented numController times
3242 pCounterResults = True
3243 for i in addedPValues:
3244 tmpResult = i in pCounters
3245 pCounterResults = pCounterResults and tmpResult
3246 if not tmpResult:
3247 main.log.error( str( i ) + " is not in partitioned "
3248 "counter incremented results" )
3249 utilities.assert_equals( expect=True,
3250 actual=pCounterResults,
3251 onpass="Default counter incremented",
3252 onfail="Error incrementing default" +
3253 " counter" )
3254
3255 main.step( "Get then add 5 to a default counter on each node" )
3256 pCounters = []
3257 threads = []
3258 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003259 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003260 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3261 name="counterIncrement-" + str( i ),
3262 args=[ pCounterName ],
3263 kwargs={ "delta": 5 } )
3264 addedPValues.append( pCounterValue )
3265 pCounterValue += 5
3266 threads.append( t )
3267 t.start()
3268
3269 for t in threads:
3270 t.join()
3271 pCounters.append( t.result )
3272 # Check that counter incremented numController times
3273 pCounterResults = True
3274 for i in addedPValues:
3275 tmpResult = i in pCounters
3276 pCounterResults = pCounterResults and tmpResult
3277 if not tmpResult:
3278 main.log.error( str( i ) + " is not in partitioned "
3279 "counter incremented results" )
3280 utilities.assert_equals( expect=True,
3281 actual=pCounterResults,
3282 onpass="Default counter incremented",
3283 onfail="Error incrementing default" +
3284 " counter" )
3285
3286 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07003287 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07003288 utilities.assert_equals( expect=main.TRUE,
3289 actual=incrementCheck,
3290 onpass="Added counters are correct",
3291 onfail="Added counters are incorrect" )
3292
Jon Hall5cf14d52015-07-16 12:15:19 -07003293 # DISTRIBUTED SETS
3294 main.step( "Distributed Set get" )
3295 size = len( onosSet )
3296 getResponses = []
3297 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003298 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003299 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003300 name="setTestGet-" + str( i ),
3301 args=[ onosSetName ] )
3302 threads.append( t )
3303 t.start()
3304 for t in threads:
3305 t.join()
3306 getResponses.append( t.result )
3307
3308 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003309 for i in range( len( main.activeNodes ) ):
3310 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003311 if isinstance( getResponses[ i ], list):
3312 current = set( getResponses[ i ] )
3313 if len( current ) == len( getResponses[ i ] ):
3314 # no repeats
3315 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003316 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003317 " has incorrect view" +
3318 " of set " + onosSetName + ":\n" +
3319 str( getResponses[ i ] ) )
3320 main.log.debug( "Expected: " + str( onosSet ) )
3321 main.log.debug( "Actual: " + str( current ) )
3322 getResults = main.FALSE
3323 else:
3324 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003325 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003326 " has repeat elements in" +
3327 " set " + onosSetName + ":\n" +
3328 str( getResponses[ i ] ) )
3329 getResults = main.FALSE
3330 elif getResponses[ i ] == main.ERROR:
3331 getResults = main.FALSE
3332 utilities.assert_equals( expect=main.TRUE,
3333 actual=getResults,
3334 onpass="Set elements are correct",
3335 onfail="Set elements are incorrect" )
3336
3337 main.step( "Distributed Set size" )
3338 sizeResponses = []
3339 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003340 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003341 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003342 name="setTestSize-" + str( i ),
3343 args=[ onosSetName ] )
3344 threads.append( t )
3345 t.start()
3346 for t in threads:
3347 t.join()
3348 sizeResponses.append( t.result )
3349
3350 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003351 for i in range( len( main.activeNodes ) ):
3352 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003353 if size != sizeResponses[ i ]:
3354 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003355 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003356 " expected a size of " + str( size ) +
3357 " for set " + onosSetName +
3358 " but got " + str( sizeResponses[ i ] ) )
3359 utilities.assert_equals( expect=main.TRUE,
3360 actual=sizeResults,
3361 onpass="Set sizes are correct",
3362 onfail="Set sizes are incorrect" )
3363
3364 main.step( "Distributed Set add()" )
3365 onosSet.add( addValue )
3366 addResponses = []
3367 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003368 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003369 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003370 name="setTestAdd-" + str( i ),
3371 args=[ onosSetName, addValue ] )
3372 threads.append( t )
3373 t.start()
3374 for t in threads:
3375 t.join()
3376 addResponses.append( t.result )
3377
3378 # main.TRUE = successfully changed the set
3379 # main.FALSE = action resulted in no change in set
3380 # main.ERROR - Some error in executing the function
3381 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003382 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003383 if addResponses[ i ] == main.TRUE:
3384 # All is well
3385 pass
3386 elif addResponses[ i ] == main.FALSE:
3387 # Already in set, probably fine
3388 pass
3389 elif addResponses[ i ] == main.ERROR:
3390 # Error in execution
3391 addResults = main.FALSE
3392 else:
3393 # unexpected result
3394 addResults = main.FALSE
3395 if addResults != main.TRUE:
3396 main.log.error( "Error executing set add" )
3397
3398 # Check if set is still correct
3399 size = len( onosSet )
3400 getResponses = []
3401 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003402 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003403 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003404 name="setTestGet-" + str( i ),
3405 args=[ onosSetName ] )
3406 threads.append( t )
3407 t.start()
3408 for t in threads:
3409 t.join()
3410 getResponses.append( t.result )
3411 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003412 for i in range( len( main.activeNodes ) ):
3413 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003414 if isinstance( getResponses[ i ], list):
3415 current = set( getResponses[ i ] )
3416 if len( current ) == len( getResponses[ i ] ):
3417 # no repeats
3418 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003419 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003420 " of set " + onosSetName + ":\n" +
3421 str( getResponses[ i ] ) )
3422 main.log.debug( "Expected: " + str( onosSet ) )
3423 main.log.debug( "Actual: " + str( current ) )
3424 getResults = main.FALSE
3425 else:
3426 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003427 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003428 " set " + onosSetName + ":\n" +
3429 str( getResponses[ i ] ) )
3430 getResults = main.FALSE
3431 elif getResponses[ i ] == main.ERROR:
3432 getResults = main.FALSE
3433 sizeResponses = []
3434 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003435 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003436 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003437 name="setTestSize-" + str( i ),
3438 args=[ onosSetName ] )
3439 threads.append( t )
3440 t.start()
3441 for t in threads:
3442 t.join()
3443 sizeResponses.append( t.result )
3444 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003445 for i in range( len( main.activeNodes ) ):
3446 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003447 if size != sizeResponses[ i ]:
3448 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003449 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003450 " expected a size of " + str( size ) +
3451 " for set " + onosSetName +
3452 " but got " + str( sizeResponses[ i ] ) )
3453 addResults = addResults and getResults and sizeResults
3454 utilities.assert_equals( expect=main.TRUE,
3455 actual=addResults,
3456 onpass="Set add correct",
3457 onfail="Set add was incorrect" )
3458
3459 main.step( "Distributed Set addAll()" )
3460 onosSet.update( addAllValue.split() )
3461 addResponses = []
3462 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003463 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003464 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003465 name="setTestAddAll-" + str( i ),
3466 args=[ onosSetName, addAllValue ] )
3467 threads.append( t )
3468 t.start()
3469 for t in threads:
3470 t.join()
3471 addResponses.append( t.result )
3472
3473 # main.TRUE = successfully changed the set
3474 # main.FALSE = action resulted in no change in set
3475 # main.ERROR - Some error in executing the function
3476 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003477 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003478 if addResponses[ i ] == main.TRUE:
3479 # All is well
3480 pass
3481 elif addResponses[ i ] == main.FALSE:
3482 # Already in set, probably fine
3483 pass
3484 elif addResponses[ i ] == main.ERROR:
3485 # Error in execution
3486 addAllResults = main.FALSE
3487 else:
3488 # unexpected result
3489 addAllResults = main.FALSE
3490 if addAllResults != main.TRUE:
3491 main.log.error( "Error executing set addAll" )
3492
3493 # Check if set is still correct
3494 size = len( onosSet )
3495 getResponses = []
3496 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003497 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003498 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003499 name="setTestGet-" + str( i ),
3500 args=[ onosSetName ] )
3501 threads.append( t )
3502 t.start()
3503 for t in threads:
3504 t.join()
3505 getResponses.append( t.result )
3506 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003507 for i in range( len( main.activeNodes ) ):
3508 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003509 if isinstance( getResponses[ i ], list):
3510 current = set( getResponses[ i ] )
3511 if len( current ) == len( getResponses[ i ] ):
3512 # no repeats
3513 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003514 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003515 " has incorrect view" +
3516 " of set " + onosSetName + ":\n" +
3517 str( getResponses[ i ] ) )
3518 main.log.debug( "Expected: " + str( onosSet ) )
3519 main.log.debug( "Actual: " + str( current ) )
3520 getResults = main.FALSE
3521 else:
3522 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003523 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003524 " has repeat elements in" +
3525 " set " + onosSetName + ":\n" +
3526 str( getResponses[ i ] ) )
3527 getResults = main.FALSE
3528 elif getResponses[ i ] == main.ERROR:
3529 getResults = main.FALSE
3530 sizeResponses = []
3531 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003532 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003533 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003534 name="setTestSize-" + str( i ),
3535 args=[ onosSetName ] )
3536 threads.append( t )
3537 t.start()
3538 for t in threads:
3539 t.join()
3540 sizeResponses.append( t.result )
3541 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003542 for i in range( len( main.activeNodes ) ):
3543 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003544 if size != sizeResponses[ i ]:
3545 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003546 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003547 " expected a size of " + str( size ) +
3548 " for set " + onosSetName +
3549 " but got " + str( sizeResponses[ i ] ) )
3550 addAllResults = addAllResults and getResults and sizeResults
3551 utilities.assert_equals( expect=main.TRUE,
3552 actual=addAllResults,
3553 onpass="Set addAll correct",
3554 onfail="Set addAll was incorrect" )
3555
3556 main.step( "Distributed Set contains()" )
3557 containsResponses = []
3558 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003559 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003560 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003561 name="setContains-" + str( i ),
3562 args=[ onosSetName ],
3563 kwargs={ "values": addValue } )
3564 threads.append( t )
3565 t.start()
3566 for t in threads:
3567 t.join()
3568 # NOTE: This is the tuple
3569 containsResponses.append( t.result )
3570
3571 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003572 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003573 if containsResponses[ i ] == main.ERROR:
3574 containsResults = main.FALSE
3575 else:
3576 containsResults = containsResults and\
3577 containsResponses[ i ][ 1 ]
3578 utilities.assert_equals( expect=main.TRUE,
3579 actual=containsResults,
3580 onpass="Set contains is functional",
3581 onfail="Set contains failed" )
3582
3583 main.step( "Distributed Set containsAll()" )
3584 containsAllResponses = []
3585 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003586 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003587 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003588 name="setContainsAll-" + str( i ),
3589 args=[ onosSetName ],
3590 kwargs={ "values": addAllValue } )
3591 threads.append( t )
3592 t.start()
3593 for t in threads:
3594 t.join()
3595 # NOTE: This is the tuple
3596 containsAllResponses.append( t.result )
3597
3598 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003599 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003600 if containsResponses[ i ] == main.ERROR:
3601 containsResults = main.FALSE
3602 else:
3603 containsResults = containsResults and\
3604 containsResponses[ i ][ 1 ]
3605 utilities.assert_equals( expect=main.TRUE,
3606 actual=containsAllResults,
3607 onpass="Set containsAll is functional",
3608 onfail="Set containsAll failed" )
3609
3610 main.step( "Distributed Set remove()" )
3611 onosSet.remove( addValue )
3612 removeResponses = []
3613 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003614 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003615 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003616 name="setTestRemove-" + str( i ),
3617 args=[ onosSetName, addValue ] )
3618 threads.append( t )
3619 t.start()
3620 for t in threads:
3621 t.join()
3622 removeResponses.append( t.result )
3623
3624 # main.TRUE = successfully changed the set
3625 # main.FALSE = action resulted in no change in set
3626 # main.ERROR - Some error in executing the function
3627 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003628 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003629 if removeResponses[ i ] == main.TRUE:
3630 # All is well
3631 pass
3632 elif removeResponses[ i ] == main.FALSE:
3633 # not in set, probably fine
3634 pass
3635 elif removeResponses[ i ] == main.ERROR:
3636 # Error in execution
3637 removeResults = main.FALSE
3638 else:
3639 # unexpected result
3640 removeResults = main.FALSE
3641 if removeResults != main.TRUE:
3642 main.log.error( "Error executing set remove" )
3643
3644 # Check if set is still correct
3645 size = len( onosSet )
3646 getResponses = []
3647 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003648 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003649 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003650 name="setTestGet-" + str( i ),
3651 args=[ onosSetName ] )
3652 threads.append( t )
3653 t.start()
3654 for t in threads:
3655 t.join()
3656 getResponses.append( t.result )
3657 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003658 for i in range( len( main.activeNodes ) ):
3659 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003660 if isinstance( getResponses[ i ], list):
3661 current = set( getResponses[ i ] )
3662 if len( current ) == len( getResponses[ i ] ):
3663 # no repeats
3664 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003665 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003666 " has incorrect view" +
3667 " of set " + onosSetName + ":\n" +
3668 str( getResponses[ i ] ) )
3669 main.log.debug( "Expected: " + str( onosSet ) )
3670 main.log.debug( "Actual: " + str( current ) )
3671 getResults = main.FALSE
3672 else:
3673 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003674 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003675 " has repeat elements in" +
3676 " set " + onosSetName + ":\n" +
3677 str( getResponses[ i ] ) )
3678 getResults = main.FALSE
3679 elif getResponses[ i ] == main.ERROR:
3680 getResults = main.FALSE
3681 sizeResponses = []
3682 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003683 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003684 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003685 name="setTestSize-" + str( i ),
3686 args=[ onosSetName ] )
3687 threads.append( t )
3688 t.start()
3689 for t in threads:
3690 t.join()
3691 sizeResponses.append( t.result )
3692 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003693 for i in range( len( main.activeNodes ) ):
3694 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003695 if size != sizeResponses[ i ]:
3696 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003697 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003698 " expected a size of " + str( size ) +
3699 " for set " + onosSetName +
3700 " but got " + str( sizeResponses[ i ] ) )
3701 removeResults = removeResults and getResults and sizeResults
3702 utilities.assert_equals( expect=main.TRUE,
3703 actual=removeResults,
3704 onpass="Set remove correct",
3705 onfail="Set remove was incorrect" )
3706
3707 main.step( "Distributed Set removeAll()" )
3708 onosSet.difference_update( addAllValue.split() )
3709 removeAllResponses = []
3710 threads = []
3711 try:
Jon Halla440e872016-03-31 15:15:50 -07003712 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003713 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003714 name="setTestRemoveAll-" + str( i ),
3715 args=[ onosSetName, addAllValue ] )
3716 threads.append( t )
3717 t.start()
3718 for t in threads:
3719 t.join()
3720 removeAllResponses.append( t.result )
3721 except Exception, e:
3722 main.log.exception(e)
3723
3724 # main.TRUE = successfully changed the set
3725 # main.FALSE = action resulted in no change in set
3726 # main.ERROR - Some error in executing the function
3727 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003728 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003729 if removeAllResponses[ i ] == main.TRUE:
3730 # All is well
3731 pass
3732 elif removeAllResponses[ i ] == main.FALSE:
3733 # not in set, probably fine
3734 pass
3735 elif removeAllResponses[ i ] == main.ERROR:
3736 # Error in execution
3737 removeAllResults = main.FALSE
3738 else:
3739 # unexpected result
3740 removeAllResults = main.FALSE
3741 if removeAllResults != main.TRUE:
3742 main.log.error( "Error executing set removeAll" )
3743
3744 # Check if set is still correct
3745 size = len( onosSet )
3746 getResponses = []
3747 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003748 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003749 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003750 name="setTestGet-" + str( i ),
3751 args=[ onosSetName ] )
3752 threads.append( t )
3753 t.start()
3754 for t in threads:
3755 t.join()
3756 getResponses.append( t.result )
3757 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003758 for i in range( len( main.activeNodes ) ):
3759 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003760 if isinstance( getResponses[ i ], list):
3761 current = set( getResponses[ i ] )
3762 if len( current ) == len( getResponses[ i ] ):
3763 # no repeats
3764 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003765 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003766 " has incorrect view" +
3767 " of set " + onosSetName + ":\n" +
3768 str( getResponses[ i ] ) )
3769 main.log.debug( "Expected: " + str( onosSet ) )
3770 main.log.debug( "Actual: " + str( current ) )
3771 getResults = main.FALSE
3772 else:
3773 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003774 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003775 " has repeat elements in" +
3776 " set " + onosSetName + ":\n" +
3777 str( getResponses[ i ] ) )
3778 getResults = main.FALSE
3779 elif getResponses[ i ] == main.ERROR:
3780 getResults = main.FALSE
3781 sizeResponses = []
3782 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003783 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003784 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003785 name="setTestSize-" + str( i ),
3786 args=[ onosSetName ] )
3787 threads.append( t )
3788 t.start()
3789 for t in threads:
3790 t.join()
3791 sizeResponses.append( t.result )
3792 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003793 for i in range( len( main.activeNodes ) ):
3794 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003795 if size != sizeResponses[ i ]:
3796 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003797 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003798 " expected a size of " + str( size ) +
3799 " for set " + onosSetName +
3800 " but got " + str( sizeResponses[ i ] ) )
3801 removeAllResults = removeAllResults and getResults and sizeResults
3802 utilities.assert_equals( expect=main.TRUE,
3803 actual=removeAllResults,
3804 onpass="Set removeAll correct",
3805 onfail="Set removeAll was incorrect" )
3806
3807 main.step( "Distributed Set addAll()" )
3808 onosSet.update( addAllValue.split() )
3809 addResponses = []
3810 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003811 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003812 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003813 name="setTestAddAll-" + str( i ),
3814 args=[ onosSetName, addAllValue ] )
3815 threads.append( t )
3816 t.start()
3817 for t in threads:
3818 t.join()
3819 addResponses.append( t.result )
3820
3821 # main.TRUE = successfully changed the set
3822 # main.FALSE = action resulted in no change in set
3823 # main.ERROR - Some error in executing the function
3824 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003825 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003826 if addResponses[ i ] == main.TRUE:
3827 # All is well
3828 pass
3829 elif addResponses[ i ] == main.FALSE:
3830 # Already in set, probably fine
3831 pass
3832 elif addResponses[ i ] == main.ERROR:
3833 # Error in execution
3834 addAllResults = main.FALSE
3835 else:
3836 # unexpected result
3837 addAllResults = main.FALSE
3838 if addAllResults != main.TRUE:
3839 main.log.error( "Error executing set addAll" )
3840
3841 # Check if set is still correct
3842 size = len( onosSet )
3843 getResponses = []
3844 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003845 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003846 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003847 name="setTestGet-" + str( i ),
3848 args=[ onosSetName ] )
3849 threads.append( t )
3850 t.start()
3851 for t in threads:
3852 t.join()
3853 getResponses.append( t.result )
3854 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003855 for i in range( len( main.activeNodes ) ):
3856 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003857 if isinstance( getResponses[ i ], list):
3858 current = set( getResponses[ i ] )
3859 if len( current ) == len( getResponses[ i ] ):
3860 # no repeats
3861 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003862 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003863 " has incorrect view" +
3864 " of set " + onosSetName + ":\n" +
3865 str( getResponses[ i ] ) )
3866 main.log.debug( "Expected: " + str( onosSet ) )
3867 main.log.debug( "Actual: " + str( current ) )
3868 getResults = main.FALSE
3869 else:
3870 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003871 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003872 " has repeat elements in" +
3873 " set " + onosSetName + ":\n" +
3874 str( getResponses[ i ] ) )
3875 getResults = main.FALSE
3876 elif getResponses[ i ] == main.ERROR:
3877 getResults = main.FALSE
3878 sizeResponses = []
3879 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003880 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003881 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003882 name="setTestSize-" + str( i ),
3883 args=[ onosSetName ] )
3884 threads.append( t )
3885 t.start()
3886 for t in threads:
3887 t.join()
3888 sizeResponses.append( t.result )
3889 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003890 for i in range( len( main.activeNodes ) ):
3891 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003892 if size != sizeResponses[ i ]:
3893 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003894 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003895 " expected a size of " + str( size ) +
3896 " for set " + onosSetName +
3897 " but got " + str( sizeResponses[ i ] ) )
3898 addAllResults = addAllResults and getResults and sizeResults
3899 utilities.assert_equals( expect=main.TRUE,
3900 actual=addAllResults,
3901 onpass="Set addAll correct",
3902 onfail="Set addAll was incorrect" )
3903
3904 main.step( "Distributed Set clear()" )
3905 onosSet.clear()
3906 clearResponses = []
3907 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003908 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003909 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003910 name="setTestClear-" + str( i ),
3911 args=[ onosSetName, " "], # Values doesn't matter
3912 kwargs={ "clear": True } )
3913 threads.append( t )
3914 t.start()
3915 for t in threads:
3916 t.join()
3917 clearResponses.append( t.result )
3918
3919 # main.TRUE = successfully changed the set
3920 # main.FALSE = action resulted in no change in set
3921 # main.ERROR - Some error in executing the function
3922 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003923 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003924 if clearResponses[ i ] == main.TRUE:
3925 # All is well
3926 pass
3927 elif clearResponses[ i ] == main.FALSE:
3928 # Nothing set, probably fine
3929 pass
3930 elif clearResponses[ i ] == main.ERROR:
3931 # Error in execution
3932 clearResults = main.FALSE
3933 else:
3934 # unexpected result
3935 clearResults = main.FALSE
3936 if clearResults != main.TRUE:
3937 main.log.error( "Error executing set clear" )
3938
3939 # Check if set is still correct
3940 size = len( onosSet )
3941 getResponses = []
3942 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003943 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003944 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003945 name="setTestGet-" + str( i ),
3946 args=[ onosSetName ] )
3947 threads.append( t )
3948 t.start()
3949 for t in threads:
3950 t.join()
3951 getResponses.append( t.result )
3952 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003953 for i in range( len( main.activeNodes ) ):
3954 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003955 if isinstance( getResponses[ i ], list):
3956 current = set( getResponses[ i ] )
3957 if len( current ) == len( getResponses[ i ] ):
3958 # no repeats
3959 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003960 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003961 " has incorrect view" +
3962 " of set " + onosSetName + ":\n" +
3963 str( getResponses[ i ] ) )
3964 main.log.debug( "Expected: " + str( onosSet ) )
3965 main.log.debug( "Actual: " + str( current ) )
3966 getResults = main.FALSE
3967 else:
3968 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003969 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003970 " has repeat elements in" +
3971 " set " + onosSetName + ":\n" +
3972 str( getResponses[ i ] ) )
3973 getResults = main.FALSE
3974 elif getResponses[ i ] == main.ERROR:
3975 getResults = main.FALSE
3976 sizeResponses = []
3977 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003978 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003979 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003980 name="setTestSize-" + str( i ),
3981 args=[ onosSetName ] )
3982 threads.append( t )
3983 t.start()
3984 for t in threads:
3985 t.join()
3986 sizeResponses.append( t.result )
3987 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003988 for i in range( len( main.activeNodes ) ):
3989 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003990 if size != sizeResponses[ i ]:
3991 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003992 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003993 " expected a size of " + str( size ) +
3994 " for set " + onosSetName +
3995 " but got " + str( sizeResponses[ i ] ) )
3996 clearResults = clearResults and getResults and sizeResults
3997 utilities.assert_equals( expect=main.TRUE,
3998 actual=clearResults,
3999 onpass="Set clear correct",
4000 onfail="Set clear was incorrect" )
4001
4002 main.step( "Distributed Set addAll()" )
4003 onosSet.update( addAllValue.split() )
4004 addResponses = []
4005 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004006 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004007 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004008 name="setTestAddAll-" + str( i ),
4009 args=[ onosSetName, addAllValue ] )
4010 threads.append( t )
4011 t.start()
4012 for t in threads:
4013 t.join()
4014 addResponses.append( t.result )
4015
4016 # main.TRUE = successfully changed the set
4017 # main.FALSE = action resulted in no change in set
4018 # main.ERROR - Some error in executing the function
4019 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004020 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004021 if addResponses[ i ] == main.TRUE:
4022 # All is well
4023 pass
4024 elif addResponses[ i ] == main.FALSE:
4025 # Already in set, probably fine
4026 pass
4027 elif addResponses[ i ] == main.ERROR:
4028 # Error in execution
4029 addAllResults = main.FALSE
4030 else:
4031 # unexpected result
4032 addAllResults = main.FALSE
4033 if addAllResults != main.TRUE:
4034 main.log.error( "Error executing set addAll" )
4035
4036 # Check if set is still correct
4037 size = len( onosSet )
4038 getResponses = []
4039 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004040 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004041 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004042 name="setTestGet-" + str( i ),
4043 args=[ onosSetName ] )
4044 threads.append( t )
4045 t.start()
4046 for t in threads:
4047 t.join()
4048 getResponses.append( t.result )
4049 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004050 for i in range( len( main.activeNodes ) ):
4051 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004052 if isinstance( getResponses[ i ], list):
4053 current = set( getResponses[ i ] )
4054 if len( current ) == len( getResponses[ i ] ):
4055 # no repeats
4056 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004057 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004058 " has incorrect view" +
4059 " of set " + onosSetName + ":\n" +
4060 str( getResponses[ i ] ) )
4061 main.log.debug( "Expected: " + str( onosSet ) )
4062 main.log.debug( "Actual: " + str( current ) )
4063 getResults = main.FALSE
4064 else:
4065 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004066 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004067 " has repeat elements in" +
4068 " set " + onosSetName + ":\n" +
4069 str( getResponses[ i ] ) )
4070 getResults = main.FALSE
4071 elif getResponses[ i ] == main.ERROR:
4072 getResults = main.FALSE
4073 sizeResponses = []
4074 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004075 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004076 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004077 name="setTestSize-" + str( i ),
4078 args=[ onosSetName ] )
4079 threads.append( t )
4080 t.start()
4081 for t in threads:
4082 t.join()
4083 sizeResponses.append( t.result )
4084 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004085 for i in range( len( main.activeNodes ) ):
4086 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004087 if size != sizeResponses[ i ]:
4088 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004089 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004090 " expected a size of " + str( size ) +
4091 " for set " + onosSetName +
4092 " but got " + str( sizeResponses[ i ] ) )
4093 addAllResults = addAllResults and getResults and sizeResults
4094 utilities.assert_equals( expect=main.TRUE,
4095 actual=addAllResults,
4096 onpass="Set addAll correct",
4097 onfail="Set addAll was incorrect" )
4098
4099 main.step( "Distributed Set retain()" )
4100 onosSet.intersection_update( retainValue.split() )
4101 retainResponses = []
4102 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004103 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004104 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004105 name="setTestRetain-" + str( i ),
4106 args=[ onosSetName, retainValue ],
4107 kwargs={ "retain": True } )
4108 threads.append( t )
4109 t.start()
4110 for t in threads:
4111 t.join()
4112 retainResponses.append( t.result )
4113
4114 # main.TRUE = successfully changed the set
4115 # main.FALSE = action resulted in no change in set
4116 # main.ERROR - Some error in executing the function
4117 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004118 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004119 if retainResponses[ i ] == main.TRUE:
4120 # All is well
4121 pass
4122 elif retainResponses[ i ] == main.FALSE:
4123 # Already in set, probably fine
4124 pass
4125 elif retainResponses[ i ] == main.ERROR:
4126 # Error in execution
4127 retainResults = main.FALSE
4128 else:
4129 # unexpected result
4130 retainResults = main.FALSE
4131 if retainResults != main.TRUE:
4132 main.log.error( "Error executing set retain" )
4133
4134 # Check if set is still correct
4135 size = len( onosSet )
4136 getResponses = []
4137 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004138 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004139 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004140 name="setTestGet-" + str( i ),
4141 args=[ onosSetName ] )
4142 threads.append( t )
4143 t.start()
4144 for t in threads:
4145 t.join()
4146 getResponses.append( t.result )
4147 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004148 for i in range( len( main.activeNodes ) ):
4149 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004150 if isinstance( getResponses[ i ], list):
4151 current = set( getResponses[ i ] )
4152 if len( current ) == len( getResponses[ i ] ):
4153 # no repeats
4154 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004155 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004156 " has incorrect view" +
4157 " of set " + onosSetName + ":\n" +
4158 str( getResponses[ i ] ) )
4159 main.log.debug( "Expected: " + str( onosSet ) )
4160 main.log.debug( "Actual: " + str( current ) )
4161 getResults = main.FALSE
4162 else:
4163 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004164 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004165 " has repeat elements in" +
4166 " set " + onosSetName + ":\n" +
4167 str( getResponses[ i ] ) )
4168 getResults = main.FALSE
4169 elif getResponses[ i ] == main.ERROR:
4170 getResults = main.FALSE
4171 sizeResponses = []
4172 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004173 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004174 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004175 name="setTestSize-" + str( i ),
4176 args=[ onosSetName ] )
4177 threads.append( t )
4178 t.start()
4179 for t in threads:
4180 t.join()
4181 sizeResponses.append( t.result )
4182 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004183 for i in range( len( main.activeNodes ) ):
4184 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004185 if size != sizeResponses[ i ]:
4186 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004187 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004188 str( size ) + " for set " + onosSetName +
4189 " but got " + str( sizeResponses[ i ] ) )
4190 retainResults = retainResults and getResults and sizeResults
4191 utilities.assert_equals( expect=main.TRUE,
4192 actual=retainResults,
4193 onpass="Set retain correct",
4194 onfail="Set retain was incorrect" )
4195
Jon Hall2a5002c2015-08-21 16:49:11 -07004196 # Transactional maps
4197 main.step( "Partitioned Transactional maps put" )
4198 tMapValue = "Testing"
4199 numKeys = 100
4200 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004201 node = main.activeNodes[0]
4202 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004203 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004204 for i in putResponses:
4205 if putResponses[ i ][ 'value' ] != tMapValue:
4206 putResult = False
4207 else:
4208 putResult = False
4209 if not putResult:
4210 main.log.debug( "Put response values: " + str( putResponses ) )
4211 utilities.assert_equals( expect=True,
4212 actual=putResult,
4213 onpass="Partitioned Transactional Map put successful",
4214 onfail="Partitioned Transactional Map put values are incorrect" )
4215
4216 main.step( "Partitioned Transactional maps get" )
4217 getCheck = True
4218 for n in range( 1, numKeys + 1 ):
4219 getResponses = []
4220 threads = []
4221 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004222 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004223 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4224 name="TMap-get-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08004225 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004226 threads.append( t )
4227 t.start()
4228 for t in threads:
4229 t.join()
4230 getResponses.append( t.result )
4231 for node in getResponses:
4232 if node != tMapValue:
4233 valueCheck = False
4234 if not valueCheck:
4235 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4236 main.log.warn( getResponses )
4237 getCheck = getCheck and valueCheck
4238 utilities.assert_equals( expect=True,
4239 actual=getCheck,
4240 onpass="Partitioned Transactional Map get values were correct",
4241 onfail="Partitioned Transactional Map values incorrect" )