blob: 1adb53c6abdf3cd90d600e1df28e08055c311124 [file] [log] [blame]
Jon Hall85794ff2015-07-08 14:12:30 -07001"""
2Description: This test is to determine if a single
3 instance ONOS 'cluster' can handle a restart
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAsingleInstanceRestart:
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 Hall85794ff2015-07-08 14:12:30 -070053 main.log.info( "ONOS Single node cluster restart " +
54 "HA test - initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall85794ff2015-07-08 14:12:30 -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 )
Jon Hall85794ff2015-07-08 14:12:30 -070071
Jon Halle1a3b752015-07-22 13:02:46 -070072 try:
Jon Hall53c5e662016-04-13 16:06:56 -070073 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070074 main.HA = HA()
Jon Halle1a3b752015-07-22 13:02:46 -070075 except Exception as e:
76 main.log.exception( e )
77 main.cleanup()
78 main.exit()
79
80 main.CLIs = []
81 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070082 ipList = []
83 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
84 try:
Jon Halle1a3b752015-07-22 13:02:46 -070085 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
86 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
87 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -070088 except AttributeError:
89 break
Jon Hall85794ff2015-07-08 14:12:30 -070090
Jon Hall5cf14d52015-07-16 12:15:19 -070091 main.step( "Create cell file" )
92 cellAppString = main.params[ 'ENV' ][ 'appString' ]
93 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
94 main.Mininet1.ip_address,
95 cellAppString, ipList )
Jon Hall85794ff2015-07-08 14:12:30 -070096 main.step( "Applying cell variable to environment" )
97 cellResult = main.ONOSbench.setCell( cellName )
98 verifyResult = main.ONOSbench.verifyCell()
99
100 # FIXME:this is short term fix
101 main.log.info( "Removing raft logs" )
102 main.ONOSbench.onosRemoveRaftLogs()
103
104 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700105 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700106 main.ONOSbench.onosUninstall( node.ip_address )
107
108 # Make sure ONOS is DEAD
109 main.log.info( "Killing any ONOS processes" )
110 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700111 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700112 killed = main.ONOSbench.onosKill( node.ip_address )
113 killResults = killResults and killed
114
115 cleanInstallResult = main.TRUE
116 gitPullResult = main.TRUE
117
118 main.step( "Starting Mininet" )
119 # scp topo file to mininet
120 # TODO: move to params?
121 topoName = "obelisk.py"
122 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700123 main.ONOSbench.scp( main.Mininet1,
124 filePath + topoName,
125 main.Mininet1.home,
126 direction="to" )
Jon Hall85794ff2015-07-08 14:12:30 -0700127 mnResult = main.Mininet1.startNet( )
128 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
129 onpass="Mininet Started",
130 onfail="Error starting Mininet" )
131
132 main.step( "Git checkout and pull " + gitBranch )
133 if PULLCODE:
134 main.ONOSbench.gitCheckout( gitBranch )
135 gitPullResult = main.ONOSbench.gitPull()
136 # values of 1 or 3 are good
137 utilities.assert_lesser( expect=0, actual=gitPullResult,
138 onpass="Git pull successful",
139 onfail="Git pull failed" )
140 main.ONOSbench.getVersion( report=True )
141
142 main.step( "Using mvn clean install" )
143 cleanInstallResult = main.TRUE
144 if PULLCODE and gitPullResult == main.TRUE:
145 cleanInstallResult = main.ONOSbench.cleanInstall()
146 else:
147 main.log.warn( "Did not pull new code so skipping mvn " +
148 "clean install" )
149 utilities.assert_equals( expect=main.TRUE,
150 actual=cleanInstallResult,
151 onpass="MCI successful",
152 onfail="MCI failed" )
153 # GRAPHS
154 # NOTE: important params here:
155 # job = name of Jenkins job
156 # Plot Name = Plot-HA, only can be used if multiple plots
157 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700158 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700159 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700160 index = "2"
Jon Hall85794ff2015-07-08 14:12:30 -0700161 graphs = '<ac:structured-macro ac:name="html">\n'
162 graphs += '<ac:plain-text-body><![CDATA[\n'
163 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800164 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall85794ff2015-07-08 14:12:30 -0700165 '&width=500&height=300"' +\
166 'noborder="0" width="500" height="300" scrolling="yes" ' +\
167 'seamless="seamless"></iframe>\n'
168 graphs += ']]></ac:plain-text-body>\n'
169 graphs += '</ac:structured-macro>\n'
170 main.log.wiki(graphs)
171
Jon Halle1a3b752015-07-22 13:02:46 -0700172 main.CLIs = []
173 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700174 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700175 for i in range( 1, main.numCtrls + 1 ):
176 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
177 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
178 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700179
180 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
181 main.Mininet1.ip_address,
182 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700183 cellResult = main.ONOSbench.setCell( "SingleHA" )
184 verifyResult = main.ONOSbench.verifyCell()
185 main.step( "Creating ONOS package" )
186 packageResult = main.ONOSbench.onosPackage()
187 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
188 onpass="ONOS package successful",
189 onfail="ONOS package failed" )
190
191 main.step( "Installing ONOS package" )
Jon Halla440e872016-03-31 15:15:50 -0700192 onosInstallResult = main.TRUE
193 for node in main.nodes:
194 tmpResult = main.ONOSbench.onosInstall( options="-f",
195 node=node.ip_address )
196 onosInstallResult = onosInstallResult and tmpResult
Jon Hall85794ff2015-07-08 14:12:30 -0700197 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
198 onpass="ONOS install successful",
199 onfail="ONOS install failed" )
200
201 main.step( "Checking if ONOS is up yet" )
202 for i in range( 2 ):
Jon Halla440e872016-03-31 15:15:50 -0700203 onosIsupResult = main.TRUE
204 for node in main.nodes:
205 started = main.ONOSbench.isup( node.ip_address )
206 if not started:
207 main.log.error( node.name + " hasn't started" )
208 onosIsupResult = onosIsupResult and started
209 if onosIsupResult == main.TRUE:
Jon Hall85794ff2015-07-08 14:12:30 -0700210 break
Jon Halla440e872016-03-31 15:15:50 -0700211 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
Jon Hall85794ff2015-07-08 14:12:30 -0700212 onpass="ONOS startup successful",
213 onfail="ONOS startup failed" )
214
215 main.log.step( "Starting ONOS CLI sessions" )
Jon Halla440e872016-03-31 15:15:50 -0700216 cliResults = main.TRUE
217 threads = []
218 for i in range( main.numCtrls ):
219 t = main.Thread( target=main.CLIs[i].startOnosCli,
220 name="startOnosCli-" + str( i ),
221 args=[main.nodes[i].ip_address] )
222 threads.append( t )
223 t.start()
224
225 for t in threads:
226 t.join()
227 cliResults = cliResults and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700228 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
229 onpass="ONOS cli startup successful",
230 onfail="ONOS cli startup failed" )
231
Jon Halla440e872016-03-31 15:15:50 -0700232 # Create a list of active nodes for use when some nodes are stopped
233 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
234
Jon Hall85794ff2015-07-08 14:12:30 -0700235 if main.params[ 'tcpdump' ].lower() == "true":
236 main.step( "Start Packet Capture MN" )
237 main.Mininet2.startTcpdump(
238 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
239 + "-MN.pcap",
240 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
241 port=main.params[ 'MNtcpdump' ][ 'port' ] )
242
Jon Halla440e872016-03-31 15:15:50 -0700243 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -0700244 nodeResults = utilities.retry( main.HA.nodesCheck,
245 False,
246 args=[main.activeNodes],
247 attempts=5 )
Jon Halla440e872016-03-31 15:15:50 -0700248
Jon Hall41d39f12016-04-11 22:54:35 -0700249 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Halla440e872016-03-31 15:15:50 -0700250 onpass="Nodes check successful",
251 onfail="Nodes check NOT successful" )
252
253 if not nodeResults:
Jon Hall7ac7bc32016-05-05 10:57:02 -0700254 for i in main.activeNodes:
255 cli = main.CLIs[i]
Jon Halla440e872016-03-31 15:15:50 -0700256 main.log.debug( "{} components not ACTIVE: \n{}".format(
257 cli.name,
258 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
259
Jon Hall85794ff2015-07-08 14:12:30 -0700260 if cliResults == main.FALSE:
261 main.log.error( "Failed to start ONOS, stopping test" )
262 main.cleanup()
263 main.exit()
264
Jon Hall172b7ba2016-04-07 18:12:20 -0700265 main.step( "Activate apps defined in the params file" )
266 # get data from the params
267 apps = main.params.get( 'apps' )
268 if apps:
269 apps = apps.split(',')
270 main.log.warn( apps )
271 activateResult = True
272 for app in apps:
273 main.CLIs[ 0 ].app( app, "Activate" )
274 # TODO: check this worked
275 time.sleep( 10 ) # wait for apps to activate
276 for app in apps:
277 state = main.CLIs[ 0 ].appStatus( app )
278 if state == "ACTIVE":
279 activateResult = activeResult and True
280 else:
281 main.log.error( "{} is in {} state".format( app, state ) )
282 activeResult = False
283 utilities.assert_equals( expect=True,
284 actual=activateResult,
285 onpass="Successfully activated apps",
286 onfail="Failed to activate apps" )
287 else:
288 main.log.warn( "No apps were specified to be loaded after startup" )
289
290 main.step( "Set ONOS configurations" )
291 config = main.params.get( 'ONOS_Configuration' )
292 if config:
293 main.log.debug( config )
294 checkResult = main.TRUE
295 for component in config:
296 for setting in config[component]:
297 value = config[component][setting]
298 check = main.CLIs[ 0 ].setCfg( component, setting, value )
299 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
300 checkResult = check and checkResult
301 utilities.assert_equals( expect=main.TRUE,
302 actual=checkResult,
303 onpass="Successfully set config",
304 onfail="Failed to set config" )
305 else:
306 main.log.warn( "No configurations were specified to be changed after startup" )
307
Jon Hall9d2dcad2016-04-08 10:15:20 -0700308 main.step( "App Ids check" )
309 appCheck = main.TRUE
310 threads = []
311 for i in main.activeNodes:
312 t = main.Thread( target=main.CLIs[i].appToIDCheck,
313 name="appToIDCheck-" + str( i ),
314 args=[] )
315 threads.append( t )
316 t.start()
317
318 for t in threads:
319 t.join()
320 appCheck = appCheck and t.result
321 if appCheck != main.TRUE:
322 node = main.activeNodes[0]
323 main.log.warn( main.CLIs[node].apps() )
324 main.log.warn( main.CLIs[node].appIDs() )
325 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
326 onpass="App Ids seem to be correct",
327 onfail="Something is wrong with app Ids" )
328
Jon Hall85794ff2015-07-08 14:12:30 -0700329 def CASE2( self, main ):
330 """
331 Assign devices to controllers
332 """
333 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700334 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700335 assert main, "main not defined"
336 assert utilities.assert_equals, "utilities.assert_equals not defined"
337
338 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700339 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700340 "and check that an ONOS node becomes the " +\
341 "master of the device."
342 main.step( "Assign switches to controllers" )
343
344 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700345 for i in range( main.numCtrls ):
346 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700347 swList = []
348 for i in range( 1, 29 ):
349 swList.append( "s" + str( i ) )
350 main.Mininet1.assignSwController( sw=swList, ip=ipList )
351
352 mastershipCheck = main.TRUE
353 for i in range( 1, 29 ):
354 response = main.Mininet1.getSwController( "s" + str( i ) )
355 try:
356 main.log.info( str( response ) )
357 except Exception:
358 main.log.info( repr( response ) )
Jon Halla440e872016-03-31 15:15:50 -0700359 for node in main.nodes:
360 if re.search( "tcp:" + node.ip_address, response ):
361 mastershipCheck = mastershipCheck and main.TRUE
362 else:
363 main.log.error( "Error, node " + node.ip_address + " is " +
364 "not in the list of controllers s" +
365 str( i ) + " is connecting to." )
366 mastershipCheck = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700367 utilities.assert_equals(
368 expect=main.TRUE,
369 actual=mastershipCheck,
370 onpass="Switch mastership assigned correctly",
371 onfail="Switches not assigned correctly to controllers" )
372
373 def CASE21( self, main ):
374 """
375 Assign mastership to controllers
376 """
Jon Halle1a3b752015-07-22 13:02:46 -0700377 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700378 assert main, "main not defined"
379 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700380 assert main.CLIs, "main.CLIs not defined"
381 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700382
383 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700384 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700385 "device. Then manually assign" +\
386 " mastership to specific ONOS nodes using" +\
387 " 'device-role'"
388 main.step( "Assign mastership of switches to specific controllers" )
Jon Halla440e872016-03-31 15:15:50 -0700389 # Manually assign mastership to the controller we want
Jon Hall85794ff2015-07-08 14:12:30 -0700390 roleCall = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700391
392 ipList = [ ]
393 deviceList = []
394 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700395 try:
Jon Halla440e872016-03-31 15:15:50 -0700396 # Assign mastership to specific controllers. This assignment was
397 # determined for a 7 node cluser, but will work with any sized
398 # cluster
Jon Hall85794ff2015-07-08 14:12:30 -0700399 for i in range( 1, 29 ): # switches 1 through 28
Jon Hall85794ff2015-07-08 14:12:30 -0700400 # set up correct variables:
401 if i == 1:
Jon Halla440e872016-03-31 15:15:50 -0700402 c = 0
403 ip = main.nodes[ c ].ip_address # ONOS1
404 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700405 elif i == 2:
Jon Halla440e872016-03-31 15:15:50 -0700406 c = 1 % main.numCtrls
407 ip = main.nodes[ c ].ip_address # ONOS2
408 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700409 elif i == 3:
Jon Halla440e872016-03-31 15:15:50 -0700410 c = 1 % main.numCtrls
411 ip = main.nodes[ c ].ip_address # ONOS2
412 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700413 elif i == 4:
Jon Halla440e872016-03-31 15:15:50 -0700414 c = 3 % main.numCtrls
415 ip = main.nodes[ c ].ip_address # ONOS4
416 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700417 elif i == 5:
Jon Halla440e872016-03-31 15:15:50 -0700418 c = 2 % main.numCtrls
419 ip = main.nodes[ c ].ip_address # ONOS3
420 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700421 elif i == 6:
Jon Halla440e872016-03-31 15:15:50 -0700422 c = 2 % main.numCtrls
423 ip = main.nodes[ c ].ip_address # ONOS3
424 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700425 elif i == 7:
Jon Halla440e872016-03-31 15:15:50 -0700426 c = 5 % main.numCtrls
427 ip = main.nodes[ c ].ip_address # ONOS6
428 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700429 elif i >= 8 and i <= 17:
Jon Halla440e872016-03-31 15:15:50 -0700430 c = 4 % main.numCtrls
431 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall85794ff2015-07-08 14:12:30 -0700432 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700433 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700434 elif i >= 18 and i <= 27:
Jon Halla440e872016-03-31 15:15:50 -0700435 c = 6 % main.numCtrls
436 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall85794ff2015-07-08 14:12:30 -0700437 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700438 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700439 elif i == 28:
Jon Halla440e872016-03-31 15:15:50 -0700440 c = 0
441 ip = main.nodes[ c ].ip_address # ONOS1
442 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700443 else:
444 main.log.error( "You didn't write an else statement for " +
445 "switch s" + str( i ) )
Jon Halla440e872016-03-31 15:15:50 -0700446 roleCall = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700447 # Assign switch
448 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
449 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700450 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
451 ipList.append( ip )
452 deviceList.append( deviceId )
Jon Hall85794ff2015-07-08 14:12:30 -0700453 except ( AttributeError, AssertionError ):
454 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700455 main.log.info( onosCli.devices() )
Jon Hall85794ff2015-07-08 14:12:30 -0700456 utilities.assert_equals(
457 expect=main.TRUE,
458 actual=roleCall,
459 onpass="Re-assigned switch mastership to designated controller",
460 onfail="Something wrong with deviceRole calls" )
461
462 main.step( "Check mastership was correctly assigned" )
Jon Halla440e872016-03-31 15:15:50 -0700463 roleCheck = main.TRUE
464 # NOTE: This is due to the fact that device mastership change is not
465 # atomic and is actually a multi step process
466 time.sleep( 5 )
467 for i in range( len( ipList ) ):
468 ip = ipList[i]
469 deviceId = deviceList[i]
470 # Check assignment
471 master = onosCli.getRole( deviceId ).get( 'master' )
472 if ip in master:
473 roleCheck = roleCheck and main.TRUE
474 else:
475 roleCheck = roleCheck and main.FALSE
476 main.log.error( "Error, controller " + ip + " is not" +
477 " master " + "of device " +
478 str( deviceId ) + ". Master is " +
479 repr( master ) + "." )
Jon Hall85794ff2015-07-08 14:12:30 -0700480 utilities.assert_equals(
481 expect=main.TRUE,
482 actual=roleCheck,
483 onpass="Switches were successfully reassigned to designated " +
484 "controller",
485 onfail="Switches were not successfully reassigned" )
486
487 def CASE3( self, main ):
488 """
489 Assign intents
490 """
491 import time
492 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700493 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700494 assert main, "main not defined"
495 assert utilities.assert_equals, "utilities.assert_equals not defined"
496 # NOTE: we must reinstall intents until we have a persistant intent
497 # datastore!
498 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700499 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700500 "assign predetermined host-to-host intents." +\
501 " After installation, check that the intent" +\
502 " is distributed to all nodes and the state" +\
503 " is INSTALLED"
504
505 # install onos-app-fwd
506 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700507 onosCli = main.CLIs[ main.activeNodes[0] ]
508 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700509 utilities.assert_equals( expect=main.TRUE, actual=installResults,
510 onpass="Install fwd successful",
511 onfail="Install fwd failed" )
512
513 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700514 appCheck = main.TRUE
515 threads = []
516 for i in main.activeNodes:
517 t = main.Thread( target=main.CLIs[i].appToIDCheck,
518 name="appToIDCheck-" + str( i ),
519 args=[] )
520 threads.append( t )
521 t.start()
522
523 for t in threads:
524 t.join()
525 appCheck = appCheck and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700526 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700527 main.log.warn( onosCli.apps() )
528 main.log.warn( onosCli.appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700529 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
530 onpass="App Ids seem to be correct",
531 onfail="Something is wrong with app Ids" )
532
533 main.step( "Discovering Hosts( Via pingall for now )" )
534 # FIXME: Once we have a host discovery mechanism, use that instead
535 # REACTIVE FWD test
536 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700537 passMsg = "Reactive Pingall test passed"
538 time1 = time.time()
539 pingResult = main.Mininet1.pingall()
540 time2 = time.time()
541 if not pingResult:
542 main.log.warn("First pingall failed. Trying again...")
Jon Hall85794ff2015-07-08 14:12:30 -0700543 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700544 passMsg += " on the second try"
545 utilities.assert_equals(
546 expect=main.TRUE,
547 actual=pingResult,
548 onpass= passMsg,
549 onfail="Reactive Pingall failed, " +
550 "one or more ping pairs failed" )
551 main.log.info( "Time for pingall: %2f seconds" %
552 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700553 # timeout for fwd flows
554 time.sleep( 11 )
555 # uninstall onos-app-fwd
556 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700557 node = main.activeNodes[0]
558 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700559 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
560 onpass="Uninstall fwd successful",
561 onfail="Uninstall fwd failed" )
562
563 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700564 threads = []
565 appCheck2 = main.TRUE
566 for i in main.activeNodes:
567 t = main.Thread( target=main.CLIs[i].appToIDCheck,
568 name="appToIDCheck-" + str( i ),
569 args=[] )
570 threads.append( t )
571 t.start()
572
573 for t in threads:
574 t.join()
575 appCheck2 = appCheck2 and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700576 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700577 node = main.activeNodes[0]
578 main.log.warn( main.CLIs[node].apps() )
579 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700580 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
581 onpass="App Ids seem to be correct",
582 onfail="Something is wrong with app Ids" )
583
584 main.step( "Add host intents via cli" )
585 intentIds = []
Jon Halla440e872016-03-31 15:15:50 -0700586 # TODO: move the host numbers to params
587 # Maybe look at all the paths we ping?
Jon Hall85794ff2015-07-08 14:12:30 -0700588 intentAddResult = True
589 hostResult = main.TRUE
590 for i in range( 8, 18 ):
591 main.log.info( "Adding host intent between h" + str( i ) +
592 " and h" + str( i + 10 ) )
593 host1 = "00:00:00:00:00:" + \
594 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
595 host2 = "00:00:00:00:00:" + \
596 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
597 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700598 host1Dict = onosCli.getHost( host1 )
599 host2Dict = onosCli.getHost( host2 )
Jon Hall85794ff2015-07-08 14:12:30 -0700600 host1Id = None
601 host2Id = None
602 if host1Dict and host2Dict:
603 host1Id = host1Dict.get( 'id', None )
604 host2Id = host2Dict.get( 'id', None )
605 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700606 nodeNum = ( i % len( main.activeNodes ) )
607 node = main.activeNodes[nodeNum]
608 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall85794ff2015-07-08 14:12:30 -0700609 if tmpId:
610 main.log.info( "Added intent with id: " + tmpId )
611 intentIds.append( tmpId )
612 else:
613 main.log.error( "addHostIntent returned: " +
614 repr( tmpId ) )
615 else:
616 main.log.error( "Error, getHost() failed for h" + str( i ) +
617 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700618 node = main.activeNodes[0]
619 hosts = main.CLIs[node].hosts()
Jon Hall85794ff2015-07-08 14:12:30 -0700620 main.log.warn( "Hosts output: " )
621 try:
622 main.log.warn( json.dumps( json.loads( hosts ),
623 sort_keys=True,
624 indent=4,
625 separators=( ',', ': ' ) ) )
626 except ( ValueError, TypeError ):
627 main.log.warn( repr( hosts ) )
628 hostResult = main.FALSE
629 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
630 onpass="Found a host id for each host",
631 onfail="Error looking up host ids" )
632
633 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700634 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700635 main.log.info( "Submitted intents: " + str( intentIds ) )
636 main.log.info( "Intents in ONOS: " + str( onosIds ) )
637 for intent in intentIds:
638 if intent in onosIds:
639 pass # intent submitted is in onos
640 else:
641 intentAddResult = False
642 if intentAddResult:
643 intentStop = time.time()
644 else:
645 intentStop = None
646 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700647 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700648 intentStates = []
649 installedCheck = True
650 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
651 count = 0
652 try:
653 for intent in json.loads( intents ):
654 state = intent.get( 'state', None )
655 if "INSTALLED" not in state:
656 installedCheck = False
657 intentId = intent.get( 'id', None )
658 intentStates.append( ( intentId, state ) )
659 except ( ValueError, TypeError ):
660 main.log.exception( "Error parsing intents" )
661 # add submitted intents not in the store
662 tmplist = [ i for i, s in intentStates ]
663 missingIntents = False
664 for i in intentIds:
665 if i not in tmplist:
666 intentStates.append( ( i, " - " ) )
667 missingIntents = True
668 intentStates.sort()
669 for i, s in intentStates:
670 count += 1
671 main.log.info( "%-6s%-15s%-15s" %
672 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700673 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700674 try:
675 missing = False
676 if leaders:
677 parsedLeaders = json.loads( leaders )
678 main.log.warn( json.dumps( parsedLeaders,
679 sort_keys=True,
680 indent=4,
681 separators=( ',', ': ' ) ) )
682 # check for all intent partitions
683 topics = []
684 for i in range( 14 ):
685 topics.append( "intent-partition-" + str( i ) )
686 main.log.debug( topics )
687 ONOStopics = [ j['topic'] for j in parsedLeaders ]
688 for topic in topics:
689 if topic not in ONOStopics:
690 main.log.error( "Error: " + topic +
691 " not in leaders" )
692 missing = True
693 else:
694 main.log.error( "leaders() returned None" )
695 except ( ValueError, TypeError ):
696 main.log.exception( "Error parsing leaders" )
697 main.log.error( repr( leaders ) )
698 # Check all nodes
699 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700700 for i in main.activeNodes:
701 response = main.CLIs[i].leaders( jsonFormat=False)
702 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
703 str( response ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700704
Jon Halla440e872016-03-31 15:15:50 -0700705 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700706 try:
707 if partitions :
708 parsedPartitions = json.loads( partitions )
709 main.log.warn( json.dumps( parsedPartitions,
710 sort_keys=True,
711 indent=4,
712 separators=( ',', ': ' ) ) )
713 # TODO check for a leader in all paritions
714 # TODO check for consistency among nodes
715 else:
716 main.log.error( "partitions() returned None" )
717 except ( ValueError, TypeError ):
718 main.log.exception( "Error parsing partitions" )
719 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700720 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700721 try:
722 if pendingMap :
723 parsedPending = json.loads( pendingMap )
724 main.log.warn( json.dumps( parsedPending,
725 sort_keys=True,
726 indent=4,
727 separators=( ',', ': ' ) ) )
728 # TODO check something here?
729 else:
730 main.log.error( "pendingMap() returned None" )
731 except ( ValueError, TypeError ):
732 main.log.exception( "Error parsing pending map" )
733 main.log.error( repr( pendingMap ) )
734
735 intentAddResult = bool( intentAddResult and not missingIntents and
736 installedCheck )
737 if not intentAddResult:
738 main.log.error( "Error in pushing host intents to ONOS" )
739
740 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700741 for j in range(100):
Jon Hall85794ff2015-07-08 14:12:30 -0700742 correct = True
743 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700744 for i in main.activeNodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700745 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700746 ids = main.CLIs[i].getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700747 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700748 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall85794ff2015-07-08 14:12:30 -0700749 str( sorted( onosIds ) ) )
750 if sorted( ids ) != sorted( intentIds ):
751 main.log.warn( "Set of intent IDs doesn't match" )
752 correct = False
753 break
754 else:
Jon Halla440e872016-03-31 15:15:50 -0700755 intents = json.loads( main.CLIs[i].intents() )
Jon Hall85794ff2015-07-08 14:12:30 -0700756 for intent in intents:
757 if intent[ 'state' ] != "INSTALLED":
758 main.log.warn( "Intent " + intent[ 'id' ] +
759 " is " + intent[ 'state' ] )
760 correct = False
761 break
762 if correct:
763 break
764 else:
765 time.sleep(1)
766 if not intentStop:
767 intentStop = time.time()
768 global gossipTime
769 gossipTime = intentStop - intentStart
770 main.log.info( "It took about " + str( gossipTime ) +
771 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700772 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700773 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700774 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700775 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700776 onpass="ECM anti-entropy for intents worked within " +
777 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700778 onfail="Intent ECM anti-entropy took too long. " +
779 "Expected time:{}, Actual time:{}".format( maxGossipTime,
780 gossipTime ) )
781 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700782 intentAddResult = True
783
784 if not intentAddResult or "key" in pendingMap:
785 import time
786 installedCheck = True
787 main.log.info( "Sleeping 60 seconds to see if intents are found" )
788 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700789 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700790 main.log.info( "Submitted intents: " + str( intentIds ) )
791 main.log.info( "Intents in ONOS: " + str( onosIds ) )
792 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700793 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700794 intentStates = []
795 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
796 count = 0
797 try:
798 for intent in json.loads( intents ):
799 # Iter through intents of a node
800 state = intent.get( 'state', None )
801 if "INSTALLED" not in state:
802 installedCheck = False
803 intentId = intent.get( 'id', None )
804 intentStates.append( ( intentId, state ) )
805 except ( ValueError, TypeError ):
806 main.log.exception( "Error parsing intents" )
807 # add submitted intents not in the store
808 tmplist = [ i for i, s in intentStates ]
809 for i in intentIds:
810 if i not in tmplist:
811 intentStates.append( ( i, " - " ) )
812 intentStates.sort()
813 for i, s in intentStates:
814 count += 1
815 main.log.info( "%-6s%-15s%-15s" %
816 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700817 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700818 try:
819 missing = False
820 if leaders:
821 parsedLeaders = json.loads( leaders )
822 main.log.warn( json.dumps( parsedLeaders,
823 sort_keys=True,
824 indent=4,
825 separators=( ',', ': ' ) ) )
826 # check for all intent partitions
827 # check for election
828 topics = []
829 for i in range( 14 ):
830 topics.append( "intent-partition-" + str( i ) )
831 # FIXME: this should only be after we start the app
832 topics.append( "org.onosproject.election" )
833 main.log.debug( topics )
834 ONOStopics = [ j['topic'] for j in parsedLeaders ]
835 for topic in topics:
836 if topic not in ONOStopics:
837 main.log.error( "Error: " + topic +
838 " not in leaders" )
839 missing = True
840 else:
841 main.log.error( "leaders() returned None" )
842 except ( ValueError, TypeError ):
843 main.log.exception( "Error parsing leaders" )
844 main.log.error( repr( leaders ) )
845 # Check all nodes
846 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700847 for i in main.activeNodes:
848 node = main.CLIs[i]
849 response = node.leaders( jsonFormat=False)
850 main.log.warn( str( node.name ) + " leaders output: \n" +
851 str( response ) )
852
853 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700854 try:
855 if partitions :
856 parsedPartitions = json.loads( partitions )
857 main.log.warn( json.dumps( parsedPartitions,
858 sort_keys=True,
859 indent=4,
860 separators=( ',', ': ' ) ) )
861 # TODO check for a leader in all paritions
862 # TODO check for consistency among nodes
863 else:
864 main.log.error( "partitions() returned None" )
865 except ( ValueError, TypeError ):
866 main.log.exception( "Error parsing partitions" )
867 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700868 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700869 try:
870 if pendingMap :
871 parsedPending = json.loads( pendingMap )
872 main.log.warn( json.dumps( parsedPending,
873 sort_keys=True,
874 indent=4,
875 separators=( ',', ': ' ) ) )
876 # TODO check something here?
877 else:
878 main.log.error( "pendingMap() returned None" )
879 except ( ValueError, TypeError ):
880 main.log.exception( "Error parsing pending map" )
881 main.log.error( repr( pendingMap ) )
882
883 def CASE4( self, main ):
884 """
885 Ping across added host intents
886 """
887 import json
888 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700889 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700890 assert main, "main not defined"
891 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halla440e872016-03-31 15:15:50 -0700892 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700893 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700894 "functionality and check the state of " +\
895 "the intent"
Jon Hall9d2dcad2016-04-08 10:15:20 -0700896
Jon Hall41d39f12016-04-11 22:54:35 -0700897 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall9d2dcad2016-04-08 10:15:20 -0700898 main.step( "Check Intent state" )
899 installedCheck = True
900 # Print the intent states
901 intents = main.ONOScli1.intents()
902 intentStates = []
903 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
904 count = 0
905 # Iter through intents of a node
906 try:
907 for intent in json.loads( intents ):
908 state = intent.get( 'state', None )
909 if "INSTALLED" not in state:
910 installedCheck = False
911 intentId = intent.get( 'id', None )
912 intentStates.append( ( intentId, state ) )
913 except ( ValueError, TypeError ):
914 main.log.exception( "Error parsing intents." )
915 # Print states
916 intentStates.sort()
917 for i, s in intentStates:
918 count += 1
919 main.log.info( "%-6s%-15s%-15s" %
920 ( str( count ), str( i ), str( s ) ) )
921 utilities.assert_equals( expect=True, actual=installedCheck,
922 onpass="Intents are all INSTALLED",
923 onfail="Intents are not all in " +
924 "INSTALLED state" )
925
Jon Hall85794ff2015-07-08 14:12:30 -0700926 main.step( "Ping across added host intents" )
927 PingResult = main.TRUE
928 for i in range( 8, 18 ):
929 ping = main.Mininet1.pingHost( src="h" + str( i ),
930 target="h" + str( i + 10 ) )
931 PingResult = PingResult and ping
932 if ping == main.FALSE:
933 main.log.warn( "Ping failed between h" + str( i ) +
934 " and h" + str( i + 10 ) )
935 elif ping == main.TRUE:
936 main.log.info( "Ping test passed!" )
937 # Don't set PingResult or you'd override failures
938 if PingResult == main.FALSE:
939 main.log.error(
940 "Intents have not been installed correctly, pings failed." )
941 # TODO: pretty print
942 main.log.warn( "ONOS1 intents: " )
943 try:
Jon Halla440e872016-03-31 15:15:50 -0700944 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700945 main.log.warn( json.dumps( json.loads( tmpIntents ),
946 sort_keys=True,
947 indent=4,
948 separators=( ',', ': ' ) ) )
949 except ( ValueError, TypeError ):
950 main.log.warn( repr( tmpIntents ) )
951 utilities.assert_equals(
952 expect=main.TRUE,
953 actual=PingResult,
954 onpass="Intents have been installed correctly and pings work",
955 onfail="Intents have not been installed correctly, pings failed." )
956
Jon Hall85794ff2015-07-08 14:12:30 -0700957 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700958 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700959 topicCheck = main.TRUE
960 try:
961 if leaders:
962 parsedLeaders = json.loads( leaders )
963 main.log.warn( json.dumps( parsedLeaders,
964 sort_keys=True,
965 indent=4,
966 separators=( ',', ': ' ) ) )
967 # check for all intent partitions
968 # check for election
969 # TODO: Look at Devices as topics now that it uses this system
970 topics = []
971 for i in range( 14 ):
972 topics.append( "intent-partition-" + str( i ) )
973 # FIXME: this should only be after we start the app
974 # FIXME: topics.append( "org.onosproject.election" )
975 # Print leaders output
976 main.log.debug( topics )
977 ONOStopics = [ j['topic'] for j in parsedLeaders ]
978 for topic in topics:
979 if topic not in ONOStopics:
980 main.log.error( "Error: " + topic +
981 " not in leaders" )
982 topicCheck = main.FALSE
983 else:
984 main.log.error( "leaders() returned None" )
985 topicCheck = main.FALSE
986 except ( ValueError, TypeError ):
987 topicCheck = main.FALSE
988 main.log.exception( "Error parsing leaders" )
989 main.log.error( repr( leaders ) )
990 # TODO: Check for a leader of these topics
Jon Halla440e872016-03-31 15:15:50 -0700991 # Check all nodes
992 if topicCheck:
993 for i in main.activeNodes:
994 node = main.CLIs[i]
995 response = node.leaders( jsonFormat=False)
996 main.log.warn( str( node.name ) + " leaders output: \n" +
997 str( response ) )
998
Jon Hall85794ff2015-07-08 14:12:30 -0700999 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1000 onpass="intent Partitions is in leaders",
1001 onfail="Some topics were lost " )
1002 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001003 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001004 try:
1005 if partitions :
1006 parsedPartitions = json.loads( partitions )
1007 main.log.warn( json.dumps( parsedPartitions,
1008 sort_keys=True,
1009 indent=4,
1010 separators=( ',', ': ' ) ) )
1011 # TODO check for a leader in all paritions
1012 # TODO check for consistency among nodes
1013 else:
1014 main.log.error( "partitions() returned None" )
1015 except ( ValueError, TypeError ):
1016 main.log.exception( "Error parsing partitions" )
1017 main.log.error( repr( partitions ) )
1018 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001019 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001020 try:
1021 if pendingMap :
1022 parsedPending = json.loads( pendingMap )
1023 main.log.warn( json.dumps( parsedPending,
1024 sort_keys=True,
1025 indent=4,
1026 separators=( ',', ': ' ) ) )
1027 # TODO check something here?
1028 else:
1029 main.log.error( "pendingMap() returned None" )
1030 except ( ValueError, TypeError ):
1031 main.log.exception( "Error parsing pending map" )
1032 main.log.error( repr( pendingMap ) )
1033
1034 if not installedCheck:
1035 main.log.info( "Waiting 60 seconds to see if the state of " +
1036 "intents change" )
1037 time.sleep( 60 )
1038 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001039 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001040 intentStates = []
1041 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1042 count = 0
1043 # Iter through intents of a node
1044 try:
1045 for intent in json.loads( intents ):
1046 state = intent.get( 'state', None )
1047 if "INSTALLED" not in state:
1048 installedCheck = False
1049 intentId = intent.get( 'id', None )
1050 intentStates.append( ( intentId, state ) )
1051 except ( ValueError, TypeError ):
1052 main.log.exception( "Error parsing intents." )
1053 intentStates.sort()
1054 for i, s in intentStates:
1055 count += 1
1056 main.log.info( "%-6s%-15s%-15s" %
1057 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001058 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -07001059 try:
1060 missing = False
1061 if leaders:
1062 parsedLeaders = json.loads( leaders )
1063 main.log.warn( json.dumps( parsedLeaders,
1064 sort_keys=True,
1065 indent=4,
1066 separators=( ',', ': ' ) ) )
1067 # check for all intent partitions
1068 # check for election
1069 topics = []
1070 for i in range( 14 ):
1071 topics.append( "intent-partition-" + str( i ) )
1072 # FIXME: this should only be after we start the app
1073 topics.append( "org.onosproject.election" )
1074 main.log.debug( topics )
1075 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1076 for topic in topics:
1077 if topic not in ONOStopics:
1078 main.log.error( "Error: " + topic +
1079 " not in leaders" )
1080 missing = True
1081 else:
1082 main.log.error( "leaders() returned None" )
1083 except ( ValueError, TypeError ):
1084 main.log.exception( "Error parsing leaders" )
1085 main.log.error( repr( leaders ) )
1086 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001087 for i in main.activeNodes:
1088 node = main.CLIs[i]
1089 response = node.leaders( jsonFormat=False)
1090 main.log.warn( str( node.name ) + " leaders output: \n" +
1091 str( response ) )
1092
1093 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001094 try:
1095 if partitions :
1096 parsedPartitions = json.loads( partitions )
1097 main.log.warn( json.dumps( parsedPartitions,
1098 sort_keys=True,
1099 indent=4,
1100 separators=( ',', ': ' ) ) )
1101 # TODO check for a leader in all paritions
1102 # TODO check for consistency among nodes
1103 else:
1104 main.log.error( "partitions() returned None" )
1105 except ( ValueError, TypeError ):
1106 main.log.exception( "Error parsing partitions" )
1107 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001108 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001109 try:
1110 if pendingMap :
1111 parsedPending = json.loads( pendingMap )
1112 main.log.warn( json.dumps( parsedPending,
1113 sort_keys=True,
1114 indent=4,
1115 separators=( ',', ': ' ) ) )
1116 # TODO check something here?
1117 else:
1118 main.log.error( "pendingMap() returned None" )
1119 except ( ValueError, TypeError ):
1120 main.log.exception( "Error parsing pending map" )
1121 main.log.error( repr( pendingMap ) )
1122 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001123 node = main.activeNodes[0]
1124 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001125 main.step( "Wait a minute then ping again" )
1126 # the wait is above
1127 PingResult = main.TRUE
1128 for i in range( 8, 18 ):
1129 ping = main.Mininet1.pingHost( src="h" + str( i ),
1130 target="h" + str( i + 10 ) )
1131 PingResult = PingResult and ping
1132 if ping == main.FALSE:
1133 main.log.warn( "Ping failed between h" + str( i ) +
1134 " and h" + str( i + 10 ) )
1135 elif ping == main.TRUE:
1136 main.log.info( "Ping test passed!" )
1137 # Don't set PingResult or you'd override failures
1138 if PingResult == main.FALSE:
1139 main.log.error(
1140 "Intents have not been installed correctly, pings failed." )
1141 # TODO: pretty print
1142 main.log.warn( "ONOS1 intents: " )
1143 try:
Jon Halla440e872016-03-31 15:15:50 -07001144 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001145 main.log.warn( json.dumps( json.loads( tmpIntents ),
1146 sort_keys=True,
1147 indent=4,
1148 separators=( ',', ': ' ) ) )
1149 except ( ValueError, TypeError ):
1150 main.log.warn( repr( tmpIntents ) )
1151 utilities.assert_equals(
1152 expect=main.TRUE,
1153 actual=PingResult,
1154 onpass="Intents have been installed correctly and pings work",
1155 onfail="Intents have not been installed correctly, pings failed." )
1156
1157 def CASE5( self, main ):
1158 """
1159 Reading state of ONOS
1160 """
1161 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001162 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001163 assert main, "main not defined"
1164 assert utilities.assert_equals, "utilities.assert_equals not defined"
1165
1166 main.case( "Setting up and gathering data for current state" )
1167 # The general idea for this test case is to pull the state of
1168 # ( intents,flows, topology,... ) from each ONOS node
1169 # We can then compare them with each other and also with past states
1170
1171 main.step( "Check that each switch has a master" )
1172 global mastershipState
1173 mastershipState = '[]'
1174
1175 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001176 rolesNotNull = main.TRUE
1177 threads = []
1178 for i in main.activeNodes:
1179 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1180 name="rolesNotNull-" + str( i ),
1181 args=[] )
1182 threads.append( t )
1183 t.start()
1184
1185 for t in threads:
1186 t.join()
1187 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001188 utilities.assert_equals(
1189 expect=main.TRUE,
1190 actual=rolesNotNull,
1191 onpass="Each device has a master",
1192 onfail="Some devices don't have a master assigned" )
1193
1194 main.step( "Get the Mastership of each switch" )
1195 ONOS1Mastership = main.ONOScli1.roles()
1196 # TODO: Make this a meaningful check
1197 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1198 main.log.error( "Error in getting ONOS roles" )
1199 main.log.warn(
1200 "ONOS1 mastership response: " +
1201 repr( ONOS1Mastership ) )
1202 consistentMastership = main.FALSE
1203 else:
1204 mastershipState = ONOS1Mastership
1205 consistentMastership = main.TRUE
1206
1207 main.step( "Get the intents from each controller" )
1208 global intentState
1209 intentState = []
1210 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1211 intentCheck = main.FALSE
1212 if "Error" in ONOS1Intents or not ONOS1Intents:
1213 main.log.error( "Error in getting ONOS intents" )
1214 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1215 else:
1216 intentCheck = main.TRUE
1217
1218 main.step( "Get the flows from each controller" )
1219 global flowState
1220 flowState = []
1221 flowCheck = main.FALSE
1222 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1223 if "Error" in ONOS1Flows or not ONOS1Flows:
1224 main.log.error( "Error in getting ONOS flows" )
1225 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1226 else:
1227 # TODO: Do a better check, maybe compare flows on switches?
1228 flowState = ONOS1Flows
1229 flowCheck = main.TRUE
1230
1231 main.step( "Get the OF Table entries" )
1232 global flows
1233 flows = []
1234 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001235 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001236 if flowCheck == main.FALSE:
1237 for table in flows:
1238 main.log.warn( table )
1239 # TODO: Compare switch flow tables with ONOS flow tables
1240
1241 main.step( "Collecting topology information from ONOS" )
1242 devices = []
1243 devices.append( main.ONOScli1.devices() )
1244 hosts = []
1245 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1246 ports = []
1247 ports.append( main.ONOScli1.ports() )
1248 links = []
1249 links.append( main.ONOScli1.links() )
1250 clusters = []
1251 clusters.append( main.ONOScli1.clusters() )
1252
1253 main.step( "Each host has an IP address" )
1254 ipResult = main.TRUE
1255 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001256 controllerStr = str( main.activeNodes[controller] + 1 )
1257 if hosts[ controller ]:
1258 for host in hosts[ controller ]:
1259 if not host.get( 'ipAddresses', [ ] ):
1260 main.log.error( "Error with host ips on controller" +
1261 controllerStr + ": " + str( host ) )
1262 ipResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001263 utilities.assert_equals(
1264 expect=main.TRUE,
1265 actual=ipResult,
1266 onpass="The ips of the hosts aren't empty",
1267 onfail="The ip of at least one host is missing" )
1268
1269 # there should always only be one cluster
1270 main.step( "There is only one dataplane cluster" )
1271 try:
1272 numClusters = len( json.loads( clusters[ 0 ] ) )
1273 except ( ValueError, TypeError ):
1274 main.log.exception( "Error parsing clusters[0]: " +
1275 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001276 numClusters = "ERROR"
Jon Hall85794ff2015-07-08 14:12:30 -07001277 clusterResults = main.FALSE
1278 if numClusters == 1:
1279 clusterResults = main.TRUE
1280 utilities.assert_equals(
1281 expect=1,
1282 actual=numClusters,
1283 onpass="ONOS shows 1 SCC",
1284 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1285
1286 main.step( "Comparing ONOS topology to MN" )
1287 devicesResults = main.TRUE
1288 linksResults = main.TRUE
1289 hostsResults = main.TRUE
1290 mnSwitches = main.Mininet1.getSwitches()
1291 mnLinks = main.Mininet1.getLinks()
1292 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001293 for controller in main.activeNodes:
1294 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07001295 if devices[ controller ] and ports[ controller ] and\
1296 "Error" not in devices[ controller ] and\
1297 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001298 currentDevicesResult = main.Mininet1.compareSwitches(
1299 mnSwitches,
1300 json.loads( devices[ controller ] ),
1301 json.loads( ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001302 else:
1303 currentDevicesResult = main.FALSE
1304 utilities.assert_equals( expect=main.TRUE,
1305 actual=currentDevicesResult,
1306 onpass="ONOS" + controllerStr +
1307 " Switches view is correct",
1308 onfail="ONOS" + controllerStr +
1309 " Switches view is incorrect" )
1310 if links[ controller ] and "Error" not in links[ controller ]:
1311 currentLinksResult = main.Mininet1.compareLinks(
1312 mnSwitches, mnLinks,
1313 json.loads( links[ controller ] ) )
1314 else:
1315 currentLinksResult = main.FALSE
1316 utilities.assert_equals( expect=main.TRUE,
1317 actual=currentLinksResult,
1318 onpass="ONOS" + controllerStr +
1319 " links view is correct",
1320 onfail="ONOS" + controllerStr +
1321 " links view is incorrect" )
1322
Jon Halla440e872016-03-31 15:15:50 -07001323 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall85794ff2015-07-08 14:12:30 -07001324 currentHostsResult = main.Mininet1.compareHosts(
1325 mnHosts,
1326 hosts[ controller ] )
1327 else:
1328 currentHostsResult = main.FALSE
1329 utilities.assert_equals( expect=main.TRUE,
1330 actual=currentHostsResult,
1331 onpass="ONOS" + controllerStr +
1332 " hosts exist in Mininet",
1333 onfail="ONOS" + controllerStr +
1334 " hosts don't match Mininet" )
1335
1336 devicesResults = devicesResults and currentDevicesResult
1337 linksResults = linksResults and currentLinksResult
1338 hostsResults = hostsResults and currentHostsResult
1339
1340 main.step( "Device information is correct" )
1341 utilities.assert_equals(
1342 expect=main.TRUE,
1343 actual=devicesResults,
1344 onpass="Device information is correct",
1345 onfail="Device information is incorrect" )
1346
1347 main.step( "Links are correct" )
1348 utilities.assert_equals(
1349 expect=main.TRUE,
1350 actual=linksResults,
1351 onpass="Link are correct",
1352 onfail="Links are incorrect" )
1353
1354 main.step( "Hosts are correct" )
1355 utilities.assert_equals(
1356 expect=main.TRUE,
1357 actual=hostsResults,
1358 onpass="Hosts are correct",
1359 onfail="Hosts are incorrect" )
1360
1361 def CASE6( self, main ):
1362 """
1363 The Failure case.
1364 """
1365 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001366 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001367 assert main, "main not defined"
1368 assert utilities.assert_equals, "utilities.assert_equals not defined"
1369
1370 # Reset non-persistent variables
1371 try:
1372 iCounterValue = 0
1373 except NameError:
1374 main.log.error( "iCounterValue not defined, setting to 0" )
1375 iCounterValue = 0
1376
1377 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001378 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001379 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001380
1381 main.step( "Checking ONOS Logs for errors" )
1382 for node in main.nodes:
1383 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1384 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1385
Jon Hall85794ff2015-07-08 14:12:30 -07001386 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001387 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001388 start = time.time()
1389 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1390 onpass="ONOS Killed",
1391 onfail="Error killing ONOS" )
1392
1393 main.step( "Checking if ONOS is up yet" )
1394 count = 0
1395 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001396 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001397 if onos1Isup == main.TRUE:
1398 elapsed = time.time() - start
1399 break
1400 else:
1401 count = count + 1
1402 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1403 onpass="ONOS is back up",
1404 onfail="ONOS failed to start" )
1405
1406 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001407 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001408 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1409 onpass="ONOS cli startup successful",
1410 onfail="ONOS cli startup failed" )
1411
1412 if elapsed:
1413 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1414 str( elapsed ) )
1415 main.restartTime = elapsed
1416 else:
1417 main.restartTime = -1
1418 time.sleep( 5 )
1419 # rerun on election apps
1420 main.ONOScli1.electionTestRun()
1421
1422 def CASE7( self, main ):
1423 """
1424 Check state after ONOS failure
1425 """
1426 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001427 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001428 assert main, "main not defined"
1429 assert utilities.assert_equals, "utilities.assert_equals not defined"
1430 main.case( "Running ONOS Constant State Tests" )
Jon Hall6e709752016-02-01 13:38:46 -08001431
Jon Hall85794ff2015-07-08 14:12:30 -07001432 main.step( "Check that each switch has a master" )
1433 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001434 rolesNotNull = main.TRUE
1435 threads = []
1436 for i in main.activeNodes:
1437 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1438 name="rolesNotNull-" + str( i ),
1439 args=[ ] )
1440 threads.append( t )
1441 t.start()
1442
1443 for t in threads:
1444 t.join()
1445 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001446 utilities.assert_equals(
1447 expect=main.TRUE,
1448 actual=rolesNotNull,
1449 onpass="Each device has a master",
1450 onfail="Some devices don't have a master assigned" )
1451
1452 main.step( "Check if switch roles are consistent across all nodes" )
1453 ONOS1Mastership = main.ONOScli1.roles()
1454 # FIXME: Refactor this whole case for single instance
1455 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1456 main.log.error( "Error in getting ONOS mastership" )
1457 main.log.warn( "ONOS1 mastership response: " +
1458 repr( ONOS1Mastership ) )
1459 consistentMastership = main.FALSE
1460 else:
1461 consistentMastership = main.TRUE
1462 utilities.assert_equals(
1463 expect=main.TRUE,
1464 actual=consistentMastership,
1465 onpass="Switch roles are consistent across all ONOS nodes",
1466 onfail="ONOS nodes have different views of switch roles" )
1467
1468 description2 = "Compare switch roles from before failure"
1469 main.step( description2 )
1470
1471 currentJson = json.loads( ONOS1Mastership )
1472 oldJson = json.loads( mastershipState )
1473 mastershipCheck = main.TRUE
1474 for i in range( 1, 29 ):
1475 switchDPID = str(
1476 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1477
1478 current = [ switch[ 'master' ] for switch in currentJson
1479 if switchDPID in switch[ 'id' ] ]
1480 old = [ switch[ 'master' ] for switch in oldJson
1481 if switchDPID in switch[ 'id' ] ]
1482 if current == old:
1483 mastershipCheck = mastershipCheck and main.TRUE
1484 else:
1485 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1486 mastershipCheck = main.FALSE
1487 utilities.assert_equals(
1488 expect=main.TRUE,
1489 actual=mastershipCheck,
1490 onpass="Mastership of Switches was not changed",
1491 onfail="Mastership of some switches changed" )
1492 mastershipCheck = mastershipCheck and consistentMastership
1493
1494 main.step( "Get the intents and compare across all nodes" )
1495 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1496 intentCheck = main.FALSE
1497 if "Error" in ONOS1Intents or not ONOS1Intents:
1498 main.log.error( "Error in getting ONOS intents" )
1499 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1500 else:
1501 intentCheck = main.TRUE
1502 utilities.assert_equals(
1503 expect=main.TRUE,
1504 actual=intentCheck,
1505 onpass="Intents are consistent across all ONOS nodes",
1506 onfail="ONOS nodes have different views of intents" )
1507 # Print the intent states
1508 intents = []
1509 intents.append( ONOS1Intents )
1510 intentStates = []
1511 for node in intents: # Iter through ONOS nodes
1512 nodeStates = []
1513 # Iter through intents of a node
1514 for intent in json.loads( node ):
1515 nodeStates.append( intent[ 'state' ] )
1516 intentStates.append( nodeStates )
1517 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1518 main.log.info( dict( out ) )
1519
1520 # NOTE: Store has no durability, so intents are lost across system
1521 # restarts
1522 """
1523 main.step( "Compare current intents with intents before the failure" )
1524 # NOTE: this requires case 5 to pass for intentState to be set.
1525 # maybe we should stop the test if that fails?
1526 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001527 try:
1528 intentState
1529 except NameError:
1530 main.log.warn( "No previous intent state was saved" )
1531 else:
1532 if intentState and intentState == ONOSIntents[ 0 ]:
1533 sameIntents = main.TRUE
1534 main.log.info( "Intents are consistent with before failure" )
1535 # TODO: possibly the states have changed? we may need to figure out
1536 # what the acceptable states are
1537 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1538 sameIntents = main.TRUE
1539 try:
1540 before = json.loads( intentState )
1541 after = json.loads( ONOSIntents[ 0 ] )
1542 for intent in before:
1543 if intent not in after:
1544 sameIntents = main.FALSE
1545 main.log.debug( "Intent is not currently in ONOS " +
1546 "(at least in the same form):" )
1547 main.log.debug( json.dumps( intent ) )
1548 except ( ValueError, TypeError ):
1549 main.log.exception( "Exception printing intents" )
1550 main.log.debug( repr( ONOSIntents[0] ) )
1551 main.log.debug( repr( intentState ) )
1552 if sameIntents == main.FALSE:
1553 try:
1554 main.log.debug( "ONOS intents before: " )
1555 main.log.debug( json.dumps( json.loads( intentState ),
1556 sort_keys=True, indent=4,
1557 separators=( ',', ': ' ) ) )
1558 main.log.debug( "Current ONOS intents: " )
1559 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1560 sort_keys=True, indent=4,
1561 separators=( ',', ': ' ) ) )
1562 except ( ValueError, TypeError ):
1563 main.log.exception( "Exception printing intents" )
1564 main.log.debug( repr( ONOSIntents[0] ) )
1565 main.log.debug( repr( intentState ) )
1566 utilities.assert_equals(
1567 expect=main.TRUE,
1568 actual=sameIntents,
1569 onpass="Intents are consistent with before failure",
1570 onfail="The Intents changed during failure" )
Jon Hall85794ff2015-07-08 14:12:30 -07001571 intentCheck = intentCheck and sameIntents
1572 """
1573 main.step( "Get the OF Table entries and compare to before " +
1574 "component failure" )
1575 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001576 for i in range( 28 ):
1577 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001578 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
Jon Hall41d39f12016-04-11 22:54:35 -07001579 curSwitch = main.Mininet1.flowTableComp( flows[i], tmpFlows )
1580 FlowTables = FlowTables and curSwitch
1581 if curSwitch == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001582 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001583 utilities.assert_equals(
1584 expect=main.TRUE,
1585 actual=FlowTables,
1586 onpass="No changes were found in the flow tables",
1587 onfail="Changes were found in the flow tables" )
1588
1589 main.step( "Leadership Election is still functional" )
1590 # Test of LeadershipElection
1591
Jon Halla440e872016-03-31 15:15:50 -07001592 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001593 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001594 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001595 # loop through ONOScli handlers
1596 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1597 leaderN = node.electionTestLeader()
1598 # verify leader is ONOS1
1599 # NOTE even though we restarted ONOS, it is the only one so onos 1
1600 # must be leader
1601 if leaderN == leader:
1602 # all is well
1603 pass
1604 elif leaderN == main.FALSE:
1605 # error in response
1606 main.log.error( "Something is wrong with " +
1607 "electionTestLeader function, check the" +
1608 " error logs" )
1609 leaderResult = main.FALSE
1610 elif leader != leaderN:
1611 leaderResult = main.FALSE
1612 main.log.error( "ONOS" + str( controller ) + " sees " +
1613 str( leaderN ) +
1614 " as the leader of the election app. " +
1615 "Leader should be " + str( leader ) )
1616 utilities.assert_equals(
1617 expect=main.TRUE,
1618 actual=leaderResult,
1619 onpass="Leadership election passed",
1620 onfail="Something went wrong with Leadership election" )
1621
1622 def CASE8( self, main ):
1623 """
1624 Compare topo
1625 """
1626 import json
1627 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001628 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001629 assert main, "main not defined"
1630 assert utilities.assert_equals, "utilities.assert_equals not defined"
1631
1632 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001633 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001634 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001635 topoResult = main.FALSE
1636 elapsed = 0
1637 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001638 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001639 startTime = time.time()
1640 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001641 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001642 devicesResults = main.TRUE
1643 linksResults = main.TRUE
1644 hostsResults = main.TRUE
1645 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001646 count += 1
1647 cliStart = time.time()
1648 devices = []
1649 devices.append( main.ONOScli1.devices() )
1650 hosts = []
1651 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1652 ipResult = main.TRUE
1653 for controller in range( 0, len( hosts ) ):
1654 controllerStr = str( controller + 1 )
1655 for host in hosts[ controller ]:
1656 if host is None or host.get( 'ipAddresses', [] ) == []:
1657 main.log.error(
1658 "DEBUG:Error with host ips on controller" +
1659 controllerStr + ": " + str( host ) )
1660 ipResult = main.FALSE
1661 ports = []
1662 ports.append( main.ONOScli1.ports() )
1663 links = []
1664 links.append( main.ONOScli1.links() )
1665 clusters = []
1666 clusters.append( main.ONOScli1.clusters() )
1667
1668 elapsed = time.time() - startTime
1669 cliTime = time.time() - cliStart
1670 print "CLI time: " + str( cliTime )
1671
1672 mnSwitches = main.Mininet1.getSwitches()
1673 mnLinks = main.Mininet1.getLinks()
1674 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001675 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001676 controllerStr = str( controller + 1 )
1677 if devices[ controller ] and ports[ controller ] and\
1678 "Error" not in devices[ controller ] and\
1679 "Error" not in ports[ controller ]:
1680
Jon Hallc6793552016-01-19 14:18:37 -08001681 try:
1682 currentDevicesResult = main.Mininet1.compareSwitches(
1683 mnSwitches,
1684 json.loads( devices[ controller ] ),
1685 json.loads( ports[ controller ] ) )
1686 except ( TypeError, ValueError ) as e:
1687 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
1688 devices[ controller ], ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001689 else:
1690 currentDevicesResult = main.FALSE
1691 utilities.assert_equals( expect=main.TRUE,
1692 actual=currentDevicesResult,
1693 onpass="ONOS" + controllerStr +
1694 " Switches view is correct",
1695 onfail="ONOS" + controllerStr +
1696 " Switches view is incorrect" )
1697
1698 if links[ controller ] and "Error" not in links[ controller ]:
1699 currentLinksResult = main.Mininet1.compareLinks(
1700 mnSwitches, mnLinks,
1701 json.loads( links[ controller ] ) )
1702 else:
1703 currentLinksResult = main.FALSE
1704 utilities.assert_equals( expect=main.TRUE,
1705 actual=currentLinksResult,
1706 onpass="ONOS" + controllerStr +
1707 " links view is correct",
1708 onfail="ONOS" + controllerStr +
1709 " links view is incorrect" )
1710
1711 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1712 currentHostsResult = main.Mininet1.compareHosts(
1713 mnHosts,
1714 hosts[ controller ] )
1715 else:
1716 currentHostsResult = main.FALSE
1717 utilities.assert_equals( expect=main.TRUE,
1718 actual=currentHostsResult,
1719 onpass="ONOS" + controllerStr +
1720 " hosts exist in Mininet",
1721 onfail="ONOS" + controllerStr +
1722 " hosts don't match Mininet" )
1723 # CHECKING HOST ATTACHMENT POINTS
1724 hostAttachment = True
1725 zeroHosts = False
1726 # FIXME: topo-HA/obelisk specific mappings:
1727 # key is mac and value is dpid
1728 mappings = {}
1729 for i in range( 1, 29 ): # hosts 1 through 28
1730 # set up correct variables:
1731 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1732 if i == 1:
1733 deviceId = "1000".zfill(16)
1734 elif i == 2:
1735 deviceId = "2000".zfill(16)
1736 elif i == 3:
1737 deviceId = "3000".zfill(16)
1738 elif i == 4:
1739 deviceId = "3004".zfill(16)
1740 elif i == 5:
1741 deviceId = "5000".zfill(16)
1742 elif i == 6:
1743 deviceId = "6000".zfill(16)
1744 elif i == 7:
1745 deviceId = "6007".zfill(16)
1746 elif i >= 8 and i <= 17:
1747 dpid = '3' + str( i ).zfill( 3 )
1748 deviceId = dpid.zfill(16)
1749 elif i >= 18 and i <= 27:
1750 dpid = '6' + str( i ).zfill( 3 )
1751 deviceId = dpid.zfill(16)
1752 elif i == 28:
1753 deviceId = "2800".zfill(16)
1754 mappings[ macId ] = deviceId
1755 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1756 if hosts[ controller ] == []:
1757 main.log.warn( "There are no hosts discovered" )
1758 zeroHosts = True
1759 else:
1760 for host in hosts[ controller ]:
1761 mac = None
1762 location = None
1763 device = None
1764 port = None
1765 try:
1766 mac = host.get( 'mac' )
1767 assert mac, "mac field could not be found for this host object"
1768
1769 location = host.get( 'location' )
1770 assert location, "location field could not be found for this host object"
1771
1772 # Trim the protocol identifier off deviceId
1773 device = str( location.get( 'elementId' ) ).split(':')[1]
1774 assert device, "elementId field could not be found for this host location object"
1775
1776 port = location.get( 'port' )
1777 assert port, "port field could not be found for this host location object"
1778
1779 # Now check if this matches where they should be
1780 if mac and device and port:
1781 if str( port ) != "1":
1782 main.log.error( "The attachment port is incorrect for " +
1783 "host " + str( mac ) +
1784 ". Expected: 1 Actual: " + str( port) )
1785 hostAttachment = False
1786 if device != mappings[ str( mac ) ]:
1787 main.log.error( "The attachment device is incorrect for " +
1788 "host " + str( mac ) +
1789 ". Expected: " + mappings[ str( mac ) ] +
1790 " Actual: " + device )
1791 hostAttachment = False
1792 else:
1793 hostAttachment = False
1794 except AssertionError:
1795 main.log.exception( "Json object not as expected" )
1796 main.log.error( repr( host ) )
1797 hostAttachment = False
1798 else:
1799 main.log.error( "No hosts json output or \"Error\"" +
1800 " in output. hosts = " +
1801 repr( hosts[ controller ] ) )
1802 if zeroHosts is False:
1803 hostAttachment = True
1804
Jon Hall85794ff2015-07-08 14:12:30 -07001805 devicesResults = devicesResults and currentDevicesResult
1806 linksResults = linksResults and currentLinksResult
1807 hostsResults = hostsResults and currentHostsResult
1808 hostAttachmentResults = hostAttachmentResults and\
1809 hostAttachment
1810
Jon Halla440e872016-03-31 15:15:50 -07001811 # "consistent" results don't make sense for single instance
Jon Hall85794ff2015-07-08 14:12:30 -07001812 # there should always only be one cluster
Jon Hall85794ff2015-07-08 14:12:30 -07001813 clusterResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001814 try:
1815 numClusters = len( json.loads( clusters[ 0 ] ) )
1816 except ( ValueError, TypeError ):
1817 main.log.exception( "Error parsing clusters[0]: " +
1818 repr( clusters[0] ) )
1819 numClusters = "ERROR"
1820 clusterResults = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001821 if numClusters == 1:
1822 clusterResults = main.TRUE
1823 utilities.assert_equals(
1824 expect=1,
1825 actual=numClusters,
1826 onpass="ONOS shows 1 SCC",
1827 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1828
1829 topoResult = ( devicesResults and linksResults
1830 and hostsResults and ipResult and clusterResults and
1831 hostAttachmentResults )
1832
1833 topoResult = topoResult and int( count <= 2 )
1834 note = "note it takes about " + str( int( cliTime ) ) + \
1835 " seconds for the test to make all the cli calls to fetch " +\
1836 "the topology from each ONOS instance"
1837 main.log.info(
1838 "Very crass estimate for topology discovery/convergence( " +
1839 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1840 str( count ) + " tries" )
1841 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1842 onpass="Topology Check Test successful",
1843 onfail="Topology Check Test NOT successful" )
Jon Hall41d39f12016-04-11 22:54:35 -07001844 main.step( "Checking ONOS nodes" )
1845 nodeResults = utilities.retry( main.HA.nodesCheck,
1846 False,
1847 args=[main.activeNodes],
1848 attempts=5 )
1849
1850 utilities.assert_equals( expect=True, actual=nodeResults,
1851 onpass="Nodes check successful",
1852 onfail="Nodes check NOT successful" )
1853 if not nodeResults:
1854 for i in main.activeNodes:
1855 main.log.debug( "{} components not ACTIVE: \n{}".format(
1856 main.CLIs[i].name,
1857 main.CLIs[i].sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001858
1859 def CASE9( self, main ):
1860 """
1861 Link s3-s28 down
1862 """
1863 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001864 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001865 assert main, "main not defined"
1866 assert utilities.assert_equals, "utilities.assert_equals not defined"
1867 # NOTE: You should probably run a topology check after this
1868
1869 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1870
1871 description = "Turn off a link to ensure that Link Discovery " +\
1872 "is working properly"
1873 main.case( description )
1874
1875 main.step( "Kill Link between s3 and s28" )
1876 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1877 main.log.info( "Waiting " + str( linkSleep ) +
1878 " seconds for link down to be discovered" )
1879 time.sleep( linkSleep )
1880 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1881 onpass="Link down successful",
1882 onfail="Failed to bring link down" )
1883 # TODO do some sort of check here
1884
1885 def CASE10( self, main ):
1886 """
1887 Link s3-s28 up
1888 """
1889 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001890 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001891 assert main, "main not defined"
1892 assert utilities.assert_equals, "utilities.assert_equals not defined"
1893 # NOTE: You should probably run a topology check after this
1894
1895 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1896
1897 description = "Restore a link to ensure that Link Discovery is " + \
1898 "working properly"
1899 main.case( description )
1900
1901 main.step( "Bring link between s3 and s28 back up" )
1902 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1903 main.log.info( "Waiting " + str( linkSleep ) +
1904 " seconds for link up to be discovered" )
1905 time.sleep( linkSleep )
1906 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1907 onpass="Link up successful",
1908 onfail="Failed to bring link up" )
1909 # TODO do some sort of check here
1910
1911 def CASE11( self, main ):
1912 """
1913 Switch Down
1914 """
1915 # NOTE: You should probably run a topology check after this
1916 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001917 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001918 assert main, "main not defined"
1919 assert utilities.assert_equals, "utilities.assert_equals not defined"
1920
1921 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1922
1923 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07001924 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001925 main.case( description )
1926 switch = main.params[ 'kill' ][ 'switch' ]
1927 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1928
1929 # TODO: Make this switch parameterizable
1930 main.step( "Kill " + switch )
1931 main.log.info( "Deleting " + switch )
1932 main.Mininet1.delSwitch( switch )
1933 main.log.info( "Waiting " + str( switchSleep ) +
1934 " seconds for switch down to be discovered" )
1935 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001936 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001937 # Peek at the deleted switch
1938 main.log.warn( str( device ) )
1939 result = main.FALSE
1940 if device and device[ 'available' ] is False:
1941 result = main.TRUE
1942 utilities.assert_equals( expect=main.TRUE, actual=result,
1943 onpass="Kill switch successful",
1944 onfail="Failed to kill switch?" )
1945
1946 def CASE12( self, main ):
1947 """
1948 Switch Up
1949 """
1950 # NOTE: You should probably run a topology check after this
1951 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001952 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001953 assert main, "main not defined"
1954 assert utilities.assert_equals, "utilities.assert_equals not defined"
1955
1956 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1957 switch = main.params[ 'kill' ][ 'switch' ]
1958 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1959 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07001960 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001961 description = "Adding a switch to ensure it is discovered correctly"
1962 main.case( description )
1963
1964 main.step( "Add back " + switch )
1965 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1966 for peer in links:
1967 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07001968 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall85794ff2015-07-08 14:12:30 -07001969 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1970 main.log.info( "Waiting " + str( switchSleep ) +
1971 " seconds for switch up to be discovered" )
1972 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001973 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001974 # Peek at the deleted switch
1975 main.log.warn( str( device ) )
1976 result = main.FALSE
1977 if device and device[ 'available' ]:
1978 result = main.TRUE
1979 utilities.assert_equals( expect=main.TRUE, actual=result,
1980 onpass="add switch successful",
1981 onfail="Failed to add switch?" )
1982
1983 def CASE13( self, main ):
1984 """
1985 Clean up
1986 """
1987 import os
1988 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001989 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001990 assert main, "main not defined"
1991 assert utilities.assert_equals, "utilities.assert_equals not defined"
1992 # printing colors to terminal
1993 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1994 'blue': '\033[94m', 'green': '\033[92m',
1995 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1996 main.case( "Test Cleanup" )
1997 main.step( "Killing tcpdumps" )
1998 main.Mininet2.stopTcpdump()
1999
2000 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002001 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07002002 main.step( "Copying MN pcap and ONOS log files to test station" )
2003 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2004 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002005 # NOTE: MN Pcap file is being saved to logdir.
2006 # We scp this file as MN and TestON aren't necessarily the same vm
2007
2008 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07002009 # TODO: Load these from params
2010 # NOTE: must end in /
2011 logFolder = "/opt/onos/log/"
2012 logFiles = [ "karaf.log", "karaf.log.1" ]
2013 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002014 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002015 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002016 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002017 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2018 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07002019 # std*.log's
2020 # NOTE: must end in /
2021 logFolder = "/opt/onos/var/"
2022 logFiles = [ "stderr.log", "stdout.log" ]
2023 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002024 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002025 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002026 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002027 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2028 logFolder + f, dstName )
2029 else:
2030 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07002031
Jon Hall85794ff2015-07-08 14:12:30 -07002032 main.step( "Stopping Mininet" )
2033 mnResult = main.Mininet1.stopNet()
2034 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2035 onpass="Mininet stopped",
2036 onfail="MN cleanup NOT successful" )
2037
2038 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07002039 for node in main.nodes:
2040 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2041 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07002042
2043 try:
2044 timerLog = open( main.logdir + "/Timers.csv", 'w')
2045 # Overwrite with empty line and close
2046 labels = "Gossip Intents, Restart"
2047 data = str( gossipTime ) + ", " + str( main.restartTime )
2048 timerLog.write( labels + "\n" + data )
2049 timerLog.close()
2050 except NameError, e:
2051 main.log.exception(e)
2052
2053 def CASE14( self, main ):
2054 """
2055 start election app on all onos nodes
2056 """
Jon Halle1a3b752015-07-22 13:02:46 -07002057 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002058 assert main, "main not defined"
2059 assert utilities.assert_equals, "utilities.assert_equals not defined"
2060
2061 main.case("Start Leadership Election app")
2062 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002063 onosCli = main.CLIs[ main.activeNodes[0] ]
2064 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002065 utilities.assert_equals(
2066 expect=main.TRUE,
2067 actual=appResult,
2068 onpass="Election app installed",
2069 onfail="Something went wrong with installing Leadership election" )
2070
2071 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002072 for i in main.activeNodes:
2073 main.CLIs[i].electionTestRun()
Jon Hall25463a82016-04-13 14:03:52 -07002074 time.sleep(5)
2075 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2076 sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall85794ff2015-07-08 14:12:30 -07002077 utilities.assert_equals(
Jon Hall25463a82016-04-13 14:03:52 -07002078 expect=True,
2079 actual=sameResult,
2080 onpass="All nodes see the same leaderboards",
2081 onfail="Inconsistent leaderboards" )
2082
2083 if sameResult:
2084 leader = leaders[ 0 ][ 0 ]
2085 if main.nodes[main.activeNodes[0]].ip_address in leader:
2086 correctLeader = True
2087 else:
2088 correctLeader = False
2089 main.step( "First node was elected leader" )
2090 utilities.assert_equals(
2091 expect=True,
2092 actual=correctLeader,
2093 onpass="Correct leader was elected",
2094 onfail="Incorrect leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002095
2096 def CASE15( self, main ):
2097 """
2098 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002099 15.1 Run election on each node
2100 15.2 Check that each node has the same leaders and candidates
2101 15.3 Find current leader and withdraw
2102 15.4 Check that a new node was elected leader
2103 15.5 Check that that new leader was the candidate of old leader
2104 15.6 Run for election on old leader
2105 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2106 15.8 Make sure that the old leader was added to the candidate list
2107
2108 old and new variable prefixes refer to data from before vs after
2109 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07002110 """
acsmars71adceb2015-08-31 15:09:26 -07002111 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002112 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002113 assert main, "main not defined"
2114 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07002115 assert main.CLIs, "main.CLIs not defined"
2116 assert main.nodes, "main.nodes not defined"
2117
Jon Hall85794ff2015-07-08 14:12:30 -07002118 description = "Check that Leadership Election is still functional"
2119 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002120 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars2c2fcdd2015-08-25 17:14:13 -07002121
Jon Halla440e872016-03-31 15:15:50 -07002122 oldLeaders = [] # list of lists of each nodes' candidates before
2123 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002124 oldLeader = '' # the old leader from oldLeaders, None if not same
2125 newLeader = '' # the new leaders fron newLoeaders, None if not same
2126 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2127 expectNoLeader = False # True when there is only one leader
2128 if main.numCtrls == 1:
2129 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07002130
acsmars71adceb2015-08-31 15:09:26 -07002131 main.step( "Run for election on each node" )
2132 electionResult = main.TRUE
2133
Jon Halla440e872016-03-31 15:15:50 -07002134 for i in main.activeNodes: # run test election on each node
2135 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002136 electionResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002137 utilities.assert_equals(
2138 expect=main.TRUE,
2139 actual=electionResult,
2140 onpass="All nodes successfully ran for leadership",
2141 onfail="At least one node failed to run for leadership" )
2142
acsmars3a72bde2015-09-02 14:16:22 -07002143 if electionResult == main.FALSE:
2144 main.log.error(
2145 "Skipping Test Case because Election Test App isn't loaded" )
2146 main.skipCase()
2147
acsmars71adceb2015-08-31 15:09:26 -07002148 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002149 failMessage = "Nodes have different leaderboards"
Jon Halla440e872016-03-31 15:15:50 -07002150 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
Jon Hall41d39f12016-04-11 22:54:35 -07002151 sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Halla440e872016-03-31 15:15:50 -07002152 if sameResult:
2153 oldLeader = oldLeaders[ 0 ][ 0 ]
2154 main.log.warn( oldLeader )
Jon Hall85794ff2015-07-08 14:12:30 -07002155 else:
Jon Halla440e872016-03-31 15:15:50 -07002156 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002157 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002158 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002159 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002160 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002161 onfail=failMessage )
2162
2163 main.step( "Find current leader and withdraw" )
2164 withdrawResult = main.TRUE
2165 # do some sanity checking on leader before using it
2166 if oldLeader is None:
2167 main.log.error( "Leadership isn't consistent." )
2168 withdrawResult = main.FALSE
2169 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002170 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002171 if oldLeader == main.nodes[ i ].ip_address:
2172 oldLeaderCLI = main.CLIs[ i ]
2173 break
2174 else: # FOR/ELSE statement
2175 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002176 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002177 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07002178 utilities.assert_equals(
2179 expect=main.TRUE,
2180 actual=withdrawResult,
2181 onpass="Node was withdrawn from election",
2182 onfail="Node was not withdrawn from election" )
2183
acsmars71adceb2015-08-31 15:09:26 -07002184 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002185 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002186 # Get new leaders and candidates
Jon Hall41d39f12016-04-11 22:54:35 -07002187 newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall3a7843a2016-04-12 03:01:09 -07002188 newLeader = None
Jon Halla440e872016-03-31 15:15:50 -07002189 if newLeaderResult:
Jon Hall3a7843a2016-04-12 03:01:09 -07002190 if newLeaders[ 0 ][ 0 ] == 'none':
2191 main.log.error( "No leader was elected on at least 1 node" )
2192 if not expectNoLeader:
2193 newLeaderResult = False
Jon Hall25463a82016-04-13 14:03:52 -07002194 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002195
2196 # Check that the new leader is not the older leader, which was withdrawn
2197 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002198 newLeaderResult = False
2199 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07002200 " as the current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002201 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002202 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002203 actual=newLeaderResult,
2204 onpass="Leadership election passed",
2205 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002206
Jon Halla440e872016-03-31 15:15:50 -07002207 main.step( "Check that that new leader was the candidate of old leader" )
2208 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002209 correctCandidateResult = main.TRUE
2210 if expectNoLeader:
2211 if newLeader == 'none':
2212 main.log.info( "No leader expected. None found. Pass" )
2213 correctCandidateResult = main.TRUE
2214 else:
2215 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2216 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002217 elif len( oldLeaders[0] ) >= 3:
2218 if newLeader == oldLeaders[ 0 ][ 2 ]:
2219 # correct leader was elected
2220 correctCandidateResult = main.TRUE
2221 else:
2222 correctCandidateResult = main.FALSE
2223 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
2224 newLeader, oldLeaders[ 0 ][ 2 ] ) )
2225 else:
2226 main.log.warn( "Could not determine who should be the correct leader" )
2227 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07002228 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002229 utilities.assert_equals(
2230 expect=main.TRUE,
2231 actual=correctCandidateResult,
2232 onpass="Correct Candidate Elected",
2233 onfail="Incorrect Candidate Elected" )
2234
Jon Hall85794ff2015-07-08 14:12:30 -07002235 main.step( "Run for election on old leader( just so everyone " +
2236 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002237 if oldLeaderCLI is not None:
2238 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002239 else:
acsmars71adceb2015-08-31 15:09:26 -07002240 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002241 runResult = main.FALSE
2242 utilities.assert_equals(
2243 expect=main.TRUE,
2244 actual=runResult,
2245 onpass="App re-ran for election",
2246 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07002247
acsmars71adceb2015-08-31 15:09:26 -07002248 main.step(
2249 "Check that oldLeader is a candidate, and leader if only 1 node" )
2250 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07002251 # Get new leaders and candidates
2252 reRunLeaders = []
2253 time.sleep( 5 ) # Paremterize
Jon Hall41d39f12016-04-11 22:54:35 -07002254 positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07002255
2256 # Check that the re-elected node is last on the candidate List
Jon Hall3a7843a2016-04-12 03:01:09 -07002257 if not reRunLeaders[0]:
2258 positionResult = main.FALSE
2259 elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07002260 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
2261 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07002262 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002263 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002264 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002265 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002266 onpass="Old leader successfully re-ran for election",
2267 onfail="Something went wrong with Leadership election after " +
2268 "the old leader re-ran for election" )
2269
2270 def CASE16( self, main ):
2271 """
2272 Install Distributed Primitives app
2273 """
Jon Halla440e872016-03-31 15:15:50 -07002274 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002275 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002276 assert main, "main not defined"
2277 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002278 assert main.CLIs, "main.CLIs not defined"
2279 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002280
2281 # Variables for the distributed primitives tests
2282 global pCounterName
Jon Hall85794ff2015-07-08 14:12:30 -07002283 global pCounterValue
Jon Hall85794ff2015-07-08 14:12:30 -07002284 global onosSet
2285 global onosSetName
2286 pCounterName = "TestON-Partitions"
Jon Hall85794ff2015-07-08 14:12:30 -07002287 pCounterValue = 0
Jon Hall85794ff2015-07-08 14:12:30 -07002288 onosSet = set([])
2289 onosSetName = "TestON-set"
2290
2291 description = "Install Primitives app"
2292 main.case( description )
2293 main.step( "Install Primitives app" )
2294 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07002295 node = main.activeNodes[0]
2296 appResults = main.CLIs[node].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002297 utilities.assert_equals( expect=main.TRUE,
2298 actual=appResults,
2299 onpass="Primitives app activated",
2300 onfail="Primitives app not activated" )
Jon Halla440e872016-03-31 15:15:50 -07002301 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall85794ff2015-07-08 14:12:30 -07002302
2303 def CASE17( self, main ):
2304 """
2305 Check for basic functionality with distributed primitives
2306 """
Jon Hall85794ff2015-07-08 14:12:30 -07002307 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002308 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002309 assert main, "main not defined"
2310 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002311 assert main.CLIs, "main.CLIs not defined"
2312 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002313 assert pCounterName, "pCounterName not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002314 assert onosSetName, "onosSetName not defined"
2315 # NOTE: assert fails if value is 0/None/Empty/False
2316 try:
2317 pCounterValue
2318 except NameError:
2319 main.log.error( "pCounterValue not defined, setting to 0" )
2320 pCounterValue = 0
2321 try:
Jon Hall85794ff2015-07-08 14:12:30 -07002322 onosSet
2323 except NameError:
2324 main.log.error( "onosSet not defined, setting to empty Set" )
2325 onosSet = set([])
2326 # Variables for the distributed primitives tests. These are local only
2327 addValue = "a"
2328 addAllValue = "a b c d e f"
2329 retainValue = "c d e f"
2330
2331 description = "Check for basic functionality with distributed " +\
2332 "primitives"
2333 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002334 main.caseExplanation = "Test the methods of the distributed " +\
2335 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002336 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002337 # Partitioned counters
2338 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002339 pCounters = []
2340 threads = []
2341 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002342 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002343 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2344 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002345 args=[ pCounterName ] )
2346 pCounterValue += 1
2347 addedPValues.append( pCounterValue )
2348 threads.append( t )
2349 t.start()
2350
2351 for t in threads:
2352 t.join()
2353 pCounters.append( t.result )
2354 # Check that counter incremented numController times
2355 pCounterResults = True
2356 for i in addedPValues:
2357 tmpResult = i in pCounters
2358 pCounterResults = pCounterResults and tmpResult
2359 if not tmpResult:
2360 main.log.error( str( i ) + " is not in partitioned "
2361 "counter incremented results" )
2362 utilities.assert_equals( expect=True,
2363 actual=pCounterResults,
2364 onpass="Default counter incremented",
2365 onfail="Error incrementing default" +
2366 " counter" )
2367
Jon Halle1a3b752015-07-22 13:02:46 -07002368 main.step( "Get then Increment a default counter on each node" )
2369 pCounters = []
2370 threads = []
2371 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002372 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002373 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2374 name="counterGetAndAdd-" + str( i ),
2375 args=[ pCounterName ] )
2376 addedPValues.append( pCounterValue )
2377 pCounterValue += 1
2378 threads.append( t )
2379 t.start()
2380
2381 for t in threads:
2382 t.join()
2383 pCounters.append( t.result )
2384 # Check that counter incremented numController times
2385 pCounterResults = True
2386 for i in addedPValues:
2387 tmpResult = i in pCounters
2388 pCounterResults = pCounterResults and tmpResult
2389 if not tmpResult:
2390 main.log.error( str( i ) + " is not in partitioned "
2391 "counter incremented results" )
2392 utilities.assert_equals( expect=True,
2393 actual=pCounterResults,
2394 onpass="Default counter incremented",
2395 onfail="Error incrementing default" +
2396 " counter" )
2397
2398 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07002399 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07002400 utilities.assert_equals( expect=main.TRUE,
2401 actual=incrementCheck,
2402 onpass="Added counters are correct",
2403 onfail="Added counters are incorrect" )
2404
2405 main.step( "Add -8 to then get a default counter on each node" )
2406 pCounters = []
2407 threads = []
2408 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002409 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002410 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2411 name="counterIncrement-" + str( i ),
2412 args=[ pCounterName ],
2413 kwargs={ "delta": -8 } )
2414 pCounterValue += -8
2415 addedPValues.append( pCounterValue )
2416 threads.append( t )
2417 t.start()
2418
2419 for t in threads:
2420 t.join()
2421 pCounters.append( t.result )
2422 # Check that counter incremented numController times
2423 pCounterResults = True
2424 for i in addedPValues:
2425 tmpResult = i in pCounters
2426 pCounterResults = pCounterResults and tmpResult
2427 if not tmpResult:
2428 main.log.error( str( i ) + " is not in partitioned "
2429 "counter incremented results" )
2430 utilities.assert_equals( expect=True,
2431 actual=pCounterResults,
2432 onpass="Default counter incremented",
2433 onfail="Error incrementing default" +
2434 " counter" )
2435
2436 main.step( "Add 5 to then get a default counter on each node" )
2437 pCounters = []
2438 threads = []
2439 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002440 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002441 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2442 name="counterIncrement-" + str( i ),
2443 args=[ pCounterName ],
2444 kwargs={ "delta": 5 } )
2445 pCounterValue += 5
2446 addedPValues.append( pCounterValue )
2447 threads.append( t )
2448 t.start()
2449
2450 for t in threads:
2451 t.join()
2452 pCounters.append( t.result )
2453 # Check that counter incremented numController times
2454 pCounterResults = True
2455 for i in addedPValues:
2456 tmpResult = i in pCounters
2457 pCounterResults = pCounterResults and tmpResult
2458 if not tmpResult:
2459 main.log.error( str( i ) + " is not in partitioned "
2460 "counter incremented results" )
2461 utilities.assert_equals( expect=True,
2462 actual=pCounterResults,
2463 onpass="Default counter incremented",
2464 onfail="Error incrementing default" +
2465 " counter" )
2466
2467 main.step( "Get then add 5 to a default counter on each node" )
2468 pCounters = []
2469 threads = []
2470 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002471 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002472 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2473 name="counterIncrement-" + str( i ),
2474 args=[ pCounterName ],
2475 kwargs={ "delta": 5 } )
2476 addedPValues.append( pCounterValue )
2477 pCounterValue += 5
2478 threads.append( t )
2479 t.start()
2480
2481 for t in threads:
2482 t.join()
2483 pCounters.append( t.result )
2484 # Check that counter incremented numController times
2485 pCounterResults = True
2486 for i in addedPValues:
2487 tmpResult = i in pCounters
2488 pCounterResults = pCounterResults and tmpResult
2489 if not tmpResult:
2490 main.log.error( str( i ) + " is not in partitioned "
2491 "counter incremented results" )
2492 utilities.assert_equals( expect=True,
2493 actual=pCounterResults,
2494 onpass="Default counter incremented",
2495 onfail="Error incrementing default" +
2496 " counter" )
2497
2498 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07002499 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07002500 utilities.assert_equals( expect=main.TRUE,
2501 actual=incrementCheck,
2502 onpass="Added counters are correct",
2503 onfail="Added counters are incorrect" )
2504
Jon Hall85794ff2015-07-08 14:12:30 -07002505 # DISTRIBUTED SETS
2506 main.step( "Distributed Set get" )
2507 size = len( onosSet )
2508 getResponses = []
2509 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002510 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002511 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002512 name="setTestGet-" + str( i ),
2513 args=[ onosSetName ] )
2514 threads.append( t )
2515 t.start()
2516 for t in threads:
2517 t.join()
2518 getResponses.append( t.result )
2519
2520 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002521 for i in range( len( main.activeNodes ) ):
2522 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002523 if isinstance( getResponses[ i ], list):
2524 current = set( getResponses[ i ] )
2525 if len( current ) == len( getResponses[ i ] ):
2526 # no repeats
2527 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002528 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002529 " has incorrect view" +
2530 " of set " + onosSetName + ":\n" +
2531 str( getResponses[ i ] ) )
2532 main.log.debug( "Expected: " + str( onosSet ) )
2533 main.log.debug( "Actual: " + str( current ) )
2534 getResults = main.FALSE
2535 else:
2536 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002537 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002538 " has repeat elements in" +
2539 " set " + onosSetName + ":\n" +
2540 str( getResponses[ i ] ) )
2541 getResults = main.FALSE
2542 elif getResponses[ i ] == main.ERROR:
2543 getResults = main.FALSE
2544 utilities.assert_equals( expect=main.TRUE,
2545 actual=getResults,
2546 onpass="Set elements are correct",
2547 onfail="Set elements are incorrect" )
2548
2549 main.step( "Distributed Set size" )
2550 sizeResponses = []
2551 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002552 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002553 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002554 name="setTestSize-" + str( i ),
2555 args=[ onosSetName ] )
2556 threads.append( t )
2557 t.start()
2558 for t in threads:
2559 t.join()
2560 sizeResponses.append( t.result )
2561
2562 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002563 for i in range( len( main.activeNodes ) ):
2564 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002565 if size != sizeResponses[ i ]:
2566 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002567 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002568 " expected a size of " + str( size ) +
2569 " for set " + onosSetName +
2570 " but got " + str( sizeResponses[ i ] ) )
2571 utilities.assert_equals( expect=main.TRUE,
2572 actual=sizeResults,
2573 onpass="Set sizes are correct",
2574 onfail="Set sizes are incorrect" )
2575
2576 main.step( "Distributed Set add()" )
2577 onosSet.add( addValue )
2578 addResponses = []
2579 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002580 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002581 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002582 name="setTestAdd-" + str( i ),
2583 args=[ onosSetName, addValue ] )
2584 threads.append( t )
2585 t.start()
2586 for t in threads:
2587 t.join()
2588 addResponses.append( t.result )
2589
2590 # main.TRUE = successfully changed the set
2591 # main.FALSE = action resulted in no change in set
2592 # main.ERROR - Some error in executing the function
2593 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002594 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002595 if addResponses[ i ] == main.TRUE:
2596 # All is well
2597 pass
2598 elif addResponses[ i ] == main.FALSE:
2599 # Already in set, probably fine
2600 pass
2601 elif addResponses[ i ] == main.ERROR:
2602 # Error in execution
2603 addResults = main.FALSE
2604 else:
2605 # unexpected result
2606 addResults = main.FALSE
2607 if addResults != main.TRUE:
2608 main.log.error( "Error executing set add" )
2609
2610 # Check if set is still correct
2611 size = len( onosSet )
2612 getResponses = []
2613 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002614 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002615 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002616 name="setTestGet-" + str( i ),
2617 args=[ onosSetName ] )
2618 threads.append( t )
2619 t.start()
2620 for t in threads:
2621 t.join()
2622 getResponses.append( t.result )
2623 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002624 for i in range( len( main.activeNodes ) ):
2625 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002626 if isinstance( getResponses[ i ], list):
2627 current = set( getResponses[ i ] )
2628 if len( current ) == len( getResponses[ i ] ):
2629 # no repeats
2630 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002631 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall85794ff2015-07-08 14:12:30 -07002632 " of set " + onosSetName + ":\n" +
2633 str( getResponses[ i ] ) )
2634 main.log.debug( "Expected: " + str( onosSet ) )
2635 main.log.debug( "Actual: " + str( current ) )
2636 getResults = main.FALSE
2637 else:
2638 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002639 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall85794ff2015-07-08 14:12:30 -07002640 " set " + onosSetName + ":\n" +
2641 str( getResponses[ i ] ) )
2642 getResults = main.FALSE
2643 elif getResponses[ i ] == main.ERROR:
2644 getResults = main.FALSE
2645 sizeResponses = []
2646 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002647 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002648 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002649 name="setTestSize-" + str( i ),
2650 args=[ onosSetName ] )
2651 threads.append( t )
2652 t.start()
2653 for t in threads:
2654 t.join()
2655 sizeResponses.append( t.result )
2656 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002657 for i in range( len( main.activeNodes ) ):
2658 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002659 if size != sizeResponses[ i ]:
2660 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002661 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002662 " expected a size of " + str( size ) +
2663 " for set " + onosSetName +
2664 " but got " + str( sizeResponses[ i ] ) )
2665 addResults = addResults and getResults and sizeResults
2666 utilities.assert_equals( expect=main.TRUE,
2667 actual=addResults,
2668 onpass="Set add correct",
2669 onfail="Set add was incorrect" )
2670
2671 main.step( "Distributed Set addAll()" )
2672 onosSet.update( addAllValue.split() )
2673 addResponses = []
2674 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002675 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002676 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002677 name="setTestAddAll-" + str( i ),
2678 args=[ onosSetName, addAllValue ] )
2679 threads.append( t )
2680 t.start()
2681 for t in threads:
2682 t.join()
2683 addResponses.append( t.result )
2684
2685 # main.TRUE = successfully changed the set
2686 # main.FALSE = action resulted in no change in set
2687 # main.ERROR - Some error in executing the function
2688 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002689 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002690 if addResponses[ i ] == main.TRUE:
2691 # All is well
2692 pass
2693 elif addResponses[ i ] == main.FALSE:
2694 # Already in set, probably fine
2695 pass
2696 elif addResponses[ i ] == main.ERROR:
2697 # Error in execution
2698 addAllResults = main.FALSE
2699 else:
2700 # unexpected result
2701 addAllResults = main.FALSE
2702 if addAllResults != main.TRUE:
2703 main.log.error( "Error executing set addAll" )
2704
2705 # Check if set is still correct
2706 size = len( onosSet )
2707 getResponses = []
2708 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002709 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002710 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002711 name="setTestGet-" + str( i ),
2712 args=[ onosSetName ] )
2713 threads.append( t )
2714 t.start()
2715 for t in threads:
2716 t.join()
2717 getResponses.append( t.result )
2718 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002719 for i in range( len( main.activeNodes ) ):
2720 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002721 if isinstance( getResponses[ i ], list):
2722 current = set( getResponses[ i ] )
2723 if len( current ) == len( getResponses[ i ] ):
2724 # no repeats
2725 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002726 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002727 " has incorrect view" +
2728 " of set " + onosSetName + ":\n" +
2729 str( getResponses[ i ] ) )
2730 main.log.debug( "Expected: " + str( onosSet ) )
2731 main.log.debug( "Actual: " + str( current ) )
2732 getResults = main.FALSE
2733 else:
2734 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002735 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002736 " has repeat elements in" +
2737 " set " + onosSetName + ":\n" +
2738 str( getResponses[ i ] ) )
2739 getResults = main.FALSE
2740 elif getResponses[ i ] == main.ERROR:
2741 getResults = main.FALSE
2742 sizeResponses = []
2743 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002744 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002745 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002746 name="setTestSize-" + str( i ),
2747 args=[ onosSetName ] )
2748 threads.append( t )
2749 t.start()
2750 for t in threads:
2751 t.join()
2752 sizeResponses.append( t.result )
2753 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002754 for i in range( len( main.activeNodes ) ):
2755 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002756 if size != sizeResponses[ i ]:
2757 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002758 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002759 " expected a size of " + str( size ) +
2760 " for set " + onosSetName +
2761 " but got " + str( sizeResponses[ i ] ) )
2762 addAllResults = addAllResults and getResults and sizeResults
2763 utilities.assert_equals( expect=main.TRUE,
2764 actual=addAllResults,
2765 onpass="Set addAll correct",
2766 onfail="Set addAll was incorrect" )
2767
2768 main.step( "Distributed Set contains()" )
2769 containsResponses = []
2770 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002771 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002772 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002773 name="setContains-" + str( i ),
2774 args=[ onosSetName ],
2775 kwargs={ "values": addValue } )
2776 threads.append( t )
2777 t.start()
2778 for t in threads:
2779 t.join()
2780 # NOTE: This is the tuple
2781 containsResponses.append( t.result )
2782
2783 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002784 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002785 if containsResponses[ i ] == main.ERROR:
2786 containsResults = main.FALSE
2787 else:
2788 containsResults = containsResults and\
2789 containsResponses[ i ][ 1 ]
2790 utilities.assert_equals( expect=main.TRUE,
2791 actual=containsResults,
2792 onpass="Set contains is functional",
2793 onfail="Set contains failed" )
2794
2795 main.step( "Distributed Set containsAll()" )
2796 containsAllResponses = []
2797 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002798 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002799 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002800 name="setContainsAll-" + str( i ),
2801 args=[ onosSetName ],
2802 kwargs={ "values": addAllValue } )
2803 threads.append( t )
2804 t.start()
2805 for t in threads:
2806 t.join()
2807 # NOTE: This is the tuple
2808 containsAllResponses.append( t.result )
2809
2810 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002811 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002812 if containsResponses[ i ] == main.ERROR:
2813 containsResults = main.FALSE
2814 else:
2815 containsResults = containsResults and\
2816 containsResponses[ i ][ 1 ]
2817 utilities.assert_equals( expect=main.TRUE,
2818 actual=containsAllResults,
2819 onpass="Set containsAll is functional",
2820 onfail="Set containsAll failed" )
2821
2822 main.step( "Distributed Set remove()" )
2823 onosSet.remove( addValue )
2824 removeResponses = []
2825 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002826 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002827 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002828 name="setTestRemove-" + str( i ),
2829 args=[ onosSetName, addValue ] )
2830 threads.append( t )
2831 t.start()
2832 for t in threads:
2833 t.join()
2834 removeResponses.append( t.result )
2835
2836 # main.TRUE = successfully changed the set
2837 # main.FALSE = action resulted in no change in set
2838 # main.ERROR - Some error in executing the function
2839 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002840 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002841 if removeResponses[ i ] == main.TRUE:
2842 # All is well
2843 pass
2844 elif removeResponses[ i ] == main.FALSE:
2845 # not in set, probably fine
2846 pass
2847 elif removeResponses[ i ] == main.ERROR:
2848 # Error in execution
2849 removeResults = main.FALSE
2850 else:
2851 # unexpected result
2852 removeResults = main.FALSE
2853 if removeResults != main.TRUE:
2854 main.log.error( "Error executing set remove" )
2855
2856 # Check if set is still correct
2857 size = len( onosSet )
2858 getResponses = []
2859 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002860 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002861 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002862 name="setTestGet-" + str( i ),
2863 args=[ onosSetName ] )
2864 threads.append( t )
2865 t.start()
2866 for t in threads:
2867 t.join()
2868 getResponses.append( t.result )
2869 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002870 for i in range( len( main.activeNodes ) ):
2871 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002872 if isinstance( getResponses[ i ], list):
2873 current = set( getResponses[ i ] )
2874 if len( current ) == len( getResponses[ i ] ):
2875 # no repeats
2876 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002877 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002878 " has incorrect view" +
2879 " of set " + onosSetName + ":\n" +
2880 str( getResponses[ i ] ) )
2881 main.log.debug( "Expected: " + str( onosSet ) )
2882 main.log.debug( "Actual: " + str( current ) )
2883 getResults = main.FALSE
2884 else:
2885 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002886 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002887 " has repeat elements in" +
2888 " set " + onosSetName + ":\n" +
2889 str( getResponses[ i ] ) )
2890 getResults = main.FALSE
2891 elif getResponses[ i ] == main.ERROR:
2892 getResults = main.FALSE
2893 sizeResponses = []
2894 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002895 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002896 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002897 name="setTestSize-" + str( i ),
2898 args=[ onosSetName ] )
2899 threads.append( t )
2900 t.start()
2901 for t in threads:
2902 t.join()
2903 sizeResponses.append( t.result )
2904 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002905 for i in range( len( main.activeNodes ) ):
2906 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002907 if size != sizeResponses[ i ]:
2908 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002909 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002910 " expected a size of " + str( size ) +
2911 " for set " + onosSetName +
2912 " but got " + str( sizeResponses[ i ] ) )
2913 removeResults = removeResults and getResults and sizeResults
2914 utilities.assert_equals( expect=main.TRUE,
2915 actual=removeResults,
2916 onpass="Set remove correct",
2917 onfail="Set remove was incorrect" )
2918
2919 main.step( "Distributed Set removeAll()" )
2920 onosSet.difference_update( addAllValue.split() )
2921 removeAllResponses = []
2922 threads = []
2923 try:
Jon Halla440e872016-03-31 15:15:50 -07002924 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002925 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002926 name="setTestRemoveAll-" + str( i ),
2927 args=[ onosSetName, addAllValue ] )
2928 threads.append( t )
2929 t.start()
2930 for t in threads:
2931 t.join()
2932 removeAllResponses.append( t.result )
2933 except Exception, e:
2934 main.log.exception(e)
2935
2936 # main.TRUE = successfully changed the set
2937 # main.FALSE = action resulted in no change in set
2938 # main.ERROR - Some error in executing the function
2939 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002940 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002941 if removeAllResponses[ i ] == main.TRUE:
2942 # All is well
2943 pass
2944 elif removeAllResponses[ i ] == main.FALSE:
2945 # not in set, probably fine
2946 pass
2947 elif removeAllResponses[ i ] == main.ERROR:
2948 # Error in execution
2949 removeAllResults = main.FALSE
2950 else:
2951 # unexpected result
2952 removeAllResults = main.FALSE
2953 if removeAllResults != main.TRUE:
2954 main.log.error( "Error executing set removeAll" )
2955
2956 # Check if set is still correct
2957 size = len( onosSet )
2958 getResponses = []
2959 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002960 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002961 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002962 name="setTestGet-" + str( i ),
2963 args=[ onosSetName ] )
2964 threads.append( t )
2965 t.start()
2966 for t in threads:
2967 t.join()
2968 getResponses.append( t.result )
2969 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002970 for i in range( len( main.activeNodes ) ):
2971 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002972 if isinstance( getResponses[ i ], list):
2973 current = set( getResponses[ i ] )
2974 if len( current ) == len( getResponses[ i ] ):
2975 # no repeats
2976 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002977 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002978 " has incorrect view" +
2979 " of set " + onosSetName + ":\n" +
2980 str( getResponses[ i ] ) )
2981 main.log.debug( "Expected: " + str( onosSet ) )
2982 main.log.debug( "Actual: " + str( current ) )
2983 getResults = main.FALSE
2984 else:
2985 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002986 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002987 " has repeat elements in" +
2988 " set " + onosSetName + ":\n" +
2989 str( getResponses[ i ] ) )
2990 getResults = main.FALSE
2991 elif getResponses[ i ] == main.ERROR:
2992 getResults = main.FALSE
2993 sizeResponses = []
2994 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002995 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002996 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002997 name="setTestSize-" + str( i ),
2998 args=[ onosSetName ] )
2999 threads.append( t )
3000 t.start()
3001 for t in threads:
3002 t.join()
3003 sizeResponses.append( t.result )
3004 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003005 for i in range( len( main.activeNodes ) ):
3006 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003007 if size != sizeResponses[ i ]:
3008 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003009 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003010 " expected a size of " + str( size ) +
3011 " for set " + onosSetName +
3012 " but got " + str( sizeResponses[ i ] ) )
3013 removeAllResults = removeAllResults and getResults and sizeResults
3014 utilities.assert_equals( expect=main.TRUE,
3015 actual=removeAllResults,
3016 onpass="Set removeAll correct",
3017 onfail="Set removeAll was incorrect" )
3018
3019 main.step( "Distributed Set addAll()" )
3020 onosSet.update( addAllValue.split() )
3021 addResponses = []
3022 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003023 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003024 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003025 name="setTestAddAll-" + str( i ),
3026 args=[ onosSetName, addAllValue ] )
3027 threads.append( t )
3028 t.start()
3029 for t in threads:
3030 t.join()
3031 addResponses.append( t.result )
3032
3033 # main.TRUE = successfully changed the set
3034 # main.FALSE = action resulted in no change in set
3035 # main.ERROR - Some error in executing the function
3036 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003037 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003038 if addResponses[ i ] == main.TRUE:
3039 # All is well
3040 pass
3041 elif addResponses[ i ] == main.FALSE:
3042 # Already in set, probably fine
3043 pass
3044 elif addResponses[ i ] == main.ERROR:
3045 # Error in execution
3046 addAllResults = main.FALSE
3047 else:
3048 # unexpected result
3049 addAllResults = main.FALSE
3050 if addAllResults != main.TRUE:
3051 main.log.error( "Error executing set addAll" )
3052
3053 # Check if set is still correct
3054 size = len( onosSet )
3055 getResponses = []
3056 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003057 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003058 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003059 name="setTestGet-" + str( i ),
3060 args=[ onosSetName ] )
3061 threads.append( t )
3062 t.start()
3063 for t in threads:
3064 t.join()
3065 getResponses.append( t.result )
3066 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003067 for i in range( len( main.activeNodes ) ):
3068 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003069 if isinstance( getResponses[ i ], list):
3070 current = set( getResponses[ i ] )
3071 if len( current ) == len( getResponses[ i ] ):
3072 # no repeats
3073 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003074 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003075 " has incorrect view" +
3076 " of set " + onosSetName + ":\n" +
3077 str( getResponses[ i ] ) )
3078 main.log.debug( "Expected: " + str( onosSet ) )
3079 main.log.debug( "Actual: " + str( current ) )
3080 getResults = main.FALSE
3081 else:
3082 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003083 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003084 " has repeat elements in" +
3085 " set " + onosSetName + ":\n" +
3086 str( getResponses[ i ] ) )
3087 getResults = main.FALSE
3088 elif getResponses[ i ] == main.ERROR:
3089 getResults = main.FALSE
3090 sizeResponses = []
3091 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003092 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003093 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003094 name="setTestSize-" + str( i ),
3095 args=[ onosSetName ] )
3096 threads.append( t )
3097 t.start()
3098 for t in threads:
3099 t.join()
3100 sizeResponses.append( t.result )
3101 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003102 for i in range( len( main.activeNodes ) ):
3103 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003104 if size != sizeResponses[ i ]:
3105 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003106 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003107 " expected a size of " + str( size ) +
3108 " for set " + onosSetName +
3109 " but got " + str( sizeResponses[ i ] ) )
3110 addAllResults = addAllResults and getResults and sizeResults
3111 utilities.assert_equals( expect=main.TRUE,
3112 actual=addAllResults,
3113 onpass="Set addAll correct",
3114 onfail="Set addAll was incorrect" )
3115
3116 main.step( "Distributed Set clear()" )
3117 onosSet.clear()
3118 clearResponses = []
3119 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003120 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003121 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003122 name="setTestClear-" + str( i ),
3123 args=[ onosSetName, " "], # Values doesn't matter
3124 kwargs={ "clear": True } )
3125 threads.append( t )
3126 t.start()
3127 for t in threads:
3128 t.join()
3129 clearResponses.append( t.result )
3130
3131 # main.TRUE = successfully changed the set
3132 # main.FALSE = action resulted in no change in set
3133 # main.ERROR - Some error in executing the function
3134 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003135 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003136 if clearResponses[ i ] == main.TRUE:
3137 # All is well
3138 pass
3139 elif clearResponses[ i ] == main.FALSE:
3140 # Nothing set, probably fine
3141 pass
3142 elif clearResponses[ i ] == main.ERROR:
3143 # Error in execution
3144 clearResults = main.FALSE
3145 else:
3146 # unexpected result
3147 clearResults = main.FALSE
3148 if clearResults != main.TRUE:
3149 main.log.error( "Error executing set clear" )
3150
3151 # Check if set is still correct
3152 size = len( onosSet )
3153 getResponses = []
3154 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003155 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003156 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003157 name="setTestGet-" + str( i ),
3158 args=[ onosSetName ] )
3159 threads.append( t )
3160 t.start()
3161 for t in threads:
3162 t.join()
3163 getResponses.append( t.result )
3164 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003165 for i in range( len( main.activeNodes ) ):
3166 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003167 if isinstance( getResponses[ i ], list):
3168 current = set( getResponses[ i ] )
3169 if len( current ) == len( getResponses[ i ] ):
3170 # no repeats
3171 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003172 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003173 " has incorrect view" +
3174 " of set " + onosSetName + ":\n" +
3175 str( getResponses[ i ] ) )
3176 main.log.debug( "Expected: " + str( onosSet ) )
3177 main.log.debug( "Actual: " + str( current ) )
3178 getResults = main.FALSE
3179 else:
3180 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003181 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003182 " has repeat elements in" +
3183 " set " + onosSetName + ":\n" +
3184 str( getResponses[ i ] ) )
3185 getResults = main.FALSE
3186 elif getResponses[ i ] == main.ERROR:
3187 getResults = main.FALSE
3188 sizeResponses = []
3189 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003190 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003191 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003192 name="setTestSize-" + str( i ),
3193 args=[ onosSetName ] )
3194 threads.append( t )
3195 t.start()
3196 for t in threads:
3197 t.join()
3198 sizeResponses.append( t.result )
3199 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003200 for i in range( len( main.activeNodes ) ):
3201 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003202 if size != sizeResponses[ i ]:
3203 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003204 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003205 " expected a size of " + str( size ) +
3206 " for set " + onosSetName +
3207 " but got " + str( sizeResponses[ i ] ) )
3208 clearResults = clearResults and getResults and sizeResults
3209 utilities.assert_equals( expect=main.TRUE,
3210 actual=clearResults,
3211 onpass="Set clear correct",
3212 onfail="Set clear was incorrect" )
3213
3214 main.step( "Distributed Set addAll()" )
3215 onosSet.update( addAllValue.split() )
3216 addResponses = []
3217 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003218 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003219 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003220 name="setTestAddAll-" + str( i ),
3221 args=[ onosSetName, addAllValue ] )
3222 threads.append( t )
3223 t.start()
3224 for t in threads:
3225 t.join()
3226 addResponses.append( t.result )
3227
3228 # main.TRUE = successfully changed the set
3229 # main.FALSE = action resulted in no change in set
3230 # main.ERROR - Some error in executing the function
3231 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003232 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003233 if addResponses[ i ] == main.TRUE:
3234 # All is well
3235 pass
3236 elif addResponses[ i ] == main.FALSE:
3237 # Already in set, probably fine
3238 pass
3239 elif addResponses[ i ] == main.ERROR:
3240 # Error in execution
3241 addAllResults = main.FALSE
3242 else:
3243 # unexpected result
3244 addAllResults = main.FALSE
3245 if addAllResults != main.TRUE:
3246 main.log.error( "Error executing set addAll" )
3247
3248 # Check if set is still correct
3249 size = len( onosSet )
3250 getResponses = []
3251 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003252 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003253 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003254 name="setTestGet-" + str( i ),
3255 args=[ onosSetName ] )
3256 threads.append( t )
3257 t.start()
3258 for t in threads:
3259 t.join()
3260 getResponses.append( t.result )
3261 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003262 for i in range( len( main.activeNodes ) ):
3263 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003264 if isinstance( getResponses[ i ], list):
3265 current = set( getResponses[ i ] )
3266 if len( current ) == len( getResponses[ i ] ):
3267 # no repeats
3268 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003269 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003270 " has incorrect view" +
3271 " of set " + onosSetName + ":\n" +
3272 str( getResponses[ i ] ) )
3273 main.log.debug( "Expected: " + str( onosSet ) )
3274 main.log.debug( "Actual: " + str( current ) )
3275 getResults = main.FALSE
3276 else:
3277 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003278 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003279 " has repeat elements in" +
3280 " set " + onosSetName + ":\n" +
3281 str( getResponses[ i ] ) )
3282 getResults = main.FALSE
3283 elif getResponses[ i ] == main.ERROR:
3284 getResults = main.FALSE
3285 sizeResponses = []
3286 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003287 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003288 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003289 name="setTestSize-" + str( i ),
3290 args=[ onosSetName ] )
3291 threads.append( t )
3292 t.start()
3293 for t in threads:
3294 t.join()
3295 sizeResponses.append( t.result )
3296 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003297 for i in range( len( main.activeNodes ) ):
3298 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003299 if size != sizeResponses[ i ]:
3300 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003301 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003302 " expected a size of " + str( size ) +
3303 " for set " + onosSetName +
3304 " but got " + str( sizeResponses[ i ] ) )
3305 addAllResults = addAllResults and getResults and sizeResults
3306 utilities.assert_equals( expect=main.TRUE,
3307 actual=addAllResults,
3308 onpass="Set addAll correct",
3309 onfail="Set addAll was incorrect" )
3310
3311 main.step( "Distributed Set retain()" )
3312 onosSet.intersection_update( retainValue.split() )
3313 retainResponses = []
3314 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003315 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003316 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003317 name="setTestRetain-" + str( i ),
3318 args=[ onosSetName, retainValue ],
3319 kwargs={ "retain": True } )
3320 threads.append( t )
3321 t.start()
3322 for t in threads:
3323 t.join()
3324 retainResponses.append( t.result )
3325
3326 # main.TRUE = successfully changed the set
3327 # main.FALSE = action resulted in no change in set
3328 # main.ERROR - Some error in executing the function
3329 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003330 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003331 if retainResponses[ i ] == main.TRUE:
3332 # All is well
3333 pass
3334 elif retainResponses[ i ] == main.FALSE:
3335 # Already in set, probably fine
3336 pass
3337 elif retainResponses[ i ] == main.ERROR:
3338 # Error in execution
3339 retainResults = main.FALSE
3340 else:
3341 # unexpected result
3342 retainResults = main.FALSE
3343 if retainResults != main.TRUE:
3344 main.log.error( "Error executing set retain" )
3345
3346 # Check if set is still correct
3347 size = len( onosSet )
3348 getResponses = []
3349 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003350 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003351 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003352 name="setTestGet-" + str( i ),
3353 args=[ onosSetName ] )
3354 threads.append( t )
3355 t.start()
3356 for t in threads:
3357 t.join()
3358 getResponses.append( t.result )
3359 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003360 for i in range( len( main.activeNodes ) ):
3361 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003362 if isinstance( getResponses[ i ], list):
3363 current = set( getResponses[ i ] )
3364 if len( current ) == len( getResponses[ i ] ):
3365 # no repeats
3366 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003367 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003368 " has incorrect view" +
3369 " of set " + onosSetName + ":\n" +
3370 str( getResponses[ i ] ) )
3371 main.log.debug( "Expected: " + str( onosSet ) )
3372 main.log.debug( "Actual: " + str( current ) )
3373 getResults = main.FALSE
3374 else:
3375 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003376 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003377 " has repeat elements in" +
3378 " set " + onosSetName + ":\n" +
3379 str( getResponses[ i ] ) )
3380 getResults = main.FALSE
3381 elif getResponses[ i ] == main.ERROR:
3382 getResults = main.FALSE
3383 sizeResponses = []
3384 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003385 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003386 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003387 name="setTestSize-" + str( i ),
3388 args=[ onosSetName ] )
3389 threads.append( t )
3390 t.start()
3391 for t in threads:
3392 t.join()
3393 sizeResponses.append( t.result )
3394 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003395 for i in range( len( main.activeNodes ) ):
3396 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003397 if size != sizeResponses[ i ]:
3398 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003399 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall85794ff2015-07-08 14:12:30 -07003400 str( size ) + " for set " + onosSetName +
3401 " but got " + str( sizeResponses[ i ] ) )
3402 retainResults = retainResults and getResults and sizeResults
3403 utilities.assert_equals( expect=main.TRUE,
3404 actual=retainResults,
3405 onpass="Set retain correct",
3406 onfail="Set retain was incorrect" )
3407
Jon Hall2a5002c2015-08-21 16:49:11 -07003408 # Transactional maps
3409 main.step( "Partitioned Transactional maps put" )
3410 tMapValue = "Testing"
3411 numKeys = 100
3412 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07003413 node = main.activeNodes[0]
3414 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
3415 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07003416 for i in putResponses:
3417 if putResponses[ i ][ 'value' ] != tMapValue:
3418 putResult = False
3419 else:
3420 putResult = False
3421 if not putResult:
3422 main.log.debug( "Put response values: " + str( putResponses ) )
3423 utilities.assert_equals( expect=True,
3424 actual=putResult,
3425 onpass="Partitioned Transactional Map put successful",
3426 onfail="Partitioned Transactional Map put values are incorrect" )
3427
3428 main.step( "Partitioned Transactional maps get" )
3429 getCheck = True
3430 for n in range( 1, numKeys + 1 ):
3431 getResponses = []
3432 threads = []
3433 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07003434 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07003435 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3436 name="TMap-get-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07003437 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07003438 threads.append( t )
3439 t.start()
3440 for t in threads:
3441 t.join()
3442 getResponses.append( t.result )
3443 for node in getResponses:
3444 if node != tMapValue:
3445 valueCheck = False
3446 if not valueCheck:
3447 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3448 main.log.warn( getResponses )
3449 getCheck = getCheck and valueCheck
3450 utilities.assert_equals( expect=True,
3451 actual=getCheck,
3452 onpass="Partitioned Transactional Map get values were correct",
3453 onfail="Partitioned Transactional Map values incorrect" )