blob: 6aab7aac1e5ff5f9dc44b5706ce6075ea280d714 [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" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700269 main.log.error( "Failed to start ONOS, stopping test" )
270 main.cleanup()
271 main.exit()
272
Jon Hall172b7ba2016-04-07 18:12:20 -0700273 main.step( "Activate apps defined in the params file" )
274 # get data from the params
275 apps = main.params.get( 'apps' )
276 if apps:
277 apps = apps.split(',')
278 main.log.warn( apps )
279 activateResult = True
280 for app in apps:
281 main.CLIs[ 0 ].app( app, "Activate" )
282 # TODO: check this worked
283 time.sleep( 10 ) # wait for apps to activate
284 for app in apps:
285 state = main.CLIs[ 0 ].appStatus( app )
286 if state == "ACTIVE":
287 activateResult = activeResult and True
288 else:
289 main.log.error( "{} is in {} state".format( app, state ) )
290 activeResult = False
291 utilities.assert_equals( expect=True,
292 actual=activateResult,
293 onpass="Successfully activated apps",
294 onfail="Failed to activate apps" )
295 else:
296 main.log.warn( "No apps were specified to be loaded after startup" )
297
298 main.step( "Set ONOS configurations" )
299 config = main.params.get( 'ONOS_Configuration' )
300 if config:
301 main.log.debug( config )
302 checkResult = main.TRUE
303 for component in config:
304 for setting in config[component]:
305 value = config[component][setting]
306 check = main.CLIs[ 0 ].setCfg( component, setting, value )
307 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
308 checkResult = check and checkResult
309 utilities.assert_equals( expect=main.TRUE,
310 actual=checkResult,
311 onpass="Successfully set config",
312 onfail="Failed to set config" )
313 else:
314 main.log.warn( "No configurations were specified to be changed after startup" )
315
Jon Hall9d2dcad2016-04-08 10:15:20 -0700316 main.step( "App Ids check" )
317 appCheck = main.TRUE
318 threads = []
319 for i in main.activeNodes:
320 t = main.Thread( target=main.CLIs[i].appToIDCheck,
321 name="appToIDCheck-" + str( i ),
322 args=[] )
323 threads.append( t )
324 t.start()
325
326 for t in threads:
327 t.join()
328 appCheck = appCheck and t.result
329 if appCheck != main.TRUE:
330 node = main.activeNodes[0]
331 main.log.warn( main.CLIs[node].apps() )
332 main.log.warn( main.CLIs[node].appIDs() )
333 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
334 onpass="App Ids seem to be correct",
335 onfail="Something is wrong with app Ids" )
336
Jon Hall5cf14d52015-07-16 12:15:19 -0700337 def CASE2( self, main ):
338 """
339 Assign devices to controllers
340 """
341 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700342 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700343 assert main, "main not defined"
344 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700345 assert main.CLIs, "main.CLIs not defined"
346 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700347 assert ONOS1Port, "ONOS1Port not defined"
348 assert ONOS2Port, "ONOS2Port not defined"
349 assert ONOS3Port, "ONOS3Port not defined"
350 assert ONOS4Port, "ONOS4Port not defined"
351 assert ONOS5Port, "ONOS5Port not defined"
352 assert ONOS6Port, "ONOS6Port not defined"
353 assert ONOS7Port, "ONOS7Port not defined"
354
355 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700356 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700357 "and check that an ONOS node becomes the " +\
358 "master of the device."
359 main.step( "Assign switches to controllers" )
360
361 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700362 for i in range( main.numCtrls ):
363 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700364 swList = []
365 for i in range( 1, 29 ):
366 swList.append( "s" + str( i ) )
367 main.Mininet1.assignSwController( sw=swList, ip=ipList )
368
369 mastershipCheck = main.TRUE
370 for i in range( 1, 29 ):
371 response = main.Mininet1.getSwController( "s" + str( i ) )
372 try:
373 main.log.info( str( response ) )
374 except Exception:
375 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700376 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700377 if re.search( "tcp:" + node.ip_address, response ):
378 mastershipCheck = mastershipCheck and main.TRUE
379 else:
380 main.log.error( "Error, node " + node.ip_address + " is " +
381 "not in the list of controllers s" +
382 str( i ) + " is connecting to." )
383 mastershipCheck = main.FALSE
384 utilities.assert_equals(
385 expect=main.TRUE,
386 actual=mastershipCheck,
387 onpass="Switch mastership assigned correctly",
388 onfail="Switches not assigned correctly to controllers" )
389
390 def CASE21( self, main ):
391 """
392 Assign mastership to controllers
393 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700394 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700395 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700396 assert main, "main not defined"
397 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700398 assert main.CLIs, "main.CLIs not defined"
399 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700400 assert ONOS1Port, "ONOS1Port not defined"
401 assert ONOS2Port, "ONOS2Port not defined"
402 assert ONOS3Port, "ONOS3Port not defined"
403 assert ONOS4Port, "ONOS4Port not defined"
404 assert ONOS5Port, "ONOS5Port not defined"
405 assert ONOS6Port, "ONOS6Port not defined"
406 assert ONOS7Port, "ONOS7Port not defined"
407
408 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700409 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700410 "device. Then manually assign" +\
411 " mastership to specific ONOS nodes using" +\
412 " 'device-role'"
413 main.step( "Assign mastership of switches to specific controllers" )
414 # Manually assign mastership to the controller we want
415 roleCall = main.TRUE
416
417 ipList = [ ]
418 deviceList = []
Jon Halla440e872016-03-31 15:15:50 -0700419 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700420 try:
421 # Assign mastership to specific controllers. This assignment was
422 # determined for a 7 node cluser, but will work with any sized
423 # cluster
424 for i in range( 1, 29 ): # switches 1 through 28
425 # set up correct variables:
426 if i == 1:
427 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700428 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700429 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700430 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700431 c = 1 % main.numCtrls
432 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700433 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700434 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700435 c = 1 % main.numCtrls
436 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700437 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700438 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700439 c = 3 % main.numCtrls
440 ip = main.nodes[ c ].ip_address # ONOS4
Jon Halla440e872016-03-31 15:15:50 -0700441 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700442 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700443 c = 2 % main.numCtrls
444 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700445 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700446 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700447 c = 2 % main.numCtrls
448 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700449 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700450 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700451 c = 5 % main.numCtrls
452 ip = main.nodes[ c ].ip_address # ONOS6
Jon Halla440e872016-03-31 15:15:50 -0700453 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700454 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700455 c = 4 % main.numCtrls
456 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700457 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700458 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700460 c = 6 % main.numCtrls
461 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700462 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700463 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700464 elif i == 28:
465 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700466 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700467 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700468 else:
469 main.log.error( "You didn't write an else statement for " +
470 "switch s" + str( i ) )
471 roleCall = main.FALSE
472 # Assign switch
473 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
474 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700475 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700476 ipList.append( ip )
477 deviceList.append( deviceId )
478 except ( AttributeError, AssertionError ):
479 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700480 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700481 utilities.assert_equals(
482 expect=main.TRUE,
483 actual=roleCall,
484 onpass="Re-assigned switch mastership to designated controller",
485 onfail="Something wrong with deviceRole calls" )
486
487 main.step( "Check mastership was correctly assigned" )
488 roleCheck = main.TRUE
489 # NOTE: This is due to the fact that device mastership change is not
490 # atomic and is actually a multi step process
491 time.sleep( 5 )
492 for i in range( len( ipList ) ):
493 ip = ipList[i]
494 deviceId = deviceList[i]
495 # Check assignment
Jon Halla440e872016-03-31 15:15:50 -0700496 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700497 if ip in master:
498 roleCheck = roleCheck and main.TRUE
499 else:
500 roleCheck = roleCheck and main.FALSE
501 main.log.error( "Error, controller " + ip + " is not" +
502 " master " + "of device " +
503 str( deviceId ) + ". Master is " +
504 repr( master ) + "." )
505 utilities.assert_equals(
506 expect=main.TRUE,
507 actual=roleCheck,
508 onpass="Switches were successfully reassigned to designated " +
509 "controller",
510 onfail="Switches were not successfully reassigned" )
511
512 def CASE3( self, main ):
513 """
514 Assign intents
515 """
516 import time
517 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700518 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700519 assert main, "main not defined"
520 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700521 assert main.CLIs, "main.CLIs not defined"
522 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700523 try:
524 labels
525 except NameError:
526 main.log.error( "labels not defined, setting to []" )
527 labels = []
528 try:
529 data
530 except NameError:
531 main.log.error( "data not defined, setting to []" )
532 data = []
533 # NOTE: we must reinstall intents until we have a persistant intent
534 # datastore!
535 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700536 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700537 "assign predetermined host-to-host intents." +\
538 " After installation, check that the intent" +\
539 " is distributed to all nodes and the state" +\
540 " is INSTALLED"
541
542 # install onos-app-fwd
543 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700544 onosCli = main.CLIs[ main.activeNodes[0] ]
545 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700546 utilities.assert_equals( expect=main.TRUE, actual=installResults,
547 onpass="Install fwd successful",
548 onfail="Install fwd failed" )
549
550 main.step( "Check app ids" )
551 appCheck = main.TRUE
552 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700553 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700554 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700555 name="appToIDCheck-" + str( i ),
556 args=[] )
557 threads.append( t )
558 t.start()
559
560 for t in threads:
561 t.join()
562 appCheck = appCheck and t.result
563 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700564 main.log.warn( onosCli.apps() )
565 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700566 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
567 onpass="App Ids seem to be correct",
568 onfail="Something is wrong with app Ids" )
569
570 main.step( "Discovering Hosts( Via pingall for now )" )
571 # FIXME: Once we have a host discovery mechanism, use that instead
572 # REACTIVE FWD test
573 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700574 passMsg = "Reactive Pingall test passed"
575 time1 = time.time()
576 pingResult = main.Mininet1.pingall()
577 time2 = time.time()
578 if not pingResult:
579 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700580 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700581 passMsg += " on the second try"
582 utilities.assert_equals(
583 expect=main.TRUE,
584 actual=pingResult,
585 onpass= passMsg,
586 onfail="Reactive Pingall failed, " +
587 "one or more ping pairs failed" )
588 main.log.info( "Time for pingall: %2f seconds" %
589 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700590 # timeout for fwd flows
591 time.sleep( 11 )
592 # uninstall onos-app-fwd
593 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700594 node = main.activeNodes[0]
595 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700596 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
597 onpass="Uninstall fwd successful",
598 onfail="Uninstall fwd failed" )
599
600 main.step( "Check app ids" )
601 threads = []
602 appCheck2 = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700603 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700604 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700605 name="appToIDCheck-" + str( i ),
606 args=[] )
607 threads.append( t )
608 t.start()
609
610 for t in threads:
611 t.join()
612 appCheck2 = appCheck2 and t.result
613 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700614 node = main.activeNodes[0]
615 main.log.warn( main.CLIs[node].apps() )
616 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700617 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
618 onpass="App Ids seem to be correct",
619 onfail="Something is wrong with app Ids" )
620
621 main.step( "Add host intents via cli" )
622 intentIds = []
Jon Hall6e709752016-02-01 13:38:46 -0800623 # TODO: move the host numbers to params
624 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700625 intentAddResult = True
626 hostResult = main.TRUE
627 for i in range( 8, 18 ):
628 main.log.info( "Adding host intent between h" + str( i ) +
629 " and h" + str( i + 10 ) )
630 host1 = "00:00:00:00:00:" + \
631 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
632 host2 = "00:00:00:00:00:" + \
633 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
634 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700635 host1Dict = onosCli.getHost( host1 )
636 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700637 host1Id = None
638 host2Id = None
639 if host1Dict and host2Dict:
640 host1Id = host1Dict.get( 'id', None )
641 host2Id = host2Dict.get( 'id', None )
642 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700643 nodeNum = ( i % len( main.activeNodes ) )
644 node = main.activeNodes[nodeNum]
645 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700646 if tmpId:
647 main.log.info( "Added intent with id: " + tmpId )
648 intentIds.append( tmpId )
649 else:
650 main.log.error( "addHostIntent returned: " +
651 repr( tmpId ) )
652 else:
653 main.log.error( "Error, getHost() failed for h" + str( i ) +
654 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700655 node = main.activeNodes[0]
656 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700657 main.log.warn( "Hosts output: " )
658 try:
659 main.log.warn( json.dumps( json.loads( hosts ),
660 sort_keys=True,
661 indent=4,
662 separators=( ',', ': ' ) ) )
663 except ( ValueError, TypeError ):
664 main.log.warn( repr( hosts ) )
665 hostResult = main.FALSE
666 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
667 onpass="Found a host id for each host",
668 onfail="Error looking up host ids" )
669
670 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700671 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700672 main.log.info( "Submitted intents: " + str( intentIds ) )
673 main.log.info( "Intents in ONOS: " + str( onosIds ) )
674 for intent in intentIds:
675 if intent in onosIds:
676 pass # intent submitted is in onos
677 else:
678 intentAddResult = False
679 if intentAddResult:
680 intentStop = time.time()
681 else:
682 intentStop = None
683 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700684 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700685 intentStates = []
686 installedCheck = True
687 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
688 count = 0
689 try:
690 for intent in json.loads( intents ):
691 state = intent.get( 'state', None )
692 if "INSTALLED" not in state:
693 installedCheck = False
694 intentId = intent.get( 'id', None )
695 intentStates.append( ( intentId, state ) )
696 except ( ValueError, TypeError ):
697 main.log.exception( "Error parsing intents" )
698 # add submitted intents not in the store
699 tmplist = [ i for i, s in intentStates ]
700 missingIntents = False
701 for i in intentIds:
702 if i not in tmplist:
703 intentStates.append( ( i, " - " ) )
704 missingIntents = True
705 intentStates.sort()
706 for i, s in intentStates:
707 count += 1
708 main.log.info( "%-6s%-15s%-15s" %
709 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700710 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700711 try:
712 missing = False
713 if leaders:
714 parsedLeaders = json.loads( leaders )
715 main.log.warn( json.dumps( parsedLeaders,
716 sort_keys=True,
717 indent=4,
718 separators=( ',', ': ' ) ) )
719 # check for all intent partitions
720 topics = []
721 for i in range( 14 ):
722 topics.append( "intent-partition-" + str( i ) )
723 main.log.debug( topics )
724 ONOStopics = [ j['topic'] for j in parsedLeaders ]
725 for topic in topics:
726 if topic not in ONOStopics:
727 main.log.error( "Error: " + topic +
728 " not in leaders" )
729 missing = True
730 else:
731 main.log.error( "leaders() returned None" )
732 except ( ValueError, TypeError ):
733 main.log.exception( "Error parsing leaders" )
734 main.log.error( repr( leaders ) )
735 # Check all nodes
736 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700737 for i in main.activeNodes:
738 response = main.CLIs[i].leaders( jsonFormat=False)
739 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700740 str( response ) )
741
Jon Halla440e872016-03-31 15:15:50 -0700742 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700743 try:
744 if partitions :
745 parsedPartitions = json.loads( partitions )
746 main.log.warn( json.dumps( parsedPartitions,
747 sort_keys=True,
748 indent=4,
749 separators=( ',', ': ' ) ) )
750 # TODO check for a leader in all paritions
751 # TODO check for consistency among nodes
752 else:
753 main.log.error( "partitions() returned None" )
754 except ( ValueError, TypeError ):
755 main.log.exception( "Error parsing partitions" )
756 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700757 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700758 try:
759 if pendingMap :
760 parsedPending = json.loads( pendingMap )
761 main.log.warn( json.dumps( parsedPending,
762 sort_keys=True,
763 indent=4,
764 separators=( ',', ': ' ) ) )
765 # TODO check something here?
766 else:
767 main.log.error( "pendingMap() returned None" )
768 except ( ValueError, TypeError ):
769 main.log.exception( "Error parsing pending map" )
770 main.log.error( repr( pendingMap ) )
771
772 intentAddResult = bool( intentAddResult and not missingIntents and
773 installedCheck )
774 if not intentAddResult:
775 main.log.error( "Error in pushing host intents to ONOS" )
776
777 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700778 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700779 correct = True
780 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700781 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700782 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700783 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700784 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700785 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700786 str( sorted( onosIds ) ) )
787 if sorted( ids ) != sorted( intentIds ):
788 main.log.warn( "Set of intent IDs doesn't match" )
789 correct = False
790 break
791 else:
Jon Halla440e872016-03-31 15:15:50 -0700792 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700793 for intent in intents:
794 if intent[ 'state' ] != "INSTALLED":
795 main.log.warn( "Intent " + intent[ 'id' ] +
796 " is " + intent[ 'state' ] )
797 correct = False
798 break
799 if correct:
800 break
801 else:
802 time.sleep(1)
803 if not intentStop:
804 intentStop = time.time()
805 global gossipTime
806 gossipTime = intentStop - intentStart
807 main.log.info( "It took about " + str( gossipTime ) +
808 " seconds for all intents to appear in each node" )
809 append = False
810 title = "Gossip Intents"
811 count = 1
812 while append is False:
813 curTitle = title + str( count )
814 if curTitle not in labels:
815 labels.append( curTitle )
816 data.append( str( gossipTime ) )
817 append = True
818 else:
819 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700820 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700821 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700822 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700823 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700824 onpass="ECM anti-entropy for intents worked within " +
825 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700826 onfail="Intent ECM anti-entropy took too long. " +
827 "Expected time:{}, Actual time:{}".format( maxGossipTime,
828 gossipTime ) )
829 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700830 intentAddResult = True
831
832 if not intentAddResult or "key" in pendingMap:
833 import time
834 installedCheck = True
835 main.log.info( "Sleeping 60 seconds to see if intents are found" )
836 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700837 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700838 main.log.info( "Submitted intents: " + str( intentIds ) )
839 main.log.info( "Intents in ONOS: " + str( onosIds ) )
840 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700841 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700842 intentStates = []
843 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
844 count = 0
845 try:
846 for intent in json.loads( intents ):
847 # Iter through intents of a node
848 state = intent.get( 'state', None )
849 if "INSTALLED" not in state:
850 installedCheck = False
851 intentId = intent.get( 'id', None )
852 intentStates.append( ( intentId, state ) )
853 except ( ValueError, TypeError ):
854 main.log.exception( "Error parsing intents" )
855 # add submitted intents not in the store
856 tmplist = [ i for i, s in intentStates ]
857 for i in intentIds:
858 if i not in tmplist:
859 intentStates.append( ( i, " - " ) )
860 intentStates.sort()
861 for i, s in intentStates:
862 count += 1
863 main.log.info( "%-6s%-15s%-15s" %
864 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700865 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700866 try:
867 missing = False
868 if leaders:
869 parsedLeaders = json.loads( leaders )
870 main.log.warn( json.dumps( parsedLeaders,
871 sort_keys=True,
872 indent=4,
873 separators=( ',', ': ' ) ) )
874 # check for all intent partitions
875 # check for election
876 topics = []
877 for i in range( 14 ):
878 topics.append( "intent-partition-" + str( i ) )
879 # FIXME: this should only be after we start the app
880 topics.append( "org.onosproject.election" )
881 main.log.debug( topics )
882 ONOStopics = [ j['topic'] for j in parsedLeaders ]
883 for topic in topics:
884 if topic not in ONOStopics:
885 main.log.error( "Error: " + topic +
886 " not in leaders" )
887 missing = True
888 else:
889 main.log.error( "leaders() returned None" )
890 except ( ValueError, TypeError ):
891 main.log.exception( "Error parsing leaders" )
892 main.log.error( repr( leaders ) )
893 # Check all nodes
894 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700895 for i in main.activeNodes:
896 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700897 response = node.leaders( jsonFormat=False)
898 main.log.warn( str( node.name ) + " leaders output: \n" +
899 str( response ) )
900
Jon Halla440e872016-03-31 15:15:50 -0700901 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700902 try:
903 if partitions :
904 parsedPartitions = json.loads( partitions )
905 main.log.warn( json.dumps( parsedPartitions,
906 sort_keys=True,
907 indent=4,
908 separators=( ',', ': ' ) ) )
909 # TODO check for a leader in all paritions
910 # TODO check for consistency among nodes
911 else:
912 main.log.error( "partitions() returned None" )
913 except ( ValueError, TypeError ):
914 main.log.exception( "Error parsing partitions" )
915 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700916 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700917 try:
918 if pendingMap :
919 parsedPending = json.loads( pendingMap )
920 main.log.warn( json.dumps( parsedPending,
921 sort_keys=True,
922 indent=4,
923 separators=( ',', ': ' ) ) )
924 # TODO check something here?
925 else:
926 main.log.error( "pendingMap() returned None" )
927 except ( ValueError, TypeError ):
928 main.log.exception( "Error parsing pending map" )
929 main.log.error( repr( pendingMap ) )
930
931 def CASE4( self, main ):
932 """
933 Ping across added host intents
934 """
935 import json
936 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700937 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700938 assert main, "main not defined"
939 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700940 assert main.CLIs, "main.CLIs not defined"
941 assert main.nodes, "main.nodes not defined"
Jon Hall6e709752016-02-01 13:38:46 -0800942 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700943 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700944 "functionality and check the state of " +\
945 "the intent"
Jon Hall5cf14d52015-07-16 12:15:19 -0700946
Jon Hall41d39f12016-04-11 22:54:35 -0700947 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700948 main.step( "Check Intent state" )
949 installedCheck = False
950 loopCount = 0
951 while not installedCheck and loopCount < 40:
952 installedCheck = True
953 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700954 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700955 intentStates = []
956 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700957 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700958 # Iter through intents of a node
959 try:
960 for intent in json.loads( intents ):
961 state = intent.get( 'state', None )
962 if "INSTALLED" not in state:
963 installedCheck = False
964 intentId = intent.get( 'id', None )
965 intentStates.append( ( intentId, state ) )
966 except ( ValueError, TypeError ):
967 main.log.exception( "Error parsing intents." )
968 # Print states
969 intentStates.sort()
970 for i, s in intentStates:
971 count += 1
972 main.log.info( "%-6s%-15s%-15s" %
973 ( str( count ), str( i ), str( s ) ) )
974 if not installedCheck:
975 time.sleep( 1 )
976 loopCount += 1
977 utilities.assert_equals( expect=True, actual=installedCheck,
978 onpass="Intents are all INSTALLED",
979 onfail="Intents are not all in " +
980 "INSTALLED state" )
981
Jon Hall9d2dcad2016-04-08 10:15:20 -0700982 main.step( "Ping across added host intents" )
Jon Hall9d2dcad2016-04-08 10:15:20 -0700983 PingResult = main.TRUE
984 for i in range( 8, 18 ):
985 ping = main.Mininet1.pingHost( src="h" + str( i ),
986 target="h" + str( i + 10 ) )
987 PingResult = PingResult and ping
988 if ping == main.FALSE:
989 main.log.warn( "Ping failed between h" + str( i ) +
990 " and h" + str( i + 10 ) )
991 elif ping == main.TRUE:
992 main.log.info( "Ping test passed!" )
993 # Don't set PingResult or you'd override failures
994 if PingResult == main.FALSE:
995 main.log.error(
996 "Intents have not been installed correctly, pings failed." )
997 # TODO: pretty print
998 main.log.warn( "ONOS1 intents: " )
999 try:
1000 tmpIntents = onosCli.intents()
1001 main.log.warn( json.dumps( json.loads( tmpIntents ),
1002 sort_keys=True,
1003 indent=4,
1004 separators=( ',', ': ' ) ) )
1005 except ( ValueError, TypeError ):
1006 main.log.warn( repr( tmpIntents ) )
1007 utilities.assert_equals(
1008 expect=main.TRUE,
1009 actual=PingResult,
1010 onpass="Intents have been installed correctly and pings work",
1011 onfail="Intents have not been installed correctly, pings failed." )
1012
Jon Hall5cf14d52015-07-16 12:15:19 -07001013 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -07001014 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001015 topicCheck = main.TRUE
1016 try:
1017 if leaders:
1018 parsedLeaders = json.loads( leaders )
1019 main.log.warn( json.dumps( parsedLeaders,
1020 sort_keys=True,
1021 indent=4,
1022 separators=( ',', ': ' ) ) )
1023 # check for all intent partitions
1024 # check for election
1025 # TODO: Look at Devices as topics now that it uses this system
1026 topics = []
1027 for i in range( 14 ):
1028 topics.append( "intent-partition-" + str( i ) )
1029 # FIXME: this should only be after we start the app
1030 # FIXME: topics.append( "org.onosproject.election" )
1031 # Print leaders output
1032 main.log.debug( topics )
1033 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1034 for topic in topics:
1035 if topic not in ONOStopics:
1036 main.log.error( "Error: " + topic +
1037 " not in leaders" )
1038 topicCheck = main.FALSE
1039 else:
1040 main.log.error( "leaders() returned None" )
1041 topicCheck = main.FALSE
1042 except ( ValueError, TypeError ):
1043 topicCheck = main.FALSE
1044 main.log.exception( "Error parsing leaders" )
1045 main.log.error( repr( leaders ) )
1046 # TODO: Check for a leader of these topics
1047 # Check all nodes
1048 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001049 for i in main.activeNodes:
1050 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001051 response = node.leaders( jsonFormat=False)
1052 main.log.warn( str( node.name ) + " leaders output: \n" +
1053 str( response ) )
1054
1055 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1056 onpass="intent Partitions is in leaders",
1057 onfail="Some topics were lost " )
1058 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001059 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001060 try:
1061 if partitions :
1062 parsedPartitions = json.loads( partitions )
1063 main.log.warn( json.dumps( parsedPartitions,
1064 sort_keys=True,
1065 indent=4,
1066 separators=( ',', ': ' ) ) )
1067 # TODO check for a leader in all paritions
1068 # TODO check for consistency among nodes
1069 else:
1070 main.log.error( "partitions() returned None" )
1071 except ( ValueError, TypeError ):
1072 main.log.exception( "Error parsing partitions" )
1073 main.log.error( repr( partitions ) )
1074 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001075 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001076 try:
1077 if pendingMap :
1078 parsedPending = json.loads( pendingMap )
1079 main.log.warn( json.dumps( parsedPending,
1080 sort_keys=True,
1081 indent=4,
1082 separators=( ',', ': ' ) ) )
1083 # TODO check something here?
1084 else:
1085 main.log.error( "pendingMap() returned None" )
1086 except ( ValueError, TypeError ):
1087 main.log.exception( "Error parsing pending map" )
1088 main.log.error( repr( pendingMap ) )
1089
1090 if not installedCheck:
1091 main.log.info( "Waiting 60 seconds to see if the state of " +
1092 "intents change" )
1093 time.sleep( 60 )
1094 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001095 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001096 intentStates = []
1097 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1098 count = 0
1099 # Iter through intents of a node
1100 try:
1101 for intent in json.loads( intents ):
1102 state = intent.get( 'state', None )
1103 if "INSTALLED" not in state:
1104 installedCheck = False
1105 intentId = intent.get( 'id', None )
1106 intentStates.append( ( intentId, state ) )
1107 except ( ValueError, TypeError ):
1108 main.log.exception( "Error parsing intents." )
1109 intentStates.sort()
1110 for i, s in intentStates:
1111 count += 1
1112 main.log.info( "%-6s%-15s%-15s" %
1113 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001114 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001115 try:
1116 missing = False
1117 if leaders:
1118 parsedLeaders = json.loads( leaders )
1119 main.log.warn( json.dumps( parsedLeaders,
1120 sort_keys=True,
1121 indent=4,
1122 separators=( ',', ': ' ) ) )
1123 # check for all intent partitions
1124 # check for election
1125 topics = []
1126 for i in range( 14 ):
1127 topics.append( "intent-partition-" + str( i ) )
1128 # FIXME: this should only be after we start the app
1129 topics.append( "org.onosproject.election" )
1130 main.log.debug( topics )
1131 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1132 for topic in topics:
1133 if topic not in ONOStopics:
1134 main.log.error( "Error: " + topic +
1135 " not in leaders" )
1136 missing = True
1137 else:
1138 main.log.error( "leaders() returned None" )
1139 except ( ValueError, TypeError ):
1140 main.log.exception( "Error parsing leaders" )
1141 main.log.error( repr( leaders ) )
1142 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001143 for i in main.activeNodes:
1144 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001145 response = node.leaders( jsonFormat=False)
1146 main.log.warn( str( node.name ) + " leaders output: \n" +
1147 str( response ) )
1148
Jon Halla440e872016-03-31 15:15:50 -07001149 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001150 try:
1151 if partitions :
1152 parsedPartitions = json.loads( partitions )
1153 main.log.warn( json.dumps( parsedPartitions,
1154 sort_keys=True,
1155 indent=4,
1156 separators=( ',', ': ' ) ) )
1157 # TODO check for a leader in all paritions
1158 # TODO check for consistency among nodes
1159 else:
1160 main.log.error( "partitions() returned None" )
1161 except ( ValueError, TypeError ):
1162 main.log.exception( "Error parsing partitions" )
1163 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001164 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001165 try:
1166 if pendingMap :
1167 parsedPending = json.loads( pendingMap )
1168 main.log.warn( json.dumps( parsedPending,
1169 sort_keys=True,
1170 indent=4,
1171 separators=( ',', ': ' ) ) )
1172 # TODO check something here?
1173 else:
1174 main.log.error( "pendingMap() returned None" )
1175 except ( ValueError, TypeError ):
1176 main.log.exception( "Error parsing pending map" )
1177 main.log.error( repr( pendingMap ) )
1178 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001179 node = main.activeNodes[0]
1180 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001181 main.step( "Wait a minute then ping again" )
1182 # the wait is above
1183 PingResult = main.TRUE
1184 for i in range( 8, 18 ):
1185 ping = main.Mininet1.pingHost( src="h" + str( i ),
1186 target="h" + str( i + 10 ) )
1187 PingResult = PingResult and ping
1188 if ping == main.FALSE:
1189 main.log.warn( "Ping failed between h" + str( i ) +
1190 " and h" + str( i + 10 ) )
1191 elif ping == main.TRUE:
1192 main.log.info( "Ping test passed!" )
1193 # Don't set PingResult or you'd override failures
1194 if PingResult == main.FALSE:
1195 main.log.error(
1196 "Intents have not been installed correctly, pings failed." )
1197 # TODO: pretty print
1198 main.log.warn( "ONOS1 intents: " )
1199 try:
Jon Halla440e872016-03-31 15:15:50 -07001200 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001201 main.log.warn( json.dumps( json.loads( tmpIntents ),
1202 sort_keys=True,
1203 indent=4,
1204 separators=( ',', ': ' ) ) )
1205 except ( ValueError, TypeError ):
1206 main.log.warn( repr( tmpIntents ) )
1207 utilities.assert_equals(
1208 expect=main.TRUE,
1209 actual=PingResult,
1210 onpass="Intents have been installed correctly and pings work",
1211 onfail="Intents have not been installed correctly, pings failed." )
1212
1213 def CASE5( self, main ):
1214 """
1215 Reading state of ONOS
1216 """
1217 import json
1218 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001219 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001220 assert main, "main not defined"
1221 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001222 assert main.CLIs, "main.CLIs not defined"
1223 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001224
1225 main.case( "Setting up and gathering data for current state" )
1226 # The general idea for this test case is to pull the state of
1227 # ( intents,flows, topology,... ) from each ONOS node
1228 # We can then compare them with each other and also with past states
1229
1230 main.step( "Check that each switch has a master" )
1231 global mastershipState
1232 mastershipState = '[]'
1233
1234 # Assert that each device has a master
1235 rolesNotNull = main.TRUE
1236 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001237 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001238 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001239 name="rolesNotNull-" + str( i ),
1240 args=[] )
1241 threads.append( t )
1242 t.start()
1243
1244 for t in threads:
1245 t.join()
1246 rolesNotNull = rolesNotNull and t.result
1247 utilities.assert_equals(
1248 expect=main.TRUE,
1249 actual=rolesNotNull,
1250 onpass="Each device has a master",
1251 onfail="Some devices don't have a master assigned" )
1252
1253 main.step( "Get the Mastership of each switch from each controller" )
1254 ONOSMastership = []
1255 mastershipCheck = main.FALSE
1256 consistentMastership = True
1257 rolesResults = True
1258 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001259 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001260 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001261 name="roles-" + str( i ),
1262 args=[] )
1263 threads.append( t )
1264 t.start()
1265
1266 for t in threads:
1267 t.join()
1268 ONOSMastership.append( t.result )
1269
Jon Halla440e872016-03-31 15:15:50 -07001270 for i in range( len( ONOSMastership ) ):
1271 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001272 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001273 main.log.error( "Error in getting ONOS" + node + " roles" )
1274 main.log.warn( "ONOS" + node + " mastership response: " +
1275 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001276 rolesResults = False
1277 utilities.assert_equals(
1278 expect=True,
1279 actual=rolesResults,
1280 onpass="No error in reading roles output",
1281 onfail="Error in reading roles from ONOS" )
1282
1283 main.step( "Check for consistency in roles from each controller" )
1284 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1285 main.log.info(
1286 "Switch roles are consistent across all ONOS nodes" )
1287 else:
1288 consistentMastership = False
1289 utilities.assert_equals(
1290 expect=True,
1291 actual=consistentMastership,
1292 onpass="Switch roles are consistent across all ONOS nodes",
1293 onfail="ONOS nodes have different views of switch roles" )
1294
1295 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001296 for i in range( len( main.activeNodes ) ):
1297 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001298 try:
1299 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001300 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001301 json.dumps(
1302 json.loads( ONOSMastership[ i ] ),
1303 sort_keys=True,
1304 indent=4,
1305 separators=( ',', ': ' ) ) )
1306 except ( ValueError, TypeError ):
1307 main.log.warn( repr( ONOSMastership[ i ] ) )
1308 elif rolesResults and consistentMastership:
1309 mastershipCheck = main.TRUE
1310 mastershipState = ONOSMastership[ 0 ]
1311
1312 main.step( "Get the intents from each controller" )
1313 global intentState
1314 intentState = []
1315 ONOSIntents = []
1316 intentCheck = main.FALSE
1317 consistentIntents = True
1318 intentsResults = True
1319 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001320 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001321 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001322 name="intents-" + str( i ),
1323 args=[],
1324 kwargs={ 'jsonFormat': True } )
1325 threads.append( t )
1326 t.start()
1327
1328 for t in threads:
1329 t.join()
1330 ONOSIntents.append( t.result )
1331
Jon Halla440e872016-03-31 15:15:50 -07001332 for i in range( len( ONOSIntents ) ):
1333 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001334 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall6e709752016-02-01 13:38:46 -08001335 main.log.error( "Error in getting ONOS" + node + " intents" )
1336 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001337 repr( ONOSIntents[ i ] ) )
1338 intentsResults = False
1339 utilities.assert_equals(
1340 expect=True,
1341 actual=intentsResults,
1342 onpass="No error in reading intents output",
1343 onfail="Error in reading intents from ONOS" )
1344
1345 main.step( "Check for consistency in Intents from each controller" )
1346 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1347 main.log.info( "Intents are consistent across all ONOS " +
1348 "nodes" )
1349 else:
1350 consistentIntents = False
1351 main.log.error( "Intents not consistent" )
1352 utilities.assert_equals(
1353 expect=True,
1354 actual=consistentIntents,
1355 onpass="Intents are consistent across all ONOS nodes",
1356 onfail="ONOS nodes have different views of intents" )
1357
1358 if intentsResults:
1359 # Try to make it easy to figure out what is happening
1360 #
1361 # Intent ONOS1 ONOS2 ...
1362 # 0x01 INSTALLED INSTALLING
1363 # ... ... ...
1364 # ... ... ...
1365 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001366 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001367 title += " " * 10 + "ONOS" + str( n + 1 )
1368 main.log.warn( title )
1369 # get all intent keys in the cluster
1370 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001371 try:
1372 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001373 for nodeStr in ONOSIntents:
1374 node = json.loads( nodeStr )
1375 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001376 keys.append( intent.get( 'id' ) )
1377 keys = set( keys )
1378 # For each intent key, print the state on each node
1379 for key in keys:
1380 row = "%-13s" % key
1381 for nodeStr in ONOSIntents:
1382 node = json.loads( nodeStr )
1383 for intent in node:
1384 if intent.get( 'id', "Error" ) == key:
1385 row += "%-15s" % intent.get( 'state' )
1386 main.log.warn( row )
1387 # End of intent state table
1388 except ValueError as e:
1389 main.log.exception( e )
1390 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001391
1392 if intentsResults and not consistentIntents:
1393 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001394 n = str( main.activeNodes[-1] + 1 )
1395 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001396 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1397 sort_keys=True,
1398 indent=4,
1399 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001400 for i in range( len( ONOSIntents ) ):
1401 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001402 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001403 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001404 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1405 sort_keys=True,
1406 indent=4,
1407 separators=( ',', ': ' ) ) )
1408 else:
Jon Halla440e872016-03-31 15:15:50 -07001409 main.log.debug( "ONOS" + node + " intents match ONOS" +
1410 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001411 elif intentsResults and consistentIntents:
1412 intentCheck = main.TRUE
1413 intentState = ONOSIntents[ 0 ]
1414
1415 main.step( "Get the flows from each controller" )
1416 global flowState
1417 flowState = []
1418 ONOSFlows = []
1419 ONOSFlowsJson = []
1420 flowCheck = main.FALSE
1421 consistentFlows = True
1422 flowsResults = True
1423 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001424 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001425 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001426 name="flows-" + str( i ),
1427 args=[],
1428 kwargs={ 'jsonFormat': True } )
1429 threads.append( t )
1430 t.start()
1431
1432 # NOTE: Flows command can take some time to run
1433 time.sleep(30)
1434 for t in threads:
1435 t.join()
1436 result = t.result
1437 ONOSFlows.append( result )
1438
Jon Halla440e872016-03-31 15:15:50 -07001439 for i in range( len( ONOSFlows ) ):
1440 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001441 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1442 main.log.error( "Error in getting ONOS" + num + " flows" )
1443 main.log.warn( "ONOS" + num + " flows response: " +
1444 repr( ONOSFlows[ i ] ) )
1445 flowsResults = False
1446 ONOSFlowsJson.append( None )
1447 else:
1448 try:
1449 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1450 except ( ValueError, TypeError ):
1451 # FIXME: change this to log.error?
1452 main.log.exception( "Error in parsing ONOS" + num +
1453 " response as json." )
1454 main.log.error( repr( ONOSFlows[ i ] ) )
1455 ONOSFlowsJson.append( None )
1456 flowsResults = False
1457 utilities.assert_equals(
1458 expect=True,
1459 actual=flowsResults,
1460 onpass="No error in reading flows output",
1461 onfail="Error in reading flows from ONOS" )
1462
1463 main.step( "Check for consistency in Flows from each controller" )
1464 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1465 if all( tmp ):
1466 main.log.info( "Flow count is consistent across all ONOS nodes" )
1467 else:
1468 consistentFlows = False
1469 utilities.assert_equals(
1470 expect=True,
1471 actual=consistentFlows,
1472 onpass="The flow count is consistent across all ONOS nodes",
1473 onfail="ONOS nodes have different flow counts" )
1474
1475 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001476 for i in range( len( ONOSFlows ) ):
1477 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001478 try:
1479 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001480 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001481 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1482 indent=4, separators=( ',', ': ' ) ) )
1483 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001484 main.log.warn( "ONOS" + node + " flows: " +
1485 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001486 elif flowsResults and consistentFlows:
1487 flowCheck = main.TRUE
1488 flowState = ONOSFlows[ 0 ]
1489
1490 main.step( "Get the OF Table entries" )
1491 global flows
1492 flows = []
1493 for i in range( 1, 29 ):
Jon Halla440e872016-03-31 15:15:50 -07001494 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001495 if flowCheck == main.FALSE:
1496 for table in flows:
1497 main.log.warn( table )
1498 # TODO: Compare switch flow tables with ONOS flow tables
1499
1500 main.step( "Start continuous pings" )
1501 main.Mininet2.pingLong(
1502 src=main.params[ 'PING' ][ 'source1' ],
1503 target=main.params[ 'PING' ][ 'target1' ],
1504 pingTime=500 )
1505 main.Mininet2.pingLong(
1506 src=main.params[ 'PING' ][ 'source2' ],
1507 target=main.params[ 'PING' ][ 'target2' ],
1508 pingTime=500 )
1509 main.Mininet2.pingLong(
1510 src=main.params[ 'PING' ][ 'source3' ],
1511 target=main.params[ 'PING' ][ 'target3' ],
1512 pingTime=500 )
1513 main.Mininet2.pingLong(
1514 src=main.params[ 'PING' ][ 'source4' ],
1515 target=main.params[ 'PING' ][ 'target4' ],
1516 pingTime=500 )
1517 main.Mininet2.pingLong(
1518 src=main.params[ 'PING' ][ 'source5' ],
1519 target=main.params[ 'PING' ][ 'target5' ],
1520 pingTime=500 )
1521 main.Mininet2.pingLong(
1522 src=main.params[ 'PING' ][ 'source6' ],
1523 target=main.params[ 'PING' ][ 'target6' ],
1524 pingTime=500 )
1525 main.Mininet2.pingLong(
1526 src=main.params[ 'PING' ][ 'source7' ],
1527 target=main.params[ 'PING' ][ 'target7' ],
1528 pingTime=500 )
1529 main.Mininet2.pingLong(
1530 src=main.params[ 'PING' ][ 'source8' ],
1531 target=main.params[ 'PING' ][ 'target8' ],
1532 pingTime=500 )
1533 main.Mininet2.pingLong(
1534 src=main.params[ 'PING' ][ 'source9' ],
1535 target=main.params[ 'PING' ][ 'target9' ],
1536 pingTime=500 )
1537 main.Mininet2.pingLong(
1538 src=main.params[ 'PING' ][ 'source10' ],
1539 target=main.params[ 'PING' ][ 'target10' ],
1540 pingTime=500 )
1541
1542 main.step( "Collecting topology information from ONOS" )
1543 devices = []
1544 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001545 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001546 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001547 name="devices-" + str( i ),
1548 args=[ ] )
1549 threads.append( t )
1550 t.start()
1551
1552 for t in threads:
1553 t.join()
1554 devices.append( t.result )
1555 hosts = []
1556 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001557 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001558 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001559 name="hosts-" + str( i ),
1560 args=[ ] )
1561 threads.append( t )
1562 t.start()
1563
1564 for t in threads:
1565 t.join()
1566 try:
1567 hosts.append( json.loads( t.result ) )
1568 except ( ValueError, TypeError ):
1569 # FIXME: better handling of this, print which node
1570 # Maybe use thread name?
1571 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001572 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001573 hosts.append( None )
1574
1575 ports = []
1576 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001577 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001578 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001579 name="ports-" + str( i ),
1580 args=[ ] )
1581 threads.append( t )
1582 t.start()
1583
1584 for t in threads:
1585 t.join()
1586 ports.append( t.result )
1587 links = []
1588 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001589 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001590 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001591 name="links-" + str( i ),
1592 args=[ ] )
1593 threads.append( t )
1594 t.start()
1595
1596 for t in threads:
1597 t.join()
1598 links.append( t.result )
1599 clusters = []
1600 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001601 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001602 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001603 name="clusters-" + str( i ),
1604 args=[ ] )
1605 threads.append( t )
1606 t.start()
1607
1608 for t in threads:
1609 t.join()
1610 clusters.append( t.result )
1611 # Compare json objects for hosts and dataplane clusters
1612
1613 # hosts
1614 main.step( "Host view is consistent across ONOS nodes" )
1615 consistentHostsResult = main.TRUE
1616 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001617 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001618 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001619 if hosts[ controller ] == hosts[ 0 ]:
1620 continue
1621 else: # hosts not consistent
1622 main.log.error( "hosts from ONOS" +
1623 controllerStr +
1624 " is inconsistent with ONOS1" )
1625 main.log.warn( repr( hosts[ controller ] ) )
1626 consistentHostsResult = main.FALSE
1627
1628 else:
1629 main.log.error( "Error in getting ONOS hosts from ONOS" +
1630 controllerStr )
1631 consistentHostsResult = main.FALSE
1632 main.log.warn( "ONOS" + controllerStr +
1633 " hosts response: " +
1634 repr( hosts[ controller ] ) )
1635 utilities.assert_equals(
1636 expect=main.TRUE,
1637 actual=consistentHostsResult,
1638 onpass="Hosts view is consistent across all ONOS nodes",
1639 onfail="ONOS nodes have different views of hosts" )
1640
1641 main.step( "Each host has an IP address" )
1642 ipResult = main.TRUE
1643 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001644 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001645 if hosts[ controller ]:
1646 for host in hosts[ controller ]:
1647 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001648 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001649 controllerStr + ": " + str( host ) )
1650 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001651 utilities.assert_equals(
1652 expect=main.TRUE,
1653 actual=ipResult,
1654 onpass="The ips of the hosts aren't empty",
1655 onfail="The ip of at least one host is missing" )
1656
1657 # Strongly connected clusters of devices
1658 main.step( "Cluster view is consistent across ONOS nodes" )
1659 consistentClustersResult = main.TRUE
1660 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001661 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001662 if "Error" not in clusters[ controller ]:
1663 if clusters[ controller ] == clusters[ 0 ]:
1664 continue
1665 else: # clusters not consistent
1666 main.log.error( "clusters from ONOS" + controllerStr +
1667 " is inconsistent with ONOS1" )
1668 consistentClustersResult = main.FALSE
1669
1670 else:
1671 main.log.error( "Error in getting dataplane clusters " +
1672 "from ONOS" + controllerStr )
1673 consistentClustersResult = main.FALSE
1674 main.log.warn( "ONOS" + controllerStr +
1675 " clusters response: " +
1676 repr( clusters[ controller ] ) )
1677 utilities.assert_equals(
1678 expect=main.TRUE,
1679 actual=consistentClustersResult,
1680 onpass="Clusters view is consistent across all ONOS nodes",
1681 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001682 if consistentClustersResult != main.TRUE:
1683 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001684 # there should always only be one cluster
1685 main.step( "Cluster view correct across ONOS nodes" )
1686 try:
1687 numClusters = len( json.loads( clusters[ 0 ] ) )
1688 except ( ValueError, TypeError ):
1689 main.log.exception( "Error parsing clusters[0]: " +
1690 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001691 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001692 clusterResults = main.FALSE
1693 if numClusters == 1:
1694 clusterResults = main.TRUE
1695 utilities.assert_equals(
1696 expect=1,
1697 actual=numClusters,
1698 onpass="ONOS shows 1 SCC",
1699 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1700
1701 main.step( "Comparing ONOS topology to MN" )
1702 devicesResults = main.TRUE
1703 linksResults = main.TRUE
1704 hostsResults = main.TRUE
1705 mnSwitches = main.Mininet1.getSwitches()
1706 mnLinks = main.Mininet1.getLinks()
1707 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001708 for controller in main.activeNodes:
1709 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001710 if devices[ controller ] and ports[ controller ] and\
1711 "Error" not in devices[ controller ] and\
1712 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001713 currentDevicesResult = main.Mininet1.compareSwitches(
1714 mnSwitches,
1715 json.loads( devices[ controller ] ),
1716 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001717 else:
1718 currentDevicesResult = main.FALSE
1719 utilities.assert_equals( expect=main.TRUE,
1720 actual=currentDevicesResult,
1721 onpass="ONOS" + controllerStr +
1722 " Switches view is correct",
1723 onfail="ONOS" + controllerStr +
1724 " Switches view is incorrect" )
1725 if links[ controller ] and "Error" not in links[ controller ]:
1726 currentLinksResult = main.Mininet1.compareLinks(
1727 mnSwitches, mnLinks,
1728 json.loads( links[ controller ] ) )
1729 else:
1730 currentLinksResult = main.FALSE
1731 utilities.assert_equals( expect=main.TRUE,
1732 actual=currentLinksResult,
1733 onpass="ONOS" + controllerStr +
1734 " links view is correct",
1735 onfail="ONOS" + controllerStr +
1736 " links view is incorrect" )
1737
Jon Hall657cdf62015-12-17 14:40:51 -08001738 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001739 currentHostsResult = main.Mininet1.compareHosts(
1740 mnHosts,
1741 hosts[ controller ] )
1742 else:
1743 currentHostsResult = main.FALSE
1744 utilities.assert_equals( expect=main.TRUE,
1745 actual=currentHostsResult,
1746 onpass="ONOS" + controllerStr +
1747 " hosts exist in Mininet",
1748 onfail="ONOS" + controllerStr +
1749 " hosts don't match Mininet" )
1750
1751 devicesResults = devicesResults and currentDevicesResult
1752 linksResults = linksResults and currentLinksResult
1753 hostsResults = hostsResults and currentHostsResult
1754
1755 main.step( "Device information is correct" )
1756 utilities.assert_equals(
1757 expect=main.TRUE,
1758 actual=devicesResults,
1759 onpass="Device information is correct",
1760 onfail="Device information is incorrect" )
1761
1762 main.step( "Links are correct" )
1763 utilities.assert_equals(
1764 expect=main.TRUE,
1765 actual=linksResults,
1766 onpass="Link are correct",
1767 onfail="Links are incorrect" )
1768
1769 main.step( "Hosts are correct" )
1770 utilities.assert_equals(
1771 expect=main.TRUE,
1772 actual=hostsResults,
1773 onpass="Hosts are correct",
1774 onfail="Hosts are incorrect" )
1775
1776 def CASE6( self, main ):
1777 """
1778 The Failure case.
1779 """
1780 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001781 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001782 assert main, "main not defined"
1783 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001784 assert main.CLIs, "main.CLIs not defined"
1785 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001786 try:
1787 labels
1788 except NameError:
1789 main.log.error( "labels not defined, setting to []" )
1790 global labels
1791 labels = []
1792 try:
1793 data
1794 except NameError:
1795 main.log.error( "data not defined, setting to []" )
1796 global data
1797 data = []
1798 # Reset non-persistent variables
1799 try:
1800 iCounterValue = 0
1801 except NameError:
1802 main.log.error( "iCounterValue not defined, setting to 0" )
1803 iCounterValue = 0
1804
1805 main.case( "Restart entire ONOS cluster" )
1806
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001807 main.step( "Checking ONOS Logs for errors" )
1808 for node in main.nodes:
1809 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1810 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1811
Jon Hall5cf14d52015-07-16 12:15:19 -07001812 main.step( "Killing ONOS nodes" )
1813 killResults = main.TRUE
1814 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001815 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001816 killed = main.ONOSbench.onosKill( node.ip_address )
1817 killResults = killResults and killed
1818 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1819 onpass="ONOS nodes killed",
1820 onfail="ONOS kill unsuccessful" )
1821
1822 main.step( "Checking if ONOS is up yet" )
1823 for i in range( 2 ):
1824 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001825 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001826 started = main.ONOSbench.isup( node.ip_address )
1827 if not started:
1828 main.log.error( node.name + " didn't start!" )
1829 onosIsupResult = onosIsupResult and started
1830 if onosIsupResult == main.TRUE:
1831 break
1832 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1833 onpass="ONOS restarted",
1834 onfail="ONOS restart NOT successful" )
1835
1836 main.log.step( "Starting ONOS CLI sessions" )
1837 cliResults = main.TRUE
1838 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001839 for i in range( main.numCtrls ):
1840 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001841 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001842 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001843 threads.append( t )
1844 t.start()
1845
1846 for t in threads:
1847 t.join()
1848 cliResults = cliResults and t.result
1849 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1850 onpass="ONOS cli started",
1851 onfail="ONOS clis did not restart" )
1852
Jon Hall6e709752016-02-01 13:38:46 -08001853 for i in range( 10 ):
1854 ready = True
Jon Hall7ac7bc32016-05-05 10:57:02 -07001855 for i in main.activeNodes:
1856 cli = main.CLIs[i]
Jon Hall6e709752016-02-01 13:38:46 -08001857 output = cli.summary()
1858 if not output:
1859 ready = False
1860 time.sleep( 30 )
1861 utilities.assert_equals( expect=True, actual=ready,
1862 onpass="ONOS summary command succeded",
1863 onfail="ONOS summary command failed" )
1864 if not ready:
1865 main.cleanup()
1866 main.exit()
1867
Jon Hall5cf14d52015-07-16 12:15:19 -07001868 # Grab the time of restart so we chan check how long the gossip
1869 # protocol has had time to work
1870 main.restartTime = time.time() - killTime
1871 main.log.debug( "Restart time: " + str( main.restartTime ) )
1872 labels.append( "Restart" )
1873 data.append( str( main.restartTime ) )
1874
Jon Hall5cf14d52015-07-16 12:15:19 -07001875 # Rerun for election on restarted nodes
1876 runResults = main.TRUE
Jon Hall7ac7bc32016-05-05 10:57:02 -07001877 for i in main.activeNodes:
1878 cli = main.CLIs[i]
Jon Halla440e872016-03-31 15:15:50 -07001879 run = cli.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001880 if run != main.TRUE:
1881 main.log.error( "Error running for election on " + cli.name )
1882 runResults = runResults and run
1883 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1884 onpass="Reran for election",
1885 onfail="Failed to rerun for election" )
1886
1887 # TODO: Make this configurable
1888 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -07001889 node = main.activeNodes[0]
1890 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1891 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1892 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001893
1894 def CASE7( self, main ):
1895 """
1896 Check state after ONOS failure
1897 """
1898 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001899 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001900 assert main, "main not defined"
1901 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001902 assert main.CLIs, "main.CLIs not defined"
1903 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001904 main.case( "Running ONOS Constant State Tests" )
1905
1906 main.step( "Check that each switch has a master" )
1907 # Assert that each device has a master
1908 rolesNotNull = main.TRUE
1909 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001910 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001911 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001912 name="rolesNotNull-" + str( i ),
1913 args=[ ] )
1914 threads.append( t )
1915 t.start()
1916
1917 for t in threads:
1918 t.join()
1919 rolesNotNull = rolesNotNull and t.result
1920 utilities.assert_equals(
1921 expect=main.TRUE,
1922 actual=rolesNotNull,
1923 onpass="Each device has a master",
1924 onfail="Some devices don't have a master assigned" )
1925
1926 main.step( "Read device roles from ONOS" )
1927 ONOSMastership = []
1928 mastershipCheck = main.FALSE
1929 consistentMastership = True
1930 rolesResults = True
1931 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001932 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001933 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001934 name="roles-" + str( i ),
1935 args=[] )
1936 threads.append( t )
1937 t.start()
1938
1939 for t in threads:
1940 t.join()
1941 ONOSMastership.append( t.result )
1942
Jon Halla440e872016-03-31 15:15:50 -07001943 for i in range( len( ONOSMastership ) ):
1944 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001945 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001946 main.log.error( "Error in getting ONOS" + node + " roles" )
1947 main.log.warn( "ONOS" + node + " mastership response: " +
1948 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001949 rolesResults = False
1950 utilities.assert_equals(
1951 expect=True,
1952 actual=rolesResults,
1953 onpass="No error in reading roles output",
1954 onfail="Error in reading roles from ONOS" )
1955
1956 main.step( "Check for consistency in roles from each controller" )
1957 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1958 main.log.info(
1959 "Switch roles are consistent across all ONOS nodes" )
1960 else:
1961 consistentMastership = False
1962 utilities.assert_equals(
1963 expect=True,
1964 actual=consistentMastership,
1965 onpass="Switch roles are consistent across all ONOS nodes",
1966 onfail="ONOS nodes have different views of switch roles" )
1967
1968 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001969 for i in range( len( ONOSMastership ) ):
1970 node = str( main.activeNodes[i] + 1 )
1971 main.log.warn( "ONOS" + node + " roles: ",
Jon Hall6e709752016-02-01 13:38:46 -08001972 json.dumps( json.loads( ONOSMastership[ i ] ),
1973 sort_keys=True,
1974 indent=4,
1975 separators=( ',', ': ' ) ) )
1976 elif rolesResults and consistentMastership:
Jon Hall5cf14d52015-07-16 12:15:19 -07001977 mastershipCheck = main.TRUE
1978
Jon Hall5cf14d52015-07-16 12:15:19 -07001979 # NOTE: we expect mastership to change on controller failure
1980
1981 main.step( "Get the intents and compare across all nodes" )
1982 ONOSIntents = []
1983 intentCheck = main.FALSE
1984 consistentIntents = True
1985 intentsResults = True
1986 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001987 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001988 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001989 name="intents-" + str( i ),
1990 args=[],
1991 kwargs={ 'jsonFormat': True } )
1992 threads.append( t )
1993 t.start()
1994
1995 for t in threads:
1996 t.join()
1997 ONOSIntents.append( t.result )
1998
Jon Halla440e872016-03-31 15:15:50 -07001999 for i in range( len( ONOSIntents) ):
2000 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002001 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07002002 main.log.error( "Error in getting ONOS" + node + " intents" )
2003 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002004 repr( ONOSIntents[ i ] ) )
2005 intentsResults = False
2006 utilities.assert_equals(
2007 expect=True,
2008 actual=intentsResults,
2009 onpass="No error in reading intents output",
2010 onfail="Error in reading intents from ONOS" )
2011
2012 main.step( "Check for consistency in Intents from each controller" )
2013 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2014 main.log.info( "Intents are consistent across all ONOS " +
2015 "nodes" )
2016 else:
2017 consistentIntents = False
2018
2019 # Try to make it easy to figure out what is happening
2020 #
2021 # Intent ONOS1 ONOS2 ...
2022 # 0x01 INSTALLED INSTALLING
2023 # ... ... ...
2024 # ... ... ...
2025 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07002026 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002027 title += " " * 10 + "ONOS" + str( n + 1 )
2028 main.log.warn( title )
2029 # get all intent keys in the cluster
2030 keys = []
2031 for nodeStr in ONOSIntents:
2032 node = json.loads( nodeStr )
2033 for intent in node:
2034 keys.append( intent.get( 'id' ) )
2035 keys = set( keys )
2036 for key in keys:
2037 row = "%-13s" % key
2038 for nodeStr in ONOSIntents:
2039 node = json.loads( nodeStr )
2040 for intent in node:
2041 if intent.get( 'id' ) == key:
2042 row += "%-15s" % intent.get( 'state' )
2043 main.log.warn( row )
2044 # End table view
2045
2046 utilities.assert_equals(
2047 expect=True,
2048 actual=consistentIntents,
2049 onpass="Intents are consistent across all ONOS nodes",
2050 onfail="ONOS nodes have different views of intents" )
2051 intentStates = []
2052 for node in ONOSIntents: # Iter through ONOS nodes
2053 nodeStates = []
2054 # Iter through intents of a node
2055 try:
2056 for intent in json.loads( node ):
2057 nodeStates.append( intent[ 'state' ] )
2058 except ( ValueError, TypeError ):
2059 main.log.exception( "Error in parsing intents" )
2060 main.log.error( repr( node ) )
2061 intentStates.append( nodeStates )
2062 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2063 main.log.info( dict( out ) )
2064
2065 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07002066 for i in range( len( main.activeNodes ) ):
2067 node = str( main.activeNodes[i] + 1 )
2068 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002069 main.log.warn( json.dumps(
2070 json.loads( ONOSIntents[ i ] ),
2071 sort_keys=True,
2072 indent=4,
2073 separators=( ',', ': ' ) ) )
2074 elif intentsResults and consistentIntents:
2075 intentCheck = main.TRUE
2076
2077 # NOTE: Store has no durability, so intents are lost across system
2078 # restarts
2079 """
2080 main.step( "Compare current intents with intents before the failure" )
2081 # NOTE: this requires case 5 to pass for intentState to be set.
2082 # maybe we should stop the test if that fails?
2083 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002084 try:
2085 intentState
2086 except NameError:
2087 main.log.warn( "No previous intent state was saved" )
2088 else:
2089 if intentState and intentState == ONOSIntents[ 0 ]:
2090 sameIntents = main.TRUE
2091 main.log.info( "Intents are consistent with before failure" )
2092 # TODO: possibly the states have changed? we may need to figure out
2093 # what the acceptable states are
2094 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2095 sameIntents = main.TRUE
2096 try:
2097 before = json.loads( intentState )
2098 after = json.loads( ONOSIntents[ 0 ] )
2099 for intent in before:
2100 if intent not in after:
2101 sameIntents = main.FALSE
2102 main.log.debug( "Intent is not currently in ONOS " +
2103 "(at least in the same form):" )
2104 main.log.debug( json.dumps( intent ) )
2105 except ( ValueError, TypeError ):
2106 main.log.exception( "Exception printing intents" )
2107 main.log.debug( repr( ONOSIntents[0] ) )
2108 main.log.debug( repr( intentState ) )
2109 if sameIntents == main.FALSE:
2110 try:
2111 main.log.debug( "ONOS intents before: " )
2112 main.log.debug( json.dumps( json.loads( intentState ),
2113 sort_keys=True, indent=4,
2114 separators=( ',', ': ' ) ) )
2115 main.log.debug( "Current ONOS intents: " )
2116 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2117 sort_keys=True, indent=4,
2118 separators=( ',', ': ' ) ) )
2119 except ( ValueError, TypeError ):
2120 main.log.exception( "Exception printing intents" )
2121 main.log.debug( repr( ONOSIntents[0] ) )
2122 main.log.debug( repr( intentState ) )
2123 utilities.assert_equals(
2124 expect=main.TRUE,
2125 actual=sameIntents,
2126 onpass="Intents are consistent with before failure",
2127 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002128 intentCheck = intentCheck and sameIntents
2129 """
2130 main.step( "Get the OF Table entries and compare to before " +
2131 "component failure" )
2132 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002133 for i in range( 28 ):
2134 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002135 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
Jon Hall41d39f12016-04-11 22:54:35 -07002136 curSwitch = main.Mininet1.flowTableComp( flows[i], tmpFlows )
2137 FlowTables = FlowTables and curSwitch
2138 if curSwitch == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002139 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002140 utilities.assert_equals(
2141 expect=main.TRUE,
2142 actual=FlowTables,
2143 onpass="No changes were found in the flow tables",
2144 onfail="Changes were found in the flow tables" )
2145
2146 main.Mininet2.pingLongKill()
2147 '''
2148 # main.step( "Check the continuous pings to ensure that no packets " +
2149 # "were dropped during component failure" )
2150 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2151 main.params[ 'TESTONIP' ] )
2152 LossInPings = main.FALSE
2153 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2154 for i in range( 8, 18 ):
2155 main.log.info(
2156 "Checking for a loss in pings along flow from s" +
2157 str( i ) )
2158 LossInPings = main.Mininet2.checkForLoss(
2159 "/tmp/ping.h" +
2160 str( i ) ) or LossInPings
2161 if LossInPings == main.TRUE:
2162 main.log.info( "Loss in ping detected" )
2163 elif LossInPings == main.ERROR:
2164 main.log.info( "There are multiple mininet process running" )
2165 elif LossInPings == main.FALSE:
2166 main.log.info( "No Loss in the pings" )
2167 main.log.info( "No loss of dataplane connectivity" )
2168 # utilities.assert_equals(
2169 # expect=main.FALSE,
2170 # actual=LossInPings,
2171 # onpass="No Loss of connectivity",
2172 # onfail="Loss of dataplane connectivity detected" )
2173
2174 # NOTE: Since intents are not persisted with IntnentStore,
2175 # we expect loss in dataplane connectivity
2176 LossInPings = main.FALSE
2177 '''
2178
2179 main.step( "Leadership Election is still functional" )
2180 # Test of LeadershipElection
2181 leaderList = []
2182 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002183
2184 for i in main.activeNodes:
2185 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002186 leaderN = cli.electionTestLeader()
2187 leaderList.append( leaderN )
2188 if leaderN == main.FALSE:
2189 # error in response
2190 main.log.error( "Something is wrong with " +
2191 "electionTestLeader function, check the" +
2192 " error logs" )
2193 leaderResult = main.FALSE
2194 elif leaderN is None:
2195 main.log.error( cli.name +
2196 " shows no leader for the election-app." )
2197 leaderResult = main.FALSE
2198 if len( set( leaderList ) ) != 1:
2199 leaderResult = main.FALSE
2200 main.log.error(
2201 "Inconsistent view of leader for the election test app" )
2202 # TODO: print the list
2203 utilities.assert_equals(
2204 expect=main.TRUE,
2205 actual=leaderResult,
2206 onpass="Leadership election passed",
2207 onfail="Something went wrong with Leadership election" )
2208
2209 def CASE8( self, main ):
2210 """
2211 Compare topo
2212 """
2213 import json
2214 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002215 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002216 assert main, "main not defined"
2217 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002218 assert main.CLIs, "main.CLIs not defined"
2219 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002220
2221 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002222 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002223 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002224 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002225 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002226 elapsed = 0
2227 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002228 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002229 startTime = time.time()
2230 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002231 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002232 devicesResults = main.TRUE
2233 linksResults = main.TRUE
2234 hostsResults = main.TRUE
2235 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002236 count += 1
2237 cliStart = time.time()
2238 devices = []
2239 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002240 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002241 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002242 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002243 args=[ main.CLIs[i].devices, [ None ] ],
2244 kwargs= { 'sleep': 5, 'attempts': 5,
2245 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002246 threads.append( t )
2247 t.start()
2248
2249 for t in threads:
2250 t.join()
2251 devices.append( t.result )
2252 hosts = []
2253 ipResult = main.TRUE
2254 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002255 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002256 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002257 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002258 args=[ main.CLIs[i].hosts, [ None ] ],
2259 kwargs= { 'sleep': 5, 'attempts': 5,
2260 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002261 threads.append( t )
2262 t.start()
2263
2264 for t in threads:
2265 t.join()
2266 try:
2267 hosts.append( json.loads( t.result ) )
2268 except ( ValueError, TypeError ):
2269 main.log.exception( "Error parsing hosts results" )
2270 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002271 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002272 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002273 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002274 if hosts[ controller ]:
2275 for host in hosts[ controller ]:
2276 if host is None or host.get( 'ipAddresses', [] ) == []:
2277 main.log.error(
2278 "Error with host ipAddresses on controller" +
2279 controllerStr + ": " + str( host ) )
2280 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002281 ports = []
2282 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002283 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002284 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002285 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002286 args=[ main.CLIs[i].ports, [ None ] ],
2287 kwargs= { 'sleep': 5, 'attempts': 5,
2288 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002289 threads.append( t )
2290 t.start()
2291
2292 for t in threads:
2293 t.join()
2294 ports.append( t.result )
2295 links = []
2296 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002297 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002298 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002299 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002300 args=[ main.CLIs[i].links, [ None ] ],
2301 kwargs= { 'sleep': 5, 'attempts': 5,
2302 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002303 threads.append( t )
2304 t.start()
2305
2306 for t in threads:
2307 t.join()
2308 links.append( t.result )
2309 clusters = []
2310 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002311 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002312 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002313 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002314 args=[ main.CLIs[i].clusters, [ None ] ],
2315 kwargs= { 'sleep': 5, 'attempts': 5,
2316 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002317 threads.append( t )
2318 t.start()
2319
2320 for t in threads:
2321 t.join()
2322 clusters.append( t.result )
2323
2324 elapsed = time.time() - startTime
2325 cliTime = time.time() - cliStart
2326 print "Elapsed time: " + str( elapsed )
2327 print "CLI time: " + str( cliTime )
2328
Jon Hall6e709752016-02-01 13:38:46 -08002329 if all( e is None for e in devices ) and\
2330 all( e is None for e in hosts ) and\
2331 all( e is None for e in ports ) and\
2332 all( e is None for e in links ) and\
2333 all( e is None for e in clusters ):
2334 topoFailMsg = "Could not get topology from ONOS"
2335 main.log.error( topoFailMsg )
2336 continue # Try again, No use trying to compare
2337
Jon Hall5cf14d52015-07-16 12:15:19 -07002338 mnSwitches = main.Mininet1.getSwitches()
2339 mnLinks = main.Mininet1.getLinks()
2340 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07002341 for controller in range( len( main.activeNodes ) ):
2342 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002343 if devices[ controller ] and ports[ controller ] and\
2344 "Error" not in devices[ controller ] and\
2345 "Error" not in ports[ controller ]:
2346
Jon Hallc6793552016-01-19 14:18:37 -08002347 try:
2348 currentDevicesResult = main.Mininet1.compareSwitches(
2349 mnSwitches,
2350 json.loads( devices[ controller ] ),
2351 json.loads( ports[ controller ] ) )
2352 except ( TypeError, ValueError ) as e:
2353 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2354 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002355 else:
2356 currentDevicesResult = main.FALSE
2357 utilities.assert_equals( expect=main.TRUE,
2358 actual=currentDevicesResult,
2359 onpass="ONOS" + controllerStr +
2360 " Switches view is correct",
2361 onfail="ONOS" + controllerStr +
2362 " Switches view is incorrect" )
2363
2364 if links[ controller ] and "Error" not in links[ controller ]:
2365 currentLinksResult = main.Mininet1.compareLinks(
2366 mnSwitches, mnLinks,
2367 json.loads( links[ controller ] ) )
2368 else:
2369 currentLinksResult = main.FALSE
2370 utilities.assert_equals( expect=main.TRUE,
2371 actual=currentLinksResult,
2372 onpass="ONOS" + controllerStr +
2373 " links view is correct",
2374 onfail="ONOS" + controllerStr +
2375 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002376 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002377 currentHostsResult = main.Mininet1.compareHosts(
2378 mnHosts,
2379 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002380 elif hosts[ controller ] == []:
2381 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002382 else:
2383 currentHostsResult = main.FALSE
2384 utilities.assert_equals( expect=main.TRUE,
2385 actual=currentHostsResult,
2386 onpass="ONOS" + controllerStr +
2387 " hosts exist in Mininet",
2388 onfail="ONOS" + controllerStr +
2389 " hosts don't match Mininet" )
2390 # CHECKING HOST ATTACHMENT POINTS
2391 hostAttachment = True
Jon Halla440e872016-03-31 15:15:50 -07002392 zeroHosts = False
Jon Hall5cf14d52015-07-16 12:15:19 -07002393 # FIXME: topo-HA/obelisk specific mappings:
2394 # key is mac and value is dpid
2395 mappings = {}
2396 for i in range( 1, 29 ): # hosts 1 through 28
2397 # set up correct variables:
2398 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2399 if i == 1:
2400 deviceId = "1000".zfill(16)
2401 elif i == 2:
2402 deviceId = "2000".zfill(16)
2403 elif i == 3:
2404 deviceId = "3000".zfill(16)
2405 elif i == 4:
2406 deviceId = "3004".zfill(16)
2407 elif i == 5:
2408 deviceId = "5000".zfill(16)
2409 elif i == 6:
2410 deviceId = "6000".zfill(16)
2411 elif i == 7:
2412 deviceId = "6007".zfill(16)
2413 elif i >= 8 and i <= 17:
2414 dpid = '3' + str( i ).zfill( 3 )
2415 deviceId = dpid.zfill(16)
2416 elif i >= 18 and i <= 27:
2417 dpid = '6' + str( i ).zfill( 3 )
2418 deviceId = dpid.zfill(16)
2419 elif i == 28:
2420 deviceId = "2800".zfill(16)
2421 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002422 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002423 if hosts[ controller ] == []:
2424 main.log.warn( "There are no hosts discovered" )
Jon Halla440e872016-03-31 15:15:50 -07002425 zeroHosts = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002426 else:
2427 for host in hosts[ controller ]:
2428 mac = None
2429 location = None
2430 device = None
2431 port = None
2432 try:
2433 mac = host.get( 'mac' )
2434 assert mac, "mac field could not be found for this host object"
2435
2436 location = host.get( 'location' )
2437 assert location, "location field could not be found for this host object"
2438
2439 # Trim the protocol identifier off deviceId
2440 device = str( location.get( 'elementId' ) ).split(':')[1]
2441 assert device, "elementId field could not be found for this host location object"
2442
2443 port = location.get( 'port' )
2444 assert port, "port field could not be found for this host location object"
2445
2446 # Now check if this matches where they should be
2447 if mac and device and port:
2448 if str( port ) != "1":
2449 main.log.error( "The attachment port is incorrect for " +
2450 "host " + str( mac ) +
2451 ". Expected: 1 Actual: " + str( port) )
2452 hostAttachment = False
2453 if device != mappings[ str( mac ) ]:
2454 main.log.error( "The attachment device is incorrect for " +
2455 "host " + str( mac ) +
2456 ". Expected: " + mappings[ str( mac ) ] +
2457 " Actual: " + device )
2458 hostAttachment = False
2459 else:
2460 hostAttachment = False
2461 except AssertionError:
2462 main.log.exception( "Json object not as expected" )
2463 main.log.error( repr( host ) )
2464 hostAttachment = False
2465 else:
2466 main.log.error( "No hosts json output or \"Error\"" +
2467 " in output. hosts = " +
2468 repr( hosts[ controller ] ) )
Jon Halla440e872016-03-31 15:15:50 -07002469 if zeroHosts is False:
Jon Hall5cf14d52015-07-16 12:15:19 -07002470 # TODO: Find a way to know if there should be hosts in a
2471 # given point of the test
2472 hostAttachment = True
2473
2474 # END CHECKING HOST ATTACHMENT POINTS
2475 devicesResults = devicesResults and currentDevicesResult
2476 linksResults = linksResults and currentLinksResult
2477 hostsResults = hostsResults and currentHostsResult
2478 hostAttachmentResults = hostAttachmentResults and\
2479 hostAttachment
2480 topoResult = ( devicesResults and linksResults
2481 and hostsResults and ipResult and
2482 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002483 utilities.assert_equals( expect=True,
2484 actual=topoResult,
2485 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002486 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002487 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002488
2489 # Compare json objects for hosts and dataplane clusters
2490
2491 # hosts
2492 main.step( "Hosts view is consistent across all ONOS nodes" )
2493 consistentHostsResult = main.TRUE
2494 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002495 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002496 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002497 if hosts[ controller ] == hosts[ 0 ]:
2498 continue
2499 else: # hosts not consistent
2500 main.log.error( "hosts from ONOS" + controllerStr +
2501 " is inconsistent with ONOS1" )
2502 main.log.warn( repr( hosts[ controller ] ) )
2503 consistentHostsResult = main.FALSE
2504
2505 else:
2506 main.log.error( "Error in getting ONOS hosts from ONOS" +
2507 controllerStr )
2508 consistentHostsResult = main.FALSE
2509 main.log.warn( "ONOS" + controllerStr +
2510 " hosts response: " +
2511 repr( hosts[ controller ] ) )
2512 utilities.assert_equals(
2513 expect=main.TRUE,
2514 actual=consistentHostsResult,
2515 onpass="Hosts view is consistent across all ONOS nodes",
2516 onfail="ONOS nodes have different views of hosts" )
2517
2518 main.step( "Hosts information is correct" )
2519 hostsResults = hostsResults and ipResult
2520 utilities.assert_equals(
2521 expect=main.TRUE,
2522 actual=hostsResults,
2523 onpass="Host information is correct",
2524 onfail="Host information is incorrect" )
2525
2526 main.step( "Host attachment points to the network" )
2527 utilities.assert_equals(
2528 expect=True,
2529 actual=hostAttachmentResults,
2530 onpass="Hosts are correctly attached to the network",
2531 onfail="ONOS did not correctly attach hosts to the network" )
2532
2533 # Strongly connected clusters of devices
2534 main.step( "Clusters view is consistent across all ONOS nodes" )
2535 consistentClustersResult = main.TRUE
2536 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002537 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002538 if "Error" not in clusters[ controller ]:
2539 if clusters[ controller ] == clusters[ 0 ]:
2540 continue
2541 else: # clusters not consistent
2542 main.log.error( "clusters from ONOS" +
2543 controllerStr +
2544 " is inconsistent with ONOS1" )
2545 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002546 else:
2547 main.log.error( "Error in getting dataplane clusters " +
2548 "from ONOS" + controllerStr )
2549 consistentClustersResult = main.FALSE
2550 main.log.warn( "ONOS" + controllerStr +
2551 " clusters response: " +
2552 repr( clusters[ controller ] ) )
2553 utilities.assert_equals(
2554 expect=main.TRUE,
2555 actual=consistentClustersResult,
2556 onpass="Clusters view is consistent across all ONOS nodes",
2557 onfail="ONOS nodes have different views of clusters" )
2558
2559 main.step( "There is only one SCC" )
2560 # there should always only be one cluster
2561 try:
2562 numClusters = len( json.loads( clusters[ 0 ] ) )
2563 except ( ValueError, TypeError ):
2564 main.log.exception( "Error parsing clusters[0]: " +
2565 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002566 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002567 clusterResults = main.FALSE
2568 if numClusters == 1:
2569 clusterResults = main.TRUE
2570 utilities.assert_equals(
2571 expect=1,
2572 actual=numClusters,
2573 onpass="ONOS shows 1 SCC",
2574 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2575
2576 topoResult = ( devicesResults and linksResults
2577 and hostsResults and consistentHostsResult
2578 and consistentClustersResult and clusterResults
2579 and ipResult and hostAttachmentResults )
2580
2581 topoResult = topoResult and int( count <= 2 )
2582 note = "note it takes about " + str( int( cliTime ) ) + \
2583 " seconds for the test to make all the cli calls to fetch " +\
2584 "the topology from each ONOS instance"
2585 main.log.info(
2586 "Very crass estimate for topology discovery/convergence( " +
2587 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2588 str( count ) + " tries" )
2589
2590 main.step( "Device information is correct" )
2591 utilities.assert_equals(
2592 expect=main.TRUE,
2593 actual=devicesResults,
2594 onpass="Device information is correct",
2595 onfail="Device information is incorrect" )
2596
2597 main.step( "Links are correct" )
2598 utilities.assert_equals(
2599 expect=main.TRUE,
2600 actual=linksResults,
2601 onpass="Link are correct",
2602 onfail="Links are incorrect" )
2603
Jon Halla440e872016-03-31 15:15:50 -07002604 main.step( "Hosts are correct" )
2605 utilities.assert_equals(
2606 expect=main.TRUE,
2607 actual=hostsResults,
2608 onpass="Hosts are correct",
2609 onfail="Hosts are incorrect" )
2610
Jon Hall5cf14d52015-07-16 12:15:19 -07002611 # FIXME: move this to an ONOS state case
2612 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -07002613 nodeResults = utilities.retry( main.HA.nodesCheck,
2614 False,
2615 args=[main.activeNodes],
2616 attempts=5 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002617
Jon Hall41d39f12016-04-11 22:54:35 -07002618 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Hall5cf14d52015-07-16 12:15:19 -07002619 onpass="Nodes check successful",
2620 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002621 if not nodeResults:
Jon Hall41d39f12016-04-11 22:54:35 -07002622 for i in main.activeNodes:
Jon Halla440e872016-03-31 15:15:50 -07002623 main.log.debug( "{} components not ACTIVE: \n{}".format(
Jon Hall41d39f12016-04-11 22:54:35 -07002624 main.CLIs[i].name,
2625 main.CLIs[i].sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002626
2627 def CASE9( self, main ):
2628 """
2629 Link s3-s28 down
2630 """
2631 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002632 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002633 assert main, "main not defined"
2634 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002635 assert main.CLIs, "main.CLIs not defined"
2636 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002637 # NOTE: You should probably run a topology check after this
2638
2639 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2640
2641 description = "Turn off a link to ensure that Link Discovery " +\
2642 "is working properly"
2643 main.case( description )
2644
2645 main.step( "Kill Link between s3 and s28" )
2646 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2647 main.log.info( "Waiting " + str( linkSleep ) +
2648 " seconds for link down to be discovered" )
2649 time.sleep( linkSleep )
2650 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2651 onpass="Link down successful",
2652 onfail="Failed to bring link down" )
2653 # TODO do some sort of check here
2654
2655 def CASE10( self, main ):
2656 """
2657 Link s3-s28 up
2658 """
2659 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002660 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002661 assert main, "main not defined"
2662 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002663 assert main.CLIs, "main.CLIs not defined"
2664 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002665 # NOTE: You should probably run a topology check after this
2666
2667 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2668
2669 description = "Restore a link to ensure that Link Discovery is " + \
2670 "working properly"
2671 main.case( description )
2672
2673 main.step( "Bring link between s3 and s28 back up" )
2674 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2675 main.log.info( "Waiting " + str( linkSleep ) +
2676 " seconds for link up to be discovered" )
2677 time.sleep( linkSleep )
2678 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2679 onpass="Link up successful",
2680 onfail="Failed to bring link up" )
2681 # TODO do some sort of check here
2682
2683 def CASE11( self, main ):
2684 """
2685 Switch Down
2686 """
2687 # NOTE: You should probably run a topology check after this
2688 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002689 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002690 assert main, "main not defined"
2691 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002692 assert main.CLIs, "main.CLIs not defined"
2693 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002694
2695 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2696
2697 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002698 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002699 main.case( description )
2700 switch = main.params[ 'kill' ][ 'switch' ]
2701 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2702
2703 # TODO: Make this switch parameterizable
2704 main.step( "Kill " + switch )
2705 main.log.info( "Deleting " + switch )
2706 main.Mininet1.delSwitch( switch )
2707 main.log.info( "Waiting " + str( switchSleep ) +
2708 " seconds for switch down to be discovered" )
2709 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002710 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002711 # Peek at the deleted switch
2712 main.log.warn( str( device ) )
2713 result = main.FALSE
2714 if device and device[ 'available' ] is False:
2715 result = main.TRUE
2716 utilities.assert_equals( expect=main.TRUE, actual=result,
2717 onpass="Kill switch successful",
2718 onfail="Failed to kill switch?" )
2719
2720 def CASE12( self, main ):
2721 """
2722 Switch Up
2723 """
2724 # NOTE: You should probably run a topology check after this
2725 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002726 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002727 assert main, "main not defined"
2728 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002729 assert main.CLIs, "main.CLIs not defined"
2730 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002731 assert ONOS1Port, "ONOS1Port not defined"
2732 assert ONOS2Port, "ONOS2Port not defined"
2733 assert ONOS3Port, "ONOS3Port not defined"
2734 assert ONOS4Port, "ONOS4Port not defined"
2735 assert ONOS5Port, "ONOS5Port not defined"
2736 assert ONOS6Port, "ONOS6Port not defined"
2737 assert ONOS7Port, "ONOS7Port not defined"
2738
2739 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2740 switch = main.params[ 'kill' ][ 'switch' ]
2741 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2742 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002743 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002744 description = "Adding a switch to ensure it is discovered correctly"
2745 main.case( description )
2746
2747 main.step( "Add back " + switch )
2748 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2749 for peer in links:
2750 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002751 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002752 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2753 main.log.info( "Waiting " + str( switchSleep ) +
2754 " seconds for switch up to be discovered" )
2755 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002756 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002757 # Peek at the deleted switch
2758 main.log.warn( str( device ) )
2759 result = main.FALSE
2760 if device and device[ 'available' ]:
2761 result = main.TRUE
2762 utilities.assert_equals( expect=main.TRUE, actual=result,
2763 onpass="add switch successful",
2764 onfail="Failed to add switch?" )
2765
2766 def CASE13( self, main ):
2767 """
2768 Clean up
2769 """
2770 import os
2771 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002772 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002773 assert main, "main not defined"
2774 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002775 assert main.CLIs, "main.CLIs not defined"
2776 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002777
2778 # printing colors to terminal
2779 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2780 'blue': '\033[94m', 'green': '\033[92m',
2781 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2782 main.case( "Test Cleanup" )
2783 main.step( "Killing tcpdumps" )
2784 main.Mininet2.stopTcpdump()
2785
2786 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002787 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002788 main.step( "Copying MN pcap and ONOS log files to test station" )
2789 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2790 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002791 # NOTE: MN Pcap file is being saved to logdir.
2792 # We scp this file as MN and TestON aren't necessarily the same vm
2793
2794 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002795 # TODO: Load these from params
2796 # NOTE: must end in /
2797 logFolder = "/opt/onos/log/"
2798 logFiles = [ "karaf.log", "karaf.log.1" ]
2799 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002800 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002801 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002802 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002803 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2804 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002805 # std*.log's
2806 # NOTE: must end in /
2807 logFolder = "/opt/onos/var/"
2808 logFiles = [ "stderr.log", "stdout.log" ]
2809 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002810 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002811 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002812 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002813 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2814 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002815 else:
2816 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002817
2818 main.step( "Stopping Mininet" )
2819 mnResult = main.Mininet1.stopNet()
2820 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2821 onpass="Mininet stopped",
2822 onfail="MN cleanup NOT successful" )
2823
2824 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002825 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002826 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2827 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002828
2829 try:
2830 timerLog = open( main.logdir + "/Timers.csv", 'w')
2831 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2832 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2833 timerLog.close()
2834 except NameError, e:
2835 main.log.exception(e)
2836
2837 def CASE14( self, main ):
2838 """
2839 start election app on all onos nodes
2840 """
Jon Halle1a3b752015-07-22 13:02:46 -07002841 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002842 assert main, "main not defined"
2843 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002844 assert main.CLIs, "main.CLIs not defined"
2845 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002846
2847 main.case("Start Leadership Election app")
2848 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002849 onosCli = main.CLIs[ main.activeNodes[0] ]
2850 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002851 utilities.assert_equals(
2852 expect=main.TRUE,
2853 actual=appResult,
2854 onpass="Election app installed",
2855 onfail="Something went wrong with installing Leadership election" )
2856
2857 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002858 for i in main.activeNodes:
2859 main.CLIs[i].electionTestRun()
Jon Hall25463a82016-04-13 14:03:52 -07002860 time.sleep(5)
2861 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2862 sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall5cf14d52015-07-16 12:15:19 -07002863 utilities.assert_equals(
Jon Hall25463a82016-04-13 14:03:52 -07002864 expect=True,
2865 actual=sameResult,
2866 onpass="All nodes see the same leaderboards",
2867 onfail="Inconsistent leaderboards" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002868
Jon Hall25463a82016-04-13 14:03:52 -07002869 if sameResult:
2870 leader = leaders[ 0 ][ 0 ]
2871 if main.nodes[main.activeNodes[0]].ip_address in leader:
2872 correctLeader = True
2873 else:
2874 correctLeader = False
2875 main.step( "First node was elected leader" )
2876 utilities.assert_equals(
2877 expect=True,
2878 actual=correctLeader,
2879 onpass="Correct leader was elected",
2880 onfail="Incorrect leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002881
2882 def CASE15( self, main ):
2883 """
2884 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002885 15.1 Run election on each node
2886 15.2 Check that each node has the same leaders and candidates
2887 15.3 Find current leader and withdraw
2888 15.4 Check that a new node was elected leader
2889 15.5 Check that that new leader was the candidate of old leader
2890 15.6 Run for election on old leader
2891 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2892 15.8 Make sure that the old leader was added to the candidate list
2893
2894 old and new variable prefixes refer to data from before vs after
2895 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002896 """
2897 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002898 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002899 assert main, "main not defined"
2900 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002901 assert main.CLIs, "main.CLIs not defined"
2902 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002903
Jon Hall5cf14d52015-07-16 12:15:19 -07002904 description = "Check that Leadership Election is still functional"
2905 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002906 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002907
Jon Halla440e872016-03-31 15:15:50 -07002908 oldLeaders = [] # list of lists of each nodes' candidates before
2909 newLeaders = [] # list of lists of each nodes' candidates after
acsmars9475b1c2015-08-28 18:02:08 -07002910 oldLeader = '' # the old leader from oldLeaders, None if not same
2911 newLeader = '' # the new leaders fron newLoeaders, None if not same
2912 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002913 expectNoLeader = False # True when there is only one leader
2914 if main.numCtrls == 1:
2915 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002916
Jon Hall5cf14d52015-07-16 12:15:19 -07002917 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002918 electionResult = main.TRUE
2919
Jon Halla440e872016-03-31 15:15:50 -07002920 for i in main.activeNodes: # run test election on each node
2921 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars9475b1c2015-08-28 18:02:08 -07002922 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002923 utilities.assert_equals(
2924 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002925 actual=electionResult,
2926 onpass="All nodes successfully ran for leadership",
2927 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002928
acsmars3a72bde2015-09-02 14:16:22 -07002929 if electionResult == main.FALSE:
2930 main.log.error(
2931 "Skipping Test Case because Election Test App isn't loaded" )
2932 main.skipCase()
2933
acsmars9475b1c2015-08-28 18:02:08 -07002934 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002935 failMessage = "Nodes have different leaderboards"
Jon Halla440e872016-03-31 15:15:50 -07002936 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
Jon Hall41d39f12016-04-11 22:54:35 -07002937 sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Halla440e872016-03-31 15:15:50 -07002938 if sameResult:
2939 oldLeader = oldLeaders[ 0 ][ 0 ]
2940 main.log.warn( oldLeader )
acsmars9475b1c2015-08-28 18:02:08 -07002941 else:
Jon Halla440e872016-03-31 15:15:50 -07002942 oldLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002943 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002944 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002945 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002946 onpass="Leaderboards are consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002947 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002948
2949 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002950 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002951 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002952 if oldLeader is None:
2953 main.log.error( "Leadership isn't consistent." )
2954 withdrawResult = main.FALSE
2955 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002956 for i in main.activeNodes:
acsmars9475b1c2015-08-28 18:02:08 -07002957 if oldLeader == main.nodes[ i ].ip_address:
2958 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002959 break
2960 else: # FOR/ELSE statement
2961 main.log.error( "Leader election, could not find current leader" )
2962 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002963 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002964 utilities.assert_equals(
2965 expect=main.TRUE,
2966 actual=withdrawResult,
2967 onpass="Node was withdrawn from election",
2968 onfail="Node was not withdrawn from election" )
2969
acsmars9475b1c2015-08-28 18:02:08 -07002970 main.step( "Check that a new node was elected leader" )
acsmars9475b1c2015-08-28 18:02:08 -07002971 failMessage = "Nodes have different leaders"
acsmars9475b1c2015-08-28 18:02:08 -07002972 # Get new leaders and candidates
Jon Hall41d39f12016-04-11 22:54:35 -07002973 newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall3a7843a2016-04-12 03:01:09 -07002974 newLeader = None
Jon Halla440e872016-03-31 15:15:50 -07002975 if newLeaderResult:
Jon Hall3a7843a2016-04-12 03:01:09 -07002976 if newLeaders[ 0 ][ 0 ] == 'none':
2977 main.log.error( "No leader was elected on at least 1 node" )
2978 if not expectNoLeader:
2979 newLeaderResult = False
Jon Hall25463a82016-04-13 14:03:52 -07002980 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002981
acsmars9475b1c2015-08-28 18:02:08 -07002982 # Check that the new leader is not the older leader, which was withdrawn
2983 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002984 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08002985 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars9475b1c2015-08-28 18:02:08 -07002986 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002987 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002988 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07002989 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002990 onpass="Leadership election passed",
2991 onfail="Something went wrong with Leadership election" )
2992
Jon Halla440e872016-03-31 15:15:50 -07002993 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08002994 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars9475b1c2015-08-28 18:02:08 -07002995 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002996 if expectNoLeader:
2997 if newLeader == 'none':
2998 main.log.info( "No leader expected. None found. Pass" )
2999 correctCandidateResult = main.TRUE
3000 else:
3001 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3002 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003003 elif len( oldLeaders[0] ) >= 3:
3004 if newLeader == oldLeaders[ 0 ][ 2 ]:
3005 # correct leader was elected
3006 correctCandidateResult = main.TRUE
3007 else:
3008 correctCandidateResult = main.FALSE
3009 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3010 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003011 else:
3012 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003013 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003014 correctCandidateResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07003015 utilities.assert_equals(
3016 expect=main.TRUE,
3017 actual=correctCandidateResult,
3018 onpass="Correct Candidate Elected",
3019 onfail="Incorrect Candidate Elected" )
3020
Jon Hall5cf14d52015-07-16 12:15:19 -07003021 main.step( "Run for election on old leader( just so everyone " +
3022 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07003023 if oldLeaderCLI is not None:
3024 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003025 else:
acsmars9475b1c2015-08-28 18:02:08 -07003026 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003027 runResult = main.FALSE
3028 utilities.assert_equals(
3029 expect=main.TRUE,
3030 actual=runResult,
3031 onpass="App re-ran for election",
3032 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003033
acsmars9475b1c2015-08-28 18:02:08 -07003034 main.step(
3035 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003036 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003037 # Get new leaders and candidates
3038 reRunLeaders = []
3039 time.sleep( 5 ) # Paremterize
Jon Hall41d39f12016-04-11 22:54:35 -07003040 positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003041
acsmars9475b1c2015-08-28 18:02:08 -07003042 # Check that the re-elected node is last on the candidate List
Jon Hall3a7843a2016-04-12 03:01:09 -07003043 if not reRunLeaders[0]:
3044 positionResult = main.FALSE
3045 elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07003046 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3047 str( reRunLeaders[ 0 ] ) ) )
acsmars9475b1c2015-08-28 18:02:08 -07003048 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003049 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003050 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003051 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003052 onpass="Old leader successfully re-ran for election",
3053 onfail="Something went wrong with Leadership election after " +
3054 "the old leader re-ran for election" )
3055
3056 def CASE16( self, main ):
3057 """
3058 Install Distributed Primitives app
3059 """
3060 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003061 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003062 assert main, "main not defined"
3063 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003064 assert main.CLIs, "main.CLIs not defined"
3065 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003066
3067 # Variables for the distributed primitives tests
3068 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003069 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003070 global onosSet
3071 global onosSetName
3072 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003073 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003074 onosSet = set([])
3075 onosSetName = "TestON-set"
3076
3077 description = "Install Primitives app"
3078 main.case( description )
3079 main.step( "Install Primitives app" )
3080 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003081 node = main.activeNodes[0]
3082 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003083 utilities.assert_equals( expect=main.TRUE,
3084 actual=appResults,
3085 onpass="Primitives app activated",
3086 onfail="Primitives app not activated" )
3087 time.sleep( 5 ) # To allow all nodes to activate
3088
3089 def CASE17( self, main ):
3090 """
3091 Check for basic functionality with distributed primitives
3092 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003093 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003094 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003095 assert main, "main not defined"
3096 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003097 assert main.CLIs, "main.CLIs not defined"
3098 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003099 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003100 assert onosSetName, "onosSetName not defined"
3101 # NOTE: assert fails if value is 0/None/Empty/False
3102 try:
3103 pCounterValue
3104 except NameError:
3105 main.log.error( "pCounterValue not defined, setting to 0" )
3106 pCounterValue = 0
3107 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003108 onosSet
3109 except NameError:
3110 main.log.error( "onosSet not defined, setting to empty Set" )
3111 onosSet = set([])
3112 # Variables for the distributed primitives tests. These are local only
3113 addValue = "a"
3114 addAllValue = "a b c d e f"
3115 retainValue = "c d e f"
3116
3117 description = "Check for basic functionality with distributed " +\
3118 "primitives"
3119 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003120 main.caseExplanation = "Test the methods of the distributed " +\
3121 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003122 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003123 # Partitioned counters
3124 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003125 pCounters = []
3126 threads = []
3127 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003128 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003129 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3130 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003131 args=[ pCounterName ] )
3132 pCounterValue += 1
3133 addedPValues.append( pCounterValue )
3134 threads.append( t )
3135 t.start()
3136
3137 for t in threads:
3138 t.join()
3139 pCounters.append( t.result )
3140 # Check that counter incremented numController times
3141 pCounterResults = True
3142 for i in addedPValues:
3143 tmpResult = i in pCounters
3144 pCounterResults = pCounterResults and tmpResult
3145 if not tmpResult:
3146 main.log.error( str( i ) + " is not in partitioned "
3147 "counter incremented results" )
3148 utilities.assert_equals( expect=True,
3149 actual=pCounterResults,
3150 onpass="Default counter incremented",
3151 onfail="Error incrementing default" +
3152 " counter" )
3153
Jon Halle1a3b752015-07-22 13:02:46 -07003154 main.step( "Get then Increment a default counter on each node" )
3155 pCounters = []
3156 threads = []
3157 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003158 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003159 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3160 name="counterGetAndAdd-" + str( i ),
3161 args=[ pCounterName ] )
3162 addedPValues.append( pCounterValue )
3163 pCounterValue += 1
3164 threads.append( t )
3165 t.start()
3166
3167 for t in threads:
3168 t.join()
3169 pCounters.append( t.result )
3170 # Check that counter incremented numController times
3171 pCounterResults = True
3172 for i in addedPValues:
3173 tmpResult = i in pCounters
3174 pCounterResults = pCounterResults and tmpResult
3175 if not tmpResult:
3176 main.log.error( str( i ) + " is not in partitioned "
3177 "counter incremented results" )
3178 utilities.assert_equals( expect=True,
3179 actual=pCounterResults,
3180 onpass="Default counter incremented",
3181 onfail="Error incrementing default" +
3182 " counter" )
3183
3184 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07003185 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07003186 utilities.assert_equals( expect=main.TRUE,
3187 actual=incrementCheck,
3188 onpass="Added counters are correct",
3189 onfail="Added counters are incorrect" )
3190
3191 main.step( "Add -8 to then get a default counter on each node" )
3192 pCounters = []
3193 threads = []
3194 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003195 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003196 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3197 name="counterIncrement-" + str( i ),
3198 args=[ pCounterName ],
3199 kwargs={ "delta": -8 } )
3200 pCounterValue += -8
3201 addedPValues.append( pCounterValue )
3202 threads.append( t )
3203 t.start()
3204
3205 for t in threads:
3206 t.join()
3207 pCounters.append( t.result )
3208 # Check that counter incremented numController times
3209 pCounterResults = True
3210 for i in addedPValues:
3211 tmpResult = i in pCounters
3212 pCounterResults = pCounterResults and tmpResult
3213 if not tmpResult:
3214 main.log.error( str( i ) + " is not in partitioned "
3215 "counter incremented results" )
3216 utilities.assert_equals( expect=True,
3217 actual=pCounterResults,
3218 onpass="Default counter incremented",
3219 onfail="Error incrementing default" +
3220 " counter" )
3221
3222 main.step( "Add 5 to then get a default counter on each node" )
3223 pCounters = []
3224 threads = []
3225 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003226 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003227 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3228 name="counterIncrement-" + str( i ),
3229 args=[ pCounterName ],
3230 kwargs={ "delta": 5 } )
3231 pCounterValue += 5
3232 addedPValues.append( pCounterValue )
3233 threads.append( t )
3234 t.start()
3235
3236 for t in threads:
3237 t.join()
3238 pCounters.append( t.result )
3239 # Check that counter incremented numController times
3240 pCounterResults = True
3241 for i in addedPValues:
3242 tmpResult = i in pCounters
3243 pCounterResults = pCounterResults and tmpResult
3244 if not tmpResult:
3245 main.log.error( str( i ) + " is not in partitioned "
3246 "counter incremented results" )
3247 utilities.assert_equals( expect=True,
3248 actual=pCounterResults,
3249 onpass="Default counter incremented",
3250 onfail="Error incrementing default" +
3251 " counter" )
3252
3253 main.step( "Get then add 5 to a default counter on each node" )
3254 pCounters = []
3255 threads = []
3256 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003257 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003258 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3259 name="counterIncrement-" + str( i ),
3260 args=[ pCounterName ],
3261 kwargs={ "delta": 5 } )
3262 addedPValues.append( pCounterValue )
3263 pCounterValue += 5
3264 threads.append( t )
3265 t.start()
3266
3267 for t in threads:
3268 t.join()
3269 pCounters.append( t.result )
3270 # Check that counter incremented numController times
3271 pCounterResults = True
3272 for i in addedPValues:
3273 tmpResult = i in pCounters
3274 pCounterResults = pCounterResults and tmpResult
3275 if not tmpResult:
3276 main.log.error( str( i ) + " is not in partitioned "
3277 "counter incremented results" )
3278 utilities.assert_equals( expect=True,
3279 actual=pCounterResults,
3280 onpass="Default counter incremented",
3281 onfail="Error incrementing default" +
3282 " counter" )
3283
3284 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07003285 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07003286 utilities.assert_equals( expect=main.TRUE,
3287 actual=incrementCheck,
3288 onpass="Added counters are correct",
3289 onfail="Added counters are incorrect" )
3290
Jon Hall5cf14d52015-07-16 12:15:19 -07003291 # DISTRIBUTED SETS
3292 main.step( "Distributed Set get" )
3293 size = len( onosSet )
3294 getResponses = []
3295 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003296 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003297 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003298 name="setTestGet-" + str( i ),
3299 args=[ onosSetName ] )
3300 threads.append( t )
3301 t.start()
3302 for t in threads:
3303 t.join()
3304 getResponses.append( t.result )
3305
3306 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003307 for i in range( len( main.activeNodes ) ):
3308 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003309 if isinstance( getResponses[ i ], list):
3310 current = set( getResponses[ i ] )
3311 if len( current ) == len( getResponses[ i ] ):
3312 # no repeats
3313 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003314 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003315 " has incorrect view" +
3316 " of set " + onosSetName + ":\n" +
3317 str( getResponses[ i ] ) )
3318 main.log.debug( "Expected: " + str( onosSet ) )
3319 main.log.debug( "Actual: " + str( current ) )
3320 getResults = main.FALSE
3321 else:
3322 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003323 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003324 " has repeat elements in" +
3325 " set " + onosSetName + ":\n" +
3326 str( getResponses[ i ] ) )
3327 getResults = main.FALSE
3328 elif getResponses[ i ] == main.ERROR:
3329 getResults = main.FALSE
3330 utilities.assert_equals( expect=main.TRUE,
3331 actual=getResults,
3332 onpass="Set elements are correct",
3333 onfail="Set elements are incorrect" )
3334
3335 main.step( "Distributed Set size" )
3336 sizeResponses = []
3337 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003338 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003339 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003340 name="setTestSize-" + str( i ),
3341 args=[ onosSetName ] )
3342 threads.append( t )
3343 t.start()
3344 for t in threads:
3345 t.join()
3346 sizeResponses.append( t.result )
3347
3348 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003349 for i in range( len( main.activeNodes ) ):
3350 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003351 if size != sizeResponses[ i ]:
3352 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003353 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003354 " expected a size of " + str( size ) +
3355 " for set " + onosSetName +
3356 " but got " + str( sizeResponses[ i ] ) )
3357 utilities.assert_equals( expect=main.TRUE,
3358 actual=sizeResults,
3359 onpass="Set sizes are correct",
3360 onfail="Set sizes are incorrect" )
3361
3362 main.step( "Distributed Set add()" )
3363 onosSet.add( addValue )
3364 addResponses = []
3365 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003366 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003367 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003368 name="setTestAdd-" + str( i ),
3369 args=[ onosSetName, addValue ] )
3370 threads.append( t )
3371 t.start()
3372 for t in threads:
3373 t.join()
3374 addResponses.append( t.result )
3375
3376 # main.TRUE = successfully changed the set
3377 # main.FALSE = action resulted in no change in set
3378 # main.ERROR - Some error in executing the function
3379 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003380 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003381 if addResponses[ i ] == main.TRUE:
3382 # All is well
3383 pass
3384 elif addResponses[ i ] == main.FALSE:
3385 # Already in set, probably fine
3386 pass
3387 elif addResponses[ i ] == main.ERROR:
3388 # Error in execution
3389 addResults = main.FALSE
3390 else:
3391 # unexpected result
3392 addResults = main.FALSE
3393 if addResults != main.TRUE:
3394 main.log.error( "Error executing set add" )
3395
3396 # Check if set is still correct
3397 size = len( onosSet )
3398 getResponses = []
3399 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003400 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003401 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003402 name="setTestGet-" + str( i ),
3403 args=[ onosSetName ] )
3404 threads.append( t )
3405 t.start()
3406 for t in threads:
3407 t.join()
3408 getResponses.append( t.result )
3409 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003410 for i in range( len( main.activeNodes ) ):
3411 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003412 if isinstance( getResponses[ i ], list):
3413 current = set( getResponses[ i ] )
3414 if len( current ) == len( getResponses[ i ] ):
3415 # no repeats
3416 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003417 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003418 " of set " + onosSetName + ":\n" +
3419 str( getResponses[ i ] ) )
3420 main.log.debug( "Expected: " + str( onosSet ) )
3421 main.log.debug( "Actual: " + str( current ) )
3422 getResults = main.FALSE
3423 else:
3424 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003425 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003426 " set " + onosSetName + ":\n" +
3427 str( getResponses[ i ] ) )
3428 getResults = main.FALSE
3429 elif getResponses[ i ] == main.ERROR:
3430 getResults = main.FALSE
3431 sizeResponses = []
3432 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003433 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003434 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003435 name="setTestSize-" + str( i ),
3436 args=[ onosSetName ] )
3437 threads.append( t )
3438 t.start()
3439 for t in threads:
3440 t.join()
3441 sizeResponses.append( t.result )
3442 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003443 for i in range( len( main.activeNodes ) ):
3444 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003445 if size != sizeResponses[ i ]:
3446 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003447 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003448 " expected a size of " + str( size ) +
3449 " for set " + onosSetName +
3450 " but got " + str( sizeResponses[ i ] ) )
3451 addResults = addResults and getResults and sizeResults
3452 utilities.assert_equals( expect=main.TRUE,
3453 actual=addResults,
3454 onpass="Set add correct",
3455 onfail="Set add was incorrect" )
3456
3457 main.step( "Distributed Set addAll()" )
3458 onosSet.update( addAllValue.split() )
3459 addResponses = []
3460 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003461 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003462 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003463 name="setTestAddAll-" + str( i ),
3464 args=[ onosSetName, addAllValue ] )
3465 threads.append( t )
3466 t.start()
3467 for t in threads:
3468 t.join()
3469 addResponses.append( t.result )
3470
3471 # main.TRUE = successfully changed the set
3472 # main.FALSE = action resulted in no change in set
3473 # main.ERROR - Some error in executing the function
3474 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003475 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003476 if addResponses[ i ] == main.TRUE:
3477 # All is well
3478 pass
3479 elif addResponses[ i ] == main.FALSE:
3480 # Already in set, probably fine
3481 pass
3482 elif addResponses[ i ] == main.ERROR:
3483 # Error in execution
3484 addAllResults = main.FALSE
3485 else:
3486 # unexpected result
3487 addAllResults = main.FALSE
3488 if addAllResults != main.TRUE:
3489 main.log.error( "Error executing set addAll" )
3490
3491 # Check if set is still correct
3492 size = len( onosSet )
3493 getResponses = []
3494 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003495 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003496 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003497 name="setTestGet-" + str( i ),
3498 args=[ onosSetName ] )
3499 threads.append( t )
3500 t.start()
3501 for t in threads:
3502 t.join()
3503 getResponses.append( t.result )
3504 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003505 for i in range( len( main.activeNodes ) ):
3506 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003507 if isinstance( getResponses[ i ], list):
3508 current = set( getResponses[ i ] )
3509 if len( current ) == len( getResponses[ i ] ):
3510 # no repeats
3511 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003512 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003513 " has incorrect view" +
3514 " of set " + onosSetName + ":\n" +
3515 str( getResponses[ i ] ) )
3516 main.log.debug( "Expected: " + str( onosSet ) )
3517 main.log.debug( "Actual: " + str( current ) )
3518 getResults = main.FALSE
3519 else:
3520 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003521 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003522 " has repeat elements in" +
3523 " set " + onosSetName + ":\n" +
3524 str( getResponses[ i ] ) )
3525 getResults = main.FALSE
3526 elif getResponses[ i ] == main.ERROR:
3527 getResults = main.FALSE
3528 sizeResponses = []
3529 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003530 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003531 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003532 name="setTestSize-" + str( i ),
3533 args=[ onosSetName ] )
3534 threads.append( t )
3535 t.start()
3536 for t in threads:
3537 t.join()
3538 sizeResponses.append( t.result )
3539 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003540 for i in range( len( main.activeNodes ) ):
3541 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003542 if size != sizeResponses[ i ]:
3543 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003544 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003545 " expected a size of " + str( size ) +
3546 " for set " + onosSetName +
3547 " but got " + str( sizeResponses[ i ] ) )
3548 addAllResults = addAllResults and getResults and sizeResults
3549 utilities.assert_equals( expect=main.TRUE,
3550 actual=addAllResults,
3551 onpass="Set addAll correct",
3552 onfail="Set addAll was incorrect" )
3553
3554 main.step( "Distributed Set contains()" )
3555 containsResponses = []
3556 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003557 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003558 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003559 name="setContains-" + str( i ),
3560 args=[ onosSetName ],
3561 kwargs={ "values": addValue } )
3562 threads.append( t )
3563 t.start()
3564 for t in threads:
3565 t.join()
3566 # NOTE: This is the tuple
3567 containsResponses.append( t.result )
3568
3569 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003570 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003571 if containsResponses[ i ] == main.ERROR:
3572 containsResults = main.FALSE
3573 else:
3574 containsResults = containsResults and\
3575 containsResponses[ i ][ 1 ]
3576 utilities.assert_equals( expect=main.TRUE,
3577 actual=containsResults,
3578 onpass="Set contains is functional",
3579 onfail="Set contains failed" )
3580
3581 main.step( "Distributed Set containsAll()" )
3582 containsAllResponses = []
3583 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003584 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003585 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003586 name="setContainsAll-" + str( i ),
3587 args=[ onosSetName ],
3588 kwargs={ "values": addAllValue } )
3589 threads.append( t )
3590 t.start()
3591 for t in threads:
3592 t.join()
3593 # NOTE: This is the tuple
3594 containsAllResponses.append( t.result )
3595
3596 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003597 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003598 if containsResponses[ i ] == main.ERROR:
3599 containsResults = main.FALSE
3600 else:
3601 containsResults = containsResults and\
3602 containsResponses[ i ][ 1 ]
3603 utilities.assert_equals( expect=main.TRUE,
3604 actual=containsAllResults,
3605 onpass="Set containsAll is functional",
3606 onfail="Set containsAll failed" )
3607
3608 main.step( "Distributed Set remove()" )
3609 onosSet.remove( addValue )
3610 removeResponses = []
3611 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003612 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003613 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003614 name="setTestRemove-" + str( i ),
3615 args=[ onosSetName, addValue ] )
3616 threads.append( t )
3617 t.start()
3618 for t in threads:
3619 t.join()
3620 removeResponses.append( t.result )
3621
3622 # main.TRUE = successfully changed the set
3623 # main.FALSE = action resulted in no change in set
3624 # main.ERROR - Some error in executing the function
3625 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003626 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003627 if removeResponses[ i ] == main.TRUE:
3628 # All is well
3629 pass
3630 elif removeResponses[ i ] == main.FALSE:
3631 # not in set, probably fine
3632 pass
3633 elif removeResponses[ i ] == main.ERROR:
3634 # Error in execution
3635 removeResults = main.FALSE
3636 else:
3637 # unexpected result
3638 removeResults = main.FALSE
3639 if removeResults != main.TRUE:
3640 main.log.error( "Error executing set remove" )
3641
3642 # Check if set is still correct
3643 size = len( onosSet )
3644 getResponses = []
3645 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003646 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003647 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003648 name="setTestGet-" + str( i ),
3649 args=[ onosSetName ] )
3650 threads.append( t )
3651 t.start()
3652 for t in threads:
3653 t.join()
3654 getResponses.append( t.result )
3655 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003656 for i in range( len( main.activeNodes ) ):
3657 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003658 if isinstance( getResponses[ i ], list):
3659 current = set( getResponses[ i ] )
3660 if len( current ) == len( getResponses[ i ] ):
3661 # no repeats
3662 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003663 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003664 " has incorrect view" +
3665 " of set " + onosSetName + ":\n" +
3666 str( getResponses[ i ] ) )
3667 main.log.debug( "Expected: " + str( onosSet ) )
3668 main.log.debug( "Actual: " + str( current ) )
3669 getResults = main.FALSE
3670 else:
3671 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003672 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003673 " has repeat elements in" +
3674 " set " + onosSetName + ":\n" +
3675 str( getResponses[ i ] ) )
3676 getResults = main.FALSE
3677 elif getResponses[ i ] == main.ERROR:
3678 getResults = main.FALSE
3679 sizeResponses = []
3680 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003681 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003682 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003683 name="setTestSize-" + str( i ),
3684 args=[ onosSetName ] )
3685 threads.append( t )
3686 t.start()
3687 for t in threads:
3688 t.join()
3689 sizeResponses.append( t.result )
3690 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003691 for i in range( len( main.activeNodes ) ):
3692 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003693 if size != sizeResponses[ i ]:
3694 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003695 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003696 " expected a size of " + str( size ) +
3697 " for set " + onosSetName +
3698 " but got " + str( sizeResponses[ i ] ) )
3699 removeResults = removeResults and getResults and sizeResults
3700 utilities.assert_equals( expect=main.TRUE,
3701 actual=removeResults,
3702 onpass="Set remove correct",
3703 onfail="Set remove was incorrect" )
3704
3705 main.step( "Distributed Set removeAll()" )
3706 onosSet.difference_update( addAllValue.split() )
3707 removeAllResponses = []
3708 threads = []
3709 try:
Jon Halla440e872016-03-31 15:15:50 -07003710 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003711 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003712 name="setTestRemoveAll-" + str( i ),
3713 args=[ onosSetName, addAllValue ] )
3714 threads.append( t )
3715 t.start()
3716 for t in threads:
3717 t.join()
3718 removeAllResponses.append( t.result )
3719 except Exception, e:
3720 main.log.exception(e)
3721
3722 # main.TRUE = successfully changed the set
3723 # main.FALSE = action resulted in no change in set
3724 # main.ERROR - Some error in executing the function
3725 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003726 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003727 if removeAllResponses[ i ] == main.TRUE:
3728 # All is well
3729 pass
3730 elif removeAllResponses[ i ] == main.FALSE:
3731 # not in set, probably fine
3732 pass
3733 elif removeAllResponses[ i ] == main.ERROR:
3734 # Error in execution
3735 removeAllResults = main.FALSE
3736 else:
3737 # unexpected result
3738 removeAllResults = main.FALSE
3739 if removeAllResults != main.TRUE:
3740 main.log.error( "Error executing set removeAll" )
3741
3742 # Check if set is still correct
3743 size = len( onosSet )
3744 getResponses = []
3745 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003746 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003747 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003748 name="setTestGet-" + str( i ),
3749 args=[ onosSetName ] )
3750 threads.append( t )
3751 t.start()
3752 for t in threads:
3753 t.join()
3754 getResponses.append( t.result )
3755 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003756 for i in range( len( main.activeNodes ) ):
3757 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003758 if isinstance( getResponses[ i ], list):
3759 current = set( getResponses[ i ] )
3760 if len( current ) == len( getResponses[ i ] ):
3761 # no repeats
3762 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003763 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003764 " has incorrect view" +
3765 " of set " + onosSetName + ":\n" +
3766 str( getResponses[ i ] ) )
3767 main.log.debug( "Expected: " + str( onosSet ) )
3768 main.log.debug( "Actual: " + str( current ) )
3769 getResults = main.FALSE
3770 else:
3771 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003772 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003773 " has repeat elements in" +
3774 " set " + onosSetName + ":\n" +
3775 str( getResponses[ i ] ) )
3776 getResults = main.FALSE
3777 elif getResponses[ i ] == main.ERROR:
3778 getResults = main.FALSE
3779 sizeResponses = []
3780 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003781 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003782 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003783 name="setTestSize-" + str( i ),
3784 args=[ onosSetName ] )
3785 threads.append( t )
3786 t.start()
3787 for t in threads:
3788 t.join()
3789 sizeResponses.append( t.result )
3790 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003791 for i in range( len( main.activeNodes ) ):
3792 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003793 if size != sizeResponses[ i ]:
3794 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003795 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003796 " expected a size of " + str( size ) +
3797 " for set " + onosSetName +
3798 " but got " + str( sizeResponses[ i ] ) )
3799 removeAllResults = removeAllResults and getResults and sizeResults
3800 utilities.assert_equals( expect=main.TRUE,
3801 actual=removeAllResults,
3802 onpass="Set removeAll correct",
3803 onfail="Set removeAll was incorrect" )
3804
3805 main.step( "Distributed Set addAll()" )
3806 onosSet.update( addAllValue.split() )
3807 addResponses = []
3808 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003809 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003810 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003811 name="setTestAddAll-" + str( i ),
3812 args=[ onosSetName, addAllValue ] )
3813 threads.append( t )
3814 t.start()
3815 for t in threads:
3816 t.join()
3817 addResponses.append( t.result )
3818
3819 # main.TRUE = successfully changed the set
3820 # main.FALSE = action resulted in no change in set
3821 # main.ERROR - Some error in executing the function
3822 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003823 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003824 if addResponses[ i ] == main.TRUE:
3825 # All is well
3826 pass
3827 elif addResponses[ i ] == main.FALSE:
3828 # Already in set, probably fine
3829 pass
3830 elif addResponses[ i ] == main.ERROR:
3831 # Error in execution
3832 addAllResults = main.FALSE
3833 else:
3834 # unexpected result
3835 addAllResults = main.FALSE
3836 if addAllResults != main.TRUE:
3837 main.log.error( "Error executing set addAll" )
3838
3839 # Check if set is still correct
3840 size = len( onosSet )
3841 getResponses = []
3842 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003843 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003844 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003845 name="setTestGet-" + str( i ),
3846 args=[ onosSetName ] )
3847 threads.append( t )
3848 t.start()
3849 for t in threads:
3850 t.join()
3851 getResponses.append( t.result )
3852 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003853 for i in range( len( main.activeNodes ) ):
3854 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003855 if isinstance( getResponses[ i ], list):
3856 current = set( getResponses[ i ] )
3857 if len( current ) == len( getResponses[ i ] ):
3858 # no repeats
3859 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003860 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003861 " has incorrect view" +
3862 " of set " + onosSetName + ":\n" +
3863 str( getResponses[ i ] ) )
3864 main.log.debug( "Expected: " + str( onosSet ) )
3865 main.log.debug( "Actual: " + str( current ) )
3866 getResults = main.FALSE
3867 else:
3868 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003869 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003870 " has repeat elements in" +
3871 " set " + onosSetName + ":\n" +
3872 str( getResponses[ i ] ) )
3873 getResults = main.FALSE
3874 elif getResponses[ i ] == main.ERROR:
3875 getResults = main.FALSE
3876 sizeResponses = []
3877 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003878 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003879 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003880 name="setTestSize-" + str( i ),
3881 args=[ onosSetName ] )
3882 threads.append( t )
3883 t.start()
3884 for t in threads:
3885 t.join()
3886 sizeResponses.append( t.result )
3887 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003888 for i in range( len( main.activeNodes ) ):
3889 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003890 if size != sizeResponses[ i ]:
3891 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003892 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003893 " expected a size of " + str( size ) +
3894 " for set " + onosSetName +
3895 " but got " + str( sizeResponses[ i ] ) )
3896 addAllResults = addAllResults and getResults and sizeResults
3897 utilities.assert_equals( expect=main.TRUE,
3898 actual=addAllResults,
3899 onpass="Set addAll correct",
3900 onfail="Set addAll was incorrect" )
3901
3902 main.step( "Distributed Set clear()" )
3903 onosSet.clear()
3904 clearResponses = []
3905 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003906 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003907 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003908 name="setTestClear-" + str( i ),
3909 args=[ onosSetName, " "], # Values doesn't matter
3910 kwargs={ "clear": True } )
3911 threads.append( t )
3912 t.start()
3913 for t in threads:
3914 t.join()
3915 clearResponses.append( t.result )
3916
3917 # main.TRUE = successfully changed the set
3918 # main.FALSE = action resulted in no change in set
3919 # main.ERROR - Some error in executing the function
3920 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003921 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003922 if clearResponses[ i ] == main.TRUE:
3923 # All is well
3924 pass
3925 elif clearResponses[ i ] == main.FALSE:
3926 # Nothing set, probably fine
3927 pass
3928 elif clearResponses[ i ] == main.ERROR:
3929 # Error in execution
3930 clearResults = main.FALSE
3931 else:
3932 # unexpected result
3933 clearResults = main.FALSE
3934 if clearResults != main.TRUE:
3935 main.log.error( "Error executing set clear" )
3936
3937 # Check if set is still correct
3938 size = len( onosSet )
3939 getResponses = []
3940 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003941 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003942 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003943 name="setTestGet-" + str( i ),
3944 args=[ onosSetName ] )
3945 threads.append( t )
3946 t.start()
3947 for t in threads:
3948 t.join()
3949 getResponses.append( t.result )
3950 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003951 for i in range( len( main.activeNodes ) ):
3952 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003953 if isinstance( getResponses[ i ], list):
3954 current = set( getResponses[ i ] )
3955 if len( current ) == len( getResponses[ i ] ):
3956 # no repeats
3957 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003958 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003959 " has incorrect view" +
3960 " of set " + onosSetName + ":\n" +
3961 str( getResponses[ i ] ) )
3962 main.log.debug( "Expected: " + str( onosSet ) )
3963 main.log.debug( "Actual: " + str( current ) )
3964 getResults = main.FALSE
3965 else:
3966 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003967 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003968 " has repeat elements in" +
3969 " set " + onosSetName + ":\n" +
3970 str( getResponses[ i ] ) )
3971 getResults = main.FALSE
3972 elif getResponses[ i ] == main.ERROR:
3973 getResults = main.FALSE
3974 sizeResponses = []
3975 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003976 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003977 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003978 name="setTestSize-" + str( i ),
3979 args=[ onosSetName ] )
3980 threads.append( t )
3981 t.start()
3982 for t in threads:
3983 t.join()
3984 sizeResponses.append( t.result )
3985 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003986 for i in range( len( main.activeNodes ) ):
3987 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003988 if size != sizeResponses[ i ]:
3989 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003990 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003991 " expected a size of " + str( size ) +
3992 " for set " + onosSetName +
3993 " but got " + str( sizeResponses[ i ] ) )
3994 clearResults = clearResults and getResults and sizeResults
3995 utilities.assert_equals( expect=main.TRUE,
3996 actual=clearResults,
3997 onpass="Set clear correct",
3998 onfail="Set clear was incorrect" )
3999
4000 main.step( "Distributed Set addAll()" )
4001 onosSet.update( addAllValue.split() )
4002 addResponses = []
4003 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004004 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004005 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004006 name="setTestAddAll-" + str( i ),
4007 args=[ onosSetName, addAllValue ] )
4008 threads.append( t )
4009 t.start()
4010 for t in threads:
4011 t.join()
4012 addResponses.append( t.result )
4013
4014 # main.TRUE = successfully changed the set
4015 # main.FALSE = action resulted in no change in set
4016 # main.ERROR - Some error in executing the function
4017 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004018 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004019 if addResponses[ i ] == main.TRUE:
4020 # All is well
4021 pass
4022 elif addResponses[ i ] == main.FALSE:
4023 # Already in set, probably fine
4024 pass
4025 elif addResponses[ i ] == main.ERROR:
4026 # Error in execution
4027 addAllResults = main.FALSE
4028 else:
4029 # unexpected result
4030 addAllResults = main.FALSE
4031 if addAllResults != main.TRUE:
4032 main.log.error( "Error executing set addAll" )
4033
4034 # Check if set is still correct
4035 size = len( onosSet )
4036 getResponses = []
4037 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004038 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004039 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004040 name="setTestGet-" + str( i ),
4041 args=[ onosSetName ] )
4042 threads.append( t )
4043 t.start()
4044 for t in threads:
4045 t.join()
4046 getResponses.append( t.result )
4047 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004048 for i in range( len( main.activeNodes ) ):
4049 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004050 if isinstance( getResponses[ i ], list):
4051 current = set( getResponses[ i ] )
4052 if len( current ) == len( getResponses[ i ] ):
4053 # no repeats
4054 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004055 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004056 " has incorrect view" +
4057 " of set " + onosSetName + ":\n" +
4058 str( getResponses[ i ] ) )
4059 main.log.debug( "Expected: " + str( onosSet ) )
4060 main.log.debug( "Actual: " + str( current ) )
4061 getResults = main.FALSE
4062 else:
4063 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004064 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004065 " has repeat elements in" +
4066 " set " + onosSetName + ":\n" +
4067 str( getResponses[ i ] ) )
4068 getResults = main.FALSE
4069 elif getResponses[ i ] == main.ERROR:
4070 getResults = main.FALSE
4071 sizeResponses = []
4072 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004073 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004074 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004075 name="setTestSize-" + str( i ),
4076 args=[ onosSetName ] )
4077 threads.append( t )
4078 t.start()
4079 for t in threads:
4080 t.join()
4081 sizeResponses.append( t.result )
4082 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004083 for i in range( len( main.activeNodes ) ):
4084 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004085 if size != sizeResponses[ i ]:
4086 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004087 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004088 " expected a size of " + str( size ) +
4089 " for set " + onosSetName +
4090 " but got " + str( sizeResponses[ i ] ) )
4091 addAllResults = addAllResults and getResults and sizeResults
4092 utilities.assert_equals( expect=main.TRUE,
4093 actual=addAllResults,
4094 onpass="Set addAll correct",
4095 onfail="Set addAll was incorrect" )
4096
4097 main.step( "Distributed Set retain()" )
4098 onosSet.intersection_update( retainValue.split() )
4099 retainResponses = []
4100 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004101 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004102 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004103 name="setTestRetain-" + str( i ),
4104 args=[ onosSetName, retainValue ],
4105 kwargs={ "retain": True } )
4106 threads.append( t )
4107 t.start()
4108 for t in threads:
4109 t.join()
4110 retainResponses.append( t.result )
4111
4112 # main.TRUE = successfully changed the set
4113 # main.FALSE = action resulted in no change in set
4114 # main.ERROR - Some error in executing the function
4115 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004116 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004117 if retainResponses[ i ] == main.TRUE:
4118 # All is well
4119 pass
4120 elif retainResponses[ i ] == main.FALSE:
4121 # Already in set, probably fine
4122 pass
4123 elif retainResponses[ i ] == main.ERROR:
4124 # Error in execution
4125 retainResults = main.FALSE
4126 else:
4127 # unexpected result
4128 retainResults = main.FALSE
4129 if retainResults != main.TRUE:
4130 main.log.error( "Error executing set retain" )
4131
4132 # Check if set is still correct
4133 size = len( onosSet )
4134 getResponses = []
4135 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004136 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004137 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004138 name="setTestGet-" + str( i ),
4139 args=[ onosSetName ] )
4140 threads.append( t )
4141 t.start()
4142 for t in threads:
4143 t.join()
4144 getResponses.append( t.result )
4145 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004146 for i in range( len( main.activeNodes ) ):
4147 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004148 if isinstance( getResponses[ i ], list):
4149 current = set( getResponses[ i ] )
4150 if len( current ) == len( getResponses[ i ] ):
4151 # no repeats
4152 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004153 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004154 " has incorrect view" +
4155 " of set " + onosSetName + ":\n" +
4156 str( getResponses[ i ] ) )
4157 main.log.debug( "Expected: " + str( onosSet ) )
4158 main.log.debug( "Actual: " + str( current ) )
4159 getResults = main.FALSE
4160 else:
4161 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004162 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004163 " has repeat elements in" +
4164 " set " + onosSetName + ":\n" +
4165 str( getResponses[ i ] ) )
4166 getResults = main.FALSE
4167 elif getResponses[ i ] == main.ERROR:
4168 getResults = main.FALSE
4169 sizeResponses = []
4170 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004171 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004172 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004173 name="setTestSize-" + str( i ),
4174 args=[ onosSetName ] )
4175 threads.append( t )
4176 t.start()
4177 for t in threads:
4178 t.join()
4179 sizeResponses.append( t.result )
4180 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004181 for i in range( len( main.activeNodes ) ):
4182 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004183 if size != sizeResponses[ i ]:
4184 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004185 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004186 str( size ) + " for set " + onosSetName +
4187 " but got " + str( sizeResponses[ i ] ) )
4188 retainResults = retainResults and getResults and sizeResults
4189 utilities.assert_equals( expect=main.TRUE,
4190 actual=retainResults,
4191 onpass="Set retain correct",
4192 onfail="Set retain was incorrect" )
4193
Jon Hall2a5002c2015-08-21 16:49:11 -07004194 # Transactional maps
4195 main.step( "Partitioned Transactional maps put" )
4196 tMapValue = "Testing"
4197 numKeys = 100
4198 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004199 node = main.activeNodes[0]
4200 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004201 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004202 for i in putResponses:
4203 if putResponses[ i ][ 'value' ] != tMapValue:
4204 putResult = False
4205 else:
4206 putResult = False
4207 if not putResult:
4208 main.log.debug( "Put response values: " + str( putResponses ) )
4209 utilities.assert_equals( expect=True,
4210 actual=putResult,
4211 onpass="Partitioned Transactional Map put successful",
4212 onfail="Partitioned Transactional Map put values are incorrect" )
4213
4214 main.step( "Partitioned Transactional maps get" )
Jon Hall9bfadd22016-05-11 14:48:07 -07004215 # FIXME: is this sleep needed?
4216 time.sleep( 5 )
4217
Jon Hall2a5002c2015-08-21 16:49:11 -07004218 getCheck = True
4219 for n in range( 1, numKeys + 1 ):
4220 getResponses = []
4221 threads = []
4222 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004223 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004224 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4225 name="TMap-get-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08004226 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004227 threads.append( t )
4228 t.start()
4229 for t in threads:
4230 t.join()
4231 getResponses.append( t.result )
4232 for node in getResponses:
4233 if node != tMapValue:
4234 valueCheck = False
4235 if not valueCheck:
4236 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4237 main.log.warn( getResponses )
4238 getCheck = getCheck and valueCheck
4239 utilities.assert_equals( expect=True,
4240 actual=getCheck,
4241 onpass="Partitioned Transactional Map get values were correct",
4242 onfail="Partitioned Transactional Map values incorrect" )