blob: ca8a194f90fb23393cd56267f25ea97718433c23 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAminorityRestart:
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 Hall3b489db2015-10-05 14:38:37 -070051 import pexpect
Jon Hall5cf14d52015-07-16 12:15:19 -070052 main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
53 "initialization" )
54 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070055 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070056 "installing ONOS, starting Mininet and ONOS" +\
57 "cli sessions."
58 # TODO: save all the timers and output them for plotting
59
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
71 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79
80 # FIXME: just get controller port from params?
81 # TODO: do we really need all these?
82 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
83 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
84 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
85 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
86 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
87 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
88 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
89
Jon Halle1a3b752015-07-22 13:02:46 -070090 try:
91 fileName = "Counters"
92 # TODO: Maybe make a library folder somewhere?
93 path = main.params[ 'imports' ][ 'path' ]
94 main.Counters = imp.load_source( fileName,
95 path + fileName + ".py" )
96 except Exception as e:
97 main.log.exception( e )
98 main.cleanup()
99 main.exit()
100
101 main.CLIs = []
102 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700103 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700104 for i in range( 1, main.numCtrls + 1 ):
105 try:
106 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
107 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
108 ipList.append( main.nodes[ -1 ].ip_address )
109 except AttributeError:
110 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700111
112 main.step( "Create cell file" )
113 cellAppString = main.params[ 'ENV' ][ 'appString' ]
114 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
115 main.Mininet1.ip_address,
116 cellAppString, ipList )
117 main.step( "Applying cell variable to environment" )
118 cellResult = main.ONOSbench.setCell( cellName )
119 verifyResult = main.ONOSbench.verifyCell()
120
121 # FIXME:this is short term fix
122 main.log.info( "Removing raft logs" )
123 main.ONOSbench.onosRemoveRaftLogs()
124
125 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700126 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700127 main.ONOSbench.onosUninstall( node.ip_address )
128
129 # Make sure ONOS is DEAD
130 main.log.info( "Killing any ONOS processes" )
131 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700132 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700133 killed = main.ONOSbench.onosKill( node.ip_address )
134 killResults = killResults and killed
135
136 cleanInstallResult = main.TRUE
137 gitPullResult = main.TRUE
138
139 main.step( "Starting Mininet" )
140 # scp topo file to mininet
141 # TODO: move to params?
142 topoName = "obelisk.py"
143 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700144 main.ONOSbench.scp( main.Mininet1,
145 filePath + topoName,
146 main.Mininet1.home,
147 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700148 mnResult = main.Mininet1.startNet( )
149 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
150 onpass="Mininet Started",
151 onfail="Error starting Mininet" )
152
153 main.step( "Git checkout and pull " + gitBranch )
154 if PULLCODE:
155 main.ONOSbench.gitCheckout( gitBranch )
156 gitPullResult = main.ONOSbench.gitPull()
157 # values of 1 or 3 are good
158 utilities.assert_lesser( expect=0, actual=gitPullResult,
159 onpass="Git pull successful",
160 onfail="Git pull failed" )
161 main.ONOSbench.getVersion( report=True )
162
163 main.step( "Using mvn clean install" )
164 cleanInstallResult = main.TRUE
165 if PULLCODE and gitPullResult == main.TRUE:
166 cleanInstallResult = main.ONOSbench.cleanInstall()
167 else:
168 main.log.warn( "Did not pull new code so skipping mvn " +
169 "clean install" )
170 utilities.assert_equals( expect=main.TRUE,
171 actual=cleanInstallResult,
172 onpass="MCI successful",
173 onfail="MCI failed" )
174 # GRAPHS
175 # NOTE: important params here:
176 # job = name of Jenkins job
177 # Plot Name = Plot-HA, only can be used if multiple plots
178 # index = The number of the graph under plot name
179 job = "HAminorityRestart"
180 plotName = "Plot-HA"
181 graphs = '<ac:structured-macro ac:name="html">\n'
182 graphs += '<ac:plain-text-body><![CDATA[\n'
183 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
184 '/plot/' + plotName + '/getPlot?index=0' +\
185 '&width=500&height=300"' +\
186 'noborder="0" width="500" height="300" scrolling="yes" ' +\
187 'seamless="seamless"></iframe>\n'
188 graphs += ']]></ac:plain-text-body>\n'
189 graphs += '</ac:structured-macro>\n'
190 main.log.wiki(graphs)
191
192 main.step( "Creating ONOS package" )
Jon Hall3b489db2015-10-05 14:38:37 -0700193 # copy gen-partions file to ONOS
194 # NOTE: this assumes TestON and ONOS are on the same machine
195 srcFile = main.testDir + "/" + main.TEST + "/dependencies/onos-gen-partitions"
196 dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
197 cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
198 main.ONOSbench.ip_address,
199 srcFile,
200 dstDir,
201 pwd=main.ONOSbench.pwd,
202 direction="from" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700203 packageResult = main.ONOSbench.onosPackage()
204 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
205 onpass="ONOS package successful",
206 onfail="ONOS package failed" )
207
208 main.step( "Installing ONOS package" )
209 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700210 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700211 tmpResult = main.ONOSbench.onosInstall( options="-f",
212 node=node.ip_address )
213 onosInstallResult = onosInstallResult and tmpResult
214 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
215 onpass="ONOS install successful",
216 onfail="ONOS install failed" )
Jon Hall3b489db2015-10-05 14:38:37 -0700217 # clean up gen-partitions file
218 try:
219 main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
220 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
221 main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
222 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
223 main.log.info( " Cleaning custom gen partitions file, response was: \n" +
224 str( main.ONOSbench.handle.before ) )
225 except ( pexpect.TIMEOUT, pexpect.EOF ):
226 main.log.exception( "ONOSbench: pexpect exception found:" +
227 main.ONOSbench.handle.before )
228 main.cleanup()
229 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -0700230
231 main.step( "Checking if ONOS is up yet" )
232 for i in range( 2 ):
233 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700234 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700235 started = main.ONOSbench.isup( node.ip_address )
236 if not started:
237 main.log.error( node.name + " didn't start!" )
238 main.ONOSbench.onosStop( node.ip_address )
239 main.ONOSbench.onosStart( node.ip_address )
240 onosIsupResult = onosIsupResult and started
241 if onosIsupResult == main.TRUE:
242 break
243 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
244 onpass="ONOS startup successful",
245 onfail="ONOS startup failed" )
246
247 main.log.step( "Starting ONOS CLI sessions" )
248 cliResults = main.TRUE
249 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700250 for i in range( main.numCtrls ):
251 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700252 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700253 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700254 threads.append( t )
255 t.start()
256
257 for t in threads:
258 t.join()
259 cliResults = cliResults and t.result
260 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
261 onpass="ONOS cli startup successful",
262 onfail="ONOS cli startup failed" )
263
264 if main.params[ 'tcpdump' ].lower() == "true":
265 main.step( "Start Packet Capture MN" )
266 main.Mininet2.startTcpdump(
267 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
268 + "-MN.pcap",
269 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
270 port=main.params[ 'MNtcpdump' ][ 'port' ] )
271
272 main.step( "App Ids check" )
273 appCheck = main.TRUE
274 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700275 for i in range( main.numCtrls ):
276 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700277 name="appToIDCheck-" + str( i ),
278 args=[] )
279 threads.append( t )
280 t.start()
281
282 for t in threads:
283 t.join()
284 appCheck = appCheck and t.result
285 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700286 main.log.warn( main.CLIs[0].apps() )
287 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700288 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
289 onpass="App Ids seem to be correct",
290 onfail="Something is wrong with app Ids" )
291
292 if cliResults == main.FALSE:
293 main.log.error( "Failed to start ONOS, stopping test" )
294 main.cleanup()
295 main.exit()
296
297 def CASE2( self, main ):
298 """
299 Assign devices to controllers
300 """
301 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700302 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700303 assert main, "main not defined"
304 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700305 assert main.CLIs, "main.CLIs not defined"
306 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700307 assert ONOS1Port, "ONOS1Port not defined"
308 assert ONOS2Port, "ONOS2Port not defined"
309 assert ONOS3Port, "ONOS3Port not defined"
310 assert ONOS4Port, "ONOS4Port not defined"
311 assert ONOS5Port, "ONOS5Port not defined"
312 assert ONOS6Port, "ONOS6Port not defined"
313 assert ONOS7Port, "ONOS7Port not defined"
314
315 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700316 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700317 "and check that an ONOS node becomes the " +\
318 "master of the device."
319 main.step( "Assign switches to controllers" )
320
321 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700322 for i in range( main.numCtrls ):
323 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700324 swList = []
325 for i in range( 1, 29 ):
326 swList.append( "s" + str( i ) )
327 main.Mininet1.assignSwController( sw=swList, ip=ipList )
328
329 mastershipCheck = main.TRUE
330 for i in range( 1, 29 ):
331 response = main.Mininet1.getSwController( "s" + str( i ) )
332 try:
333 main.log.info( str( response ) )
334 except Exception:
335 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700336 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700337 if re.search( "tcp:" + node.ip_address, response ):
338 mastershipCheck = mastershipCheck and main.TRUE
339 else:
340 main.log.error( "Error, node " + node.ip_address + " is " +
341 "not in the list of controllers s" +
342 str( i ) + " is connecting to." )
343 mastershipCheck = main.FALSE
344 utilities.assert_equals(
345 expect=main.TRUE,
346 actual=mastershipCheck,
347 onpass="Switch mastership assigned correctly",
348 onfail="Switches not assigned correctly to controllers" )
349
350 def CASE21( self, main ):
351 """
352 Assign mastership to controllers
353 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700354 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700355 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700356 assert main, "main not defined"
357 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700358 assert main.CLIs, "main.CLIs not defined"
359 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700360 assert ONOS1Port, "ONOS1Port not defined"
361 assert ONOS2Port, "ONOS2Port not defined"
362 assert ONOS3Port, "ONOS3Port not defined"
363 assert ONOS4Port, "ONOS4Port not defined"
364 assert ONOS5Port, "ONOS5Port not defined"
365 assert ONOS6Port, "ONOS6Port not defined"
366 assert ONOS7Port, "ONOS7Port not defined"
367
368 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700369 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700370 "device. Then manually assign" +\
371 " mastership to specific ONOS nodes using" +\
372 " 'device-role'"
373 main.step( "Assign mastership of switches to specific controllers" )
374 # Manually assign mastership to the controller we want
375 roleCall = main.TRUE
376
377 ipList = [ ]
378 deviceList = []
379 try:
380 # Assign mastership to specific controllers. This assignment was
381 # determined for a 7 node cluser, but will work with any sized
382 # cluster
383 for i in range( 1, 29 ): # switches 1 through 28
384 # set up correct variables:
385 if i == 1:
386 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700387 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700388 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
389 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700390 c = 1 % main.numCtrls
391 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700392 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
393 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700394 c = 1 % main.numCtrls
395 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700396 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
397 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700398 c = 3 % main.numCtrls
399 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700400 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
401 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700402 c = 2 % main.numCtrls
403 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700404 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
405 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700406 c = 2 % main.numCtrls
407 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700408 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
409 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700410 c = 5 % main.numCtrls
411 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700412 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
413 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700414 c = 4 % main.numCtrls
415 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700416 dpid = '3' + str( i ).zfill( 3 )
417 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
418 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700419 c = 6 % main.numCtrls
420 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700421 dpid = '6' + str( i ).zfill( 3 )
422 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
423 elif i == 28:
424 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700425 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700426 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
427 else:
428 main.log.error( "You didn't write an else statement for " +
429 "switch s" + str( i ) )
430 roleCall = main.FALSE
431 # Assign switch
432 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
433 # TODO: make this controller dynamic
434 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
435 ip )
436 ipList.append( ip )
437 deviceList.append( deviceId )
438 except ( AttributeError, AssertionError ):
439 main.log.exception( "Something is wrong with ONOS device view" )
440 main.log.info( main.ONOScli1.devices() )
441 utilities.assert_equals(
442 expect=main.TRUE,
443 actual=roleCall,
444 onpass="Re-assigned switch mastership to designated controller",
445 onfail="Something wrong with deviceRole calls" )
446
447 main.step( "Check mastership was correctly assigned" )
448 roleCheck = main.TRUE
449 # NOTE: This is due to the fact that device mastership change is not
450 # atomic and is actually a multi step process
451 time.sleep( 5 )
452 for i in range( len( ipList ) ):
453 ip = ipList[i]
454 deviceId = deviceList[i]
455 # Check assignment
456 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
457 if ip in master:
458 roleCheck = roleCheck and main.TRUE
459 else:
460 roleCheck = roleCheck and main.FALSE
461 main.log.error( "Error, controller " + ip + " is not" +
462 " master " + "of device " +
463 str( deviceId ) + ". Master is " +
464 repr( master ) + "." )
465 utilities.assert_equals(
466 expect=main.TRUE,
467 actual=roleCheck,
468 onpass="Switches were successfully reassigned to designated " +
469 "controller",
470 onfail="Switches were not successfully reassigned" )
471
472 def CASE3( self, main ):
473 """
474 Assign intents
475 """
476 import time
477 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700478 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700479 assert main, "main not defined"
480 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700481 assert main.CLIs, "main.CLIs not defined"
482 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700483 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700484 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700485 "assign predetermined host-to-host intents." +\
486 " After installation, check that the intent" +\
487 " is distributed to all nodes and the state" +\
488 " is INSTALLED"
489
490 # install onos-app-fwd
491 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700492 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700493 utilities.assert_equals( expect=main.TRUE, actual=installResults,
494 onpass="Install fwd successful",
495 onfail="Install fwd failed" )
496
497 main.step( "Check app ids" )
498 appCheck = main.TRUE
499 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700500 for i in range( main.numCtrls ):
501 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700502 name="appToIDCheck-" + str( i ),
503 args=[] )
504 threads.append( t )
505 t.start()
506
507 for t in threads:
508 t.join()
509 appCheck = appCheck and t.result
510 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700511 main.log.warn( main.CLIs[0].apps() )
512 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700513 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
514 onpass="App Ids seem to be correct",
515 onfail="Something is wrong with app Ids" )
516
517 main.step( "Discovering Hosts( Via pingall for now )" )
518 # FIXME: Once we have a host discovery mechanism, use that instead
519 # REACTIVE FWD test
520 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700521 passMsg = "Reactive Pingall test passed"
522 time1 = time.time()
523 pingResult = main.Mininet1.pingall()
524 time2 = time.time()
525 if not pingResult:
526 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700527 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700528 passMsg += " on the second try"
529 utilities.assert_equals(
530 expect=main.TRUE,
531 actual=pingResult,
532 onpass= passMsg,
533 onfail="Reactive Pingall failed, " +
534 "one or more ping pairs failed" )
535 main.log.info( "Time for pingall: %2f seconds" %
536 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700537 # timeout for fwd flows
538 time.sleep( 11 )
539 # uninstall onos-app-fwd
540 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700541 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700542 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
543 onpass="Uninstall fwd successful",
544 onfail="Uninstall fwd failed" )
545
546 main.step( "Check app ids" )
547 threads = []
548 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700549 for i in range( main.numCtrls ):
550 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700551 name="appToIDCheck-" + str( i ),
552 args=[] )
553 threads.append( t )
554 t.start()
555
556 for t in threads:
557 t.join()
558 appCheck2 = appCheck2 and t.result
559 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700560 main.log.warn( main.CLIs[0].apps() )
561 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700562 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
563 onpass="App Ids seem to be correct",
564 onfail="Something is wrong with app Ids" )
565
566 main.step( "Add host intents via cli" )
567 intentIds = []
568 # TODO: move the host numbers to params
569 # Maybe look at all the paths we ping?
570 intentAddResult = True
571 hostResult = main.TRUE
572 for i in range( 8, 18 ):
573 main.log.info( "Adding host intent between h" + str( i ) +
574 " and h" + str( i + 10 ) )
575 host1 = "00:00:00:00:00:" + \
576 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
577 host2 = "00:00:00:00:00:" + \
578 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
579 # NOTE: getHost can return None
580 host1Dict = main.ONOScli1.getHost( host1 )
581 host2Dict = main.ONOScli1.getHost( host2 )
582 host1Id = None
583 host2Id = None
584 if host1Dict and host2Dict:
585 host1Id = host1Dict.get( 'id', None )
586 host2Id = host2Dict.get( 'id', None )
587 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700588 nodeNum = ( i % main.numCtrls )
589 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700590 if tmpId:
591 main.log.info( "Added intent with id: " + tmpId )
592 intentIds.append( tmpId )
593 else:
594 main.log.error( "addHostIntent returned: " +
595 repr( tmpId ) )
596 else:
597 main.log.error( "Error, getHost() failed for h" + str( i ) +
598 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700599 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700600 main.log.warn( "Hosts output: " )
601 try:
602 main.log.warn( json.dumps( json.loads( hosts ),
603 sort_keys=True,
604 indent=4,
605 separators=( ',', ': ' ) ) )
606 except ( ValueError, TypeError ):
607 main.log.warn( repr( hosts ) )
608 hostResult = main.FALSE
609 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
610 onpass="Found a host id for each host",
611 onfail="Error looking up host ids" )
612
613 intentStart = time.time()
614 onosIds = main.ONOScli1.getAllIntentsId()
615 main.log.info( "Submitted intents: " + str( intentIds ) )
616 main.log.info( "Intents in ONOS: " + str( onosIds ) )
617 for intent in intentIds:
618 if intent in onosIds:
619 pass # intent submitted is in onos
620 else:
621 intentAddResult = False
622 if intentAddResult:
623 intentStop = time.time()
624 else:
625 intentStop = None
626 # Print the intent states
627 intents = main.ONOScli1.intents()
628 intentStates = []
629 installedCheck = True
630 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
631 count = 0
632 try:
633 for intent in json.loads( intents ):
634 state = intent.get( 'state', None )
635 if "INSTALLED" not in state:
636 installedCheck = False
637 intentId = intent.get( 'id', None )
638 intentStates.append( ( intentId, state ) )
639 except ( ValueError, TypeError ):
640 main.log.exception( "Error parsing intents" )
641 # add submitted intents not in the store
642 tmplist = [ i for i, s in intentStates ]
643 missingIntents = False
644 for i in intentIds:
645 if i not in tmplist:
646 intentStates.append( ( i, " - " ) )
647 missingIntents = True
648 intentStates.sort()
649 for i, s in intentStates:
650 count += 1
651 main.log.info( "%-6s%-15s%-15s" %
652 ( str( count ), str( i ), str( s ) ) )
653 leaders = main.ONOScli1.leaders()
654 try:
655 missing = False
656 if leaders:
657 parsedLeaders = json.loads( leaders )
658 main.log.warn( json.dumps( parsedLeaders,
659 sort_keys=True,
660 indent=4,
661 separators=( ',', ': ' ) ) )
662 # check for all intent partitions
663 topics = []
664 for i in range( 14 ):
665 topics.append( "intent-partition-" + str( i ) )
666 main.log.debug( topics )
667 ONOStopics = [ j['topic'] for j in parsedLeaders ]
668 for topic in topics:
669 if topic not in ONOStopics:
670 main.log.error( "Error: " + topic +
671 " not in leaders" )
672 missing = True
673 else:
674 main.log.error( "leaders() returned None" )
675 except ( ValueError, TypeError ):
676 main.log.exception( "Error parsing leaders" )
677 main.log.error( repr( leaders ) )
678 # Check all nodes
679 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700680 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700681 response = node.leaders( jsonFormat=False)
682 main.log.warn( str( node.name ) + " leaders output: \n" +
683 str( response ) )
684
685 partitions = main.ONOScli1.partitions()
686 try:
687 if partitions :
688 parsedPartitions = json.loads( partitions )
689 main.log.warn( json.dumps( parsedPartitions,
690 sort_keys=True,
691 indent=4,
692 separators=( ',', ': ' ) ) )
693 # TODO check for a leader in all paritions
694 # TODO check for consistency among nodes
695 else:
696 main.log.error( "partitions() returned None" )
697 except ( ValueError, TypeError ):
698 main.log.exception( "Error parsing partitions" )
699 main.log.error( repr( partitions ) )
700 pendingMap = main.ONOScli1.pendingMap()
701 try:
702 if pendingMap :
703 parsedPending = json.loads( pendingMap )
704 main.log.warn( json.dumps( parsedPending,
705 sort_keys=True,
706 indent=4,
707 separators=( ',', ': ' ) ) )
708 # TODO check something here?
709 else:
710 main.log.error( "pendingMap() returned None" )
711 except ( ValueError, TypeError ):
712 main.log.exception( "Error parsing pending map" )
713 main.log.error( repr( pendingMap ) )
714
715 intentAddResult = bool( intentAddResult and not missingIntents and
716 installedCheck )
717 if not intentAddResult:
718 main.log.error( "Error in pushing host intents to ONOS" )
719
720 main.step( "Intent Anti-Entropy dispersion" )
721 for i in range(100):
722 correct = True
723 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700724 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700725 onosIds = []
726 ids = cli.getAllIntentsId()
727 onosIds.append( ids )
728 main.log.debug( "Intents in " + cli.name + ": " +
729 str( sorted( onosIds ) ) )
730 if sorted( ids ) != sorted( intentIds ):
731 main.log.warn( "Set of intent IDs doesn't match" )
732 correct = False
733 break
734 else:
735 intents = json.loads( cli.intents() )
736 for intent in intents:
737 if intent[ 'state' ] != "INSTALLED":
738 main.log.warn( "Intent " + intent[ 'id' ] +
739 " is " + intent[ 'state' ] )
740 correct = False
741 break
742 if correct:
743 break
744 else:
745 time.sleep(1)
746 if not intentStop:
747 intentStop = time.time()
748 global gossipTime
749 gossipTime = intentStop - intentStart
750 main.log.info( "It took about " + str( gossipTime ) +
751 " seconds for all intents to appear in each node" )
752 # FIXME: make this time configurable/calculate based off of number of
753 # nodes and gossip rounds
754 utilities.assert_greater_equals(
755 expect=40, actual=gossipTime,
756 onpass="ECM anti-entropy for intents worked within " +
757 "expected time",
758 onfail="Intent ECM anti-entropy took too long" )
759 if gossipTime <= 40:
760 intentAddResult = True
761
762 if not intentAddResult or "key" in pendingMap:
763 import time
764 installedCheck = True
765 main.log.info( "Sleeping 60 seconds to see if intents are found" )
766 time.sleep( 60 )
767 onosIds = main.ONOScli1.getAllIntentsId()
768 main.log.info( "Submitted intents: " + str( intentIds ) )
769 main.log.info( "Intents in ONOS: " + str( onosIds ) )
770 # Print the intent states
771 intents = main.ONOScli1.intents()
772 intentStates = []
773 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
774 count = 0
775 try:
776 for intent in json.loads( intents ):
777 # Iter through intents of a node
778 state = intent.get( 'state', None )
779 if "INSTALLED" not in state:
780 installedCheck = False
781 intentId = intent.get( 'id', None )
782 intentStates.append( ( intentId, state ) )
783 except ( ValueError, TypeError ):
784 main.log.exception( "Error parsing intents" )
785 # add submitted intents not in the store
786 tmplist = [ i for i, s in intentStates ]
787 for i in intentIds:
788 if i not in tmplist:
789 intentStates.append( ( i, " - " ) )
790 intentStates.sort()
791 for i, s in intentStates:
792 count += 1
793 main.log.info( "%-6s%-15s%-15s" %
794 ( str( count ), str( i ), str( s ) ) )
795 leaders = main.ONOScli1.leaders()
796 try:
797 missing = False
798 if leaders:
799 parsedLeaders = json.loads( leaders )
800 main.log.warn( json.dumps( parsedLeaders,
801 sort_keys=True,
802 indent=4,
803 separators=( ',', ': ' ) ) )
804 # check for all intent partitions
805 # check for election
806 topics = []
807 for i in range( 14 ):
808 topics.append( "intent-partition-" + str( i ) )
809 # FIXME: this should only be after we start the app
810 topics.append( "org.onosproject.election" )
811 main.log.debug( topics )
812 ONOStopics = [ j['topic'] for j in parsedLeaders ]
813 for topic in topics:
814 if topic not in ONOStopics:
815 main.log.error( "Error: " + topic +
816 " not in leaders" )
817 missing = True
818 else:
819 main.log.error( "leaders() returned None" )
820 except ( ValueError, TypeError ):
821 main.log.exception( "Error parsing leaders" )
822 main.log.error( repr( leaders ) )
823 # Check all nodes
824 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700825 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700826 response = node.leaders( jsonFormat=False)
827 main.log.warn( str( node.name ) + " leaders output: \n" +
828 str( response ) )
829
830 partitions = main.ONOScli1.partitions()
831 try:
832 if partitions :
833 parsedPartitions = json.loads( partitions )
834 main.log.warn( json.dumps( parsedPartitions,
835 sort_keys=True,
836 indent=4,
837 separators=( ',', ': ' ) ) )
838 # TODO check for a leader in all paritions
839 # TODO check for consistency among nodes
840 else:
841 main.log.error( "partitions() returned None" )
842 except ( ValueError, TypeError ):
843 main.log.exception( "Error parsing partitions" )
844 main.log.error( repr( partitions ) )
845 pendingMap = main.ONOScli1.pendingMap()
846 try:
847 if pendingMap :
848 parsedPending = json.loads( pendingMap )
849 main.log.warn( json.dumps( parsedPending,
850 sort_keys=True,
851 indent=4,
852 separators=( ',', ': ' ) ) )
853 # TODO check something here?
854 else:
855 main.log.error( "pendingMap() returned None" )
856 except ( ValueError, TypeError ):
857 main.log.exception( "Error parsing pending map" )
858 main.log.error( repr( pendingMap ) )
859
860 def CASE4( self, main ):
861 """
862 Ping across added host intents
863 """
864 import json
865 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700866 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700867 assert main, "main not defined"
868 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700869 assert main.CLIs, "main.CLIs not defined"
870 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700871 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700872 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700873 "functionality and check the state of " +\
874 "the intent"
875 main.step( "Ping across added host intents" )
876 PingResult = main.TRUE
877 for i in range( 8, 18 ):
878 ping = main.Mininet1.pingHost( src="h" + str( i ),
879 target="h" + str( i + 10 ) )
880 PingResult = PingResult and ping
881 if ping == main.FALSE:
882 main.log.warn( "Ping failed between h" + str( i ) +
883 " and h" + str( i + 10 ) )
884 elif ping == main.TRUE:
885 main.log.info( "Ping test passed!" )
886 # Don't set PingResult or you'd override failures
887 if PingResult == main.FALSE:
888 main.log.error(
889 "Intents have not been installed correctly, pings failed." )
890 # TODO: pretty print
891 main.log.warn( "ONOS1 intents: " )
892 try:
893 tmpIntents = main.ONOScli1.intents()
894 main.log.warn( json.dumps( json.loads( tmpIntents ),
895 sort_keys=True,
896 indent=4,
897 separators=( ',', ': ' ) ) )
898 except ( ValueError, TypeError ):
899 main.log.warn( repr( tmpIntents ) )
900 utilities.assert_equals(
901 expect=main.TRUE,
902 actual=PingResult,
903 onpass="Intents have been installed correctly and pings work",
904 onfail="Intents have not been installed correctly, pings failed." )
905
906 main.step( "Check Intent state" )
907 installedCheck = False
908 loopCount = 0
909 while not installedCheck and loopCount < 40:
910 installedCheck = True
911 # Print the intent states
912 intents = main.ONOScli1.intents()
913 intentStates = []
914 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
915 count = 0
916 # Iter through intents of a node
917 try:
918 for intent in json.loads( intents ):
919 state = intent.get( 'state', None )
920 if "INSTALLED" not in state:
921 installedCheck = False
922 intentId = intent.get( 'id', None )
923 intentStates.append( ( intentId, state ) )
924 except ( ValueError, TypeError ):
925 main.log.exception( "Error parsing intents." )
926 # Print states
927 intentStates.sort()
928 for i, s in intentStates:
929 count += 1
930 main.log.info( "%-6s%-15s%-15s" %
931 ( str( count ), str( i ), str( s ) ) )
932 if not installedCheck:
933 time.sleep( 1 )
934 loopCount += 1
935 utilities.assert_equals( expect=True, actual=installedCheck,
936 onpass="Intents are all INSTALLED",
937 onfail="Intents are not all in " +
938 "INSTALLED state" )
939
940 main.step( "Check leadership of topics" )
941 leaders = main.ONOScli1.leaders()
942 topicCheck = main.TRUE
943 try:
944 if leaders:
945 parsedLeaders = json.loads( leaders )
946 main.log.warn( json.dumps( parsedLeaders,
947 sort_keys=True,
948 indent=4,
949 separators=( ',', ': ' ) ) )
950 # check for all intent partitions
951 # check for election
952 # TODO: Look at Devices as topics now that it uses this system
953 topics = []
954 for i in range( 14 ):
955 topics.append( "intent-partition-" + str( i ) )
956 # FIXME: this should only be after we start the app
957 # FIXME: topics.append( "org.onosproject.election" )
958 # Print leaders output
959 main.log.debug( topics )
960 ONOStopics = [ j['topic'] for j in parsedLeaders ]
961 for topic in topics:
962 if topic not in ONOStopics:
963 main.log.error( "Error: " + topic +
964 " not in leaders" )
965 topicCheck = main.FALSE
966 else:
967 main.log.error( "leaders() returned None" )
968 topicCheck = main.FALSE
969 except ( ValueError, TypeError ):
970 topicCheck = main.FALSE
971 main.log.exception( "Error parsing leaders" )
972 main.log.error( repr( leaders ) )
973 # TODO: Check for a leader of these topics
974 # Check all nodes
975 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700976 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700977 response = node.leaders( jsonFormat=False)
978 main.log.warn( str( node.name ) + " leaders output: \n" +
979 str( response ) )
980
981 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
982 onpass="intent Partitions is in leaders",
983 onfail="Some topics were lost " )
984 # Print partitions
985 partitions = main.ONOScli1.partitions()
986 try:
987 if partitions :
988 parsedPartitions = json.loads( partitions )
989 main.log.warn( json.dumps( parsedPartitions,
990 sort_keys=True,
991 indent=4,
992 separators=( ',', ': ' ) ) )
993 # TODO check for a leader in all paritions
994 # TODO check for consistency among nodes
995 else:
996 main.log.error( "partitions() returned None" )
997 except ( ValueError, TypeError ):
998 main.log.exception( "Error parsing partitions" )
999 main.log.error( repr( partitions ) )
1000 # Print Pending Map
1001 pendingMap = main.ONOScli1.pendingMap()
1002 try:
1003 if pendingMap :
1004 parsedPending = json.loads( pendingMap )
1005 main.log.warn( json.dumps( parsedPending,
1006 sort_keys=True,
1007 indent=4,
1008 separators=( ',', ': ' ) ) )
1009 # TODO check something here?
1010 else:
1011 main.log.error( "pendingMap() returned None" )
1012 except ( ValueError, TypeError ):
1013 main.log.exception( "Error parsing pending map" )
1014 main.log.error( repr( pendingMap ) )
1015
1016 if not installedCheck:
1017 main.log.info( "Waiting 60 seconds to see if the state of " +
1018 "intents change" )
1019 time.sleep( 60 )
1020 # Print the intent states
1021 intents = main.ONOScli1.intents()
1022 intentStates = []
1023 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1024 count = 0
1025 # Iter through intents of a node
1026 try:
1027 for intent in json.loads( intents ):
1028 state = intent.get( 'state', None )
1029 if "INSTALLED" not in state:
1030 installedCheck = False
1031 intentId = intent.get( 'id', None )
1032 intentStates.append( ( intentId, state ) )
1033 except ( ValueError, TypeError ):
1034 main.log.exception( "Error parsing intents." )
1035 intentStates.sort()
1036 for i, s in intentStates:
1037 count += 1
1038 main.log.info( "%-6s%-15s%-15s" %
1039 ( str( count ), str( i ), str( s ) ) )
1040 leaders = main.ONOScli1.leaders()
1041 try:
1042 missing = False
1043 if leaders:
1044 parsedLeaders = json.loads( leaders )
1045 main.log.warn( json.dumps( parsedLeaders,
1046 sort_keys=True,
1047 indent=4,
1048 separators=( ',', ': ' ) ) )
1049 # check for all intent partitions
1050 # check for election
1051 topics = []
1052 for i in range( 14 ):
1053 topics.append( "intent-partition-" + str( i ) )
1054 # FIXME: this should only be after we start the app
1055 topics.append( "org.onosproject.election" )
1056 main.log.debug( topics )
1057 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1058 for topic in topics:
1059 if topic not in ONOStopics:
1060 main.log.error( "Error: " + topic +
1061 " not in leaders" )
1062 missing = True
1063 else:
1064 main.log.error( "leaders() returned None" )
1065 except ( ValueError, TypeError ):
1066 main.log.exception( "Error parsing leaders" )
1067 main.log.error( repr( leaders ) )
1068 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001069 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001070 response = node.leaders( jsonFormat=False)
1071 main.log.warn( str( node.name ) + " leaders output: \n" +
1072 str( response ) )
1073
1074 partitions = main.ONOScli1.partitions()
1075 try:
1076 if partitions :
1077 parsedPartitions = json.loads( partitions )
1078 main.log.warn( json.dumps( parsedPartitions,
1079 sort_keys=True,
1080 indent=4,
1081 separators=( ',', ': ' ) ) )
1082 # TODO check for a leader in all paritions
1083 # TODO check for consistency among nodes
1084 else:
1085 main.log.error( "partitions() returned None" )
1086 except ( ValueError, TypeError ):
1087 main.log.exception( "Error parsing partitions" )
1088 main.log.error( repr( partitions ) )
1089 pendingMap = main.ONOScli1.pendingMap()
1090 try:
1091 if pendingMap :
1092 parsedPending = json.loads( pendingMap )
1093 main.log.warn( json.dumps( parsedPending,
1094 sort_keys=True,
1095 indent=4,
1096 separators=( ',', ': ' ) ) )
1097 # TODO check something here?
1098 else:
1099 main.log.error( "pendingMap() returned None" )
1100 except ( ValueError, TypeError ):
1101 main.log.exception( "Error parsing pending map" )
1102 main.log.error( repr( pendingMap ) )
1103 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001104 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001105 main.step( "Wait a minute then ping again" )
1106 # the wait is above
1107 PingResult = main.TRUE
1108 for i in range( 8, 18 ):
1109 ping = main.Mininet1.pingHost( src="h" + str( i ),
1110 target="h" + str( i + 10 ) )
1111 PingResult = PingResult and ping
1112 if ping == main.FALSE:
1113 main.log.warn( "Ping failed between h" + str( i ) +
1114 " and h" + str( i + 10 ) )
1115 elif ping == main.TRUE:
1116 main.log.info( "Ping test passed!" )
1117 # Don't set PingResult or you'd override failures
1118 if PingResult == main.FALSE:
1119 main.log.error(
1120 "Intents have not been installed correctly, pings failed." )
1121 # TODO: pretty print
1122 main.log.warn( "ONOS1 intents: " )
1123 try:
1124 tmpIntents = main.ONOScli1.intents()
1125 main.log.warn( json.dumps( json.loads( tmpIntents ),
1126 sort_keys=True,
1127 indent=4,
1128 separators=( ',', ': ' ) ) )
1129 except ( ValueError, TypeError ):
1130 main.log.warn( repr( tmpIntents ) )
1131 utilities.assert_equals(
1132 expect=main.TRUE,
1133 actual=PingResult,
1134 onpass="Intents have been installed correctly and pings work",
1135 onfail="Intents have not been installed correctly, pings failed." )
1136
1137 def CASE5( self, main ):
1138 """
1139 Reading state of ONOS
1140 """
1141 import json
1142 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001143 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001144 assert main, "main not defined"
1145 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001146 assert main.CLIs, "main.CLIs not defined"
1147 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001148
1149 main.case( "Setting up and gathering data for current state" )
1150 # The general idea for this test case is to pull the state of
1151 # ( intents,flows, topology,... ) from each ONOS node
1152 # We can then compare them with each other and also with past states
1153
1154 main.step( "Check that each switch has a master" )
1155 global mastershipState
1156 mastershipState = '[]'
1157
1158 # Assert that each device has a master
1159 rolesNotNull = main.TRUE
1160 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001161 for i in range( main.numCtrls ):
1162 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001163 name="rolesNotNull-" + str( i ),
1164 args=[] )
1165 threads.append( t )
1166 t.start()
1167
1168 for t in threads:
1169 t.join()
1170 rolesNotNull = rolesNotNull and t.result
1171 utilities.assert_equals(
1172 expect=main.TRUE,
1173 actual=rolesNotNull,
1174 onpass="Each device has a master",
1175 onfail="Some devices don't have a master assigned" )
1176
1177 main.step( "Get the Mastership of each switch from each controller" )
1178 ONOSMastership = []
1179 mastershipCheck = main.FALSE
1180 consistentMastership = True
1181 rolesResults = True
1182 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001183 for i in range( main.numCtrls ):
1184 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001185 name="roles-" + str( i ),
1186 args=[] )
1187 threads.append( t )
1188 t.start()
1189
1190 for t in threads:
1191 t.join()
1192 ONOSMastership.append( t.result )
1193
Jon Halle1a3b752015-07-22 13:02:46 -07001194 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001195 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1196 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1197 " roles" )
1198 main.log.warn(
1199 "ONOS" + str( i + 1 ) + " mastership response: " +
1200 repr( ONOSMastership[i] ) )
1201 rolesResults = False
1202 utilities.assert_equals(
1203 expect=True,
1204 actual=rolesResults,
1205 onpass="No error in reading roles output",
1206 onfail="Error in reading roles from ONOS" )
1207
1208 main.step( "Check for consistency in roles from each controller" )
1209 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1210 main.log.info(
1211 "Switch roles are consistent across all ONOS nodes" )
1212 else:
1213 consistentMastership = False
1214 utilities.assert_equals(
1215 expect=True,
1216 actual=consistentMastership,
1217 onpass="Switch roles are consistent across all ONOS nodes",
1218 onfail="ONOS nodes have different views of switch roles" )
1219
1220 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001221 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001222 try:
1223 main.log.warn(
1224 "ONOS" + str( i + 1 ) + " roles: ",
1225 json.dumps(
1226 json.loads( ONOSMastership[ i ] ),
1227 sort_keys=True,
1228 indent=4,
1229 separators=( ',', ': ' ) ) )
1230 except ( ValueError, TypeError ):
1231 main.log.warn( repr( ONOSMastership[ i ] ) )
1232 elif rolesResults and consistentMastership:
1233 mastershipCheck = main.TRUE
1234 mastershipState = ONOSMastership[ 0 ]
1235
1236 main.step( "Get the intents from each controller" )
1237 global intentState
1238 intentState = []
1239 ONOSIntents = []
1240 intentCheck = main.FALSE
1241 consistentIntents = True
1242 intentsResults = True
1243 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001244 for i in range( main.numCtrls ):
1245 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001246 name="intents-" + str( i ),
1247 args=[],
1248 kwargs={ 'jsonFormat': True } )
1249 threads.append( t )
1250 t.start()
1251
1252 for t in threads:
1253 t.join()
1254 ONOSIntents.append( t.result )
1255
Jon Halle1a3b752015-07-22 13:02:46 -07001256 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001257 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1258 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1259 " intents" )
1260 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1261 repr( ONOSIntents[ i ] ) )
1262 intentsResults = False
1263 utilities.assert_equals(
1264 expect=True,
1265 actual=intentsResults,
1266 onpass="No error in reading intents output",
1267 onfail="Error in reading intents from ONOS" )
1268
1269 main.step( "Check for consistency in Intents from each controller" )
1270 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1271 main.log.info( "Intents are consistent across all ONOS " +
1272 "nodes" )
1273 else:
1274 consistentIntents = False
1275 main.log.error( "Intents not consistent" )
1276 utilities.assert_equals(
1277 expect=True,
1278 actual=consistentIntents,
1279 onpass="Intents are consistent across all ONOS nodes",
1280 onfail="ONOS nodes have different views of intents" )
1281
1282 if intentsResults:
1283 # Try to make it easy to figure out what is happening
1284 #
1285 # Intent ONOS1 ONOS2 ...
1286 # 0x01 INSTALLED INSTALLING
1287 # ... ... ...
1288 # ... ... ...
1289 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001290 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001291 title += " " * 10 + "ONOS" + str( n + 1 )
1292 main.log.warn( title )
1293 # get all intent keys in the cluster
1294 keys = []
1295 for nodeStr in ONOSIntents:
1296 node = json.loads( nodeStr )
1297 for intent in node:
1298 keys.append( intent.get( 'id' ) )
1299 keys = set( keys )
1300 for key in keys:
1301 row = "%-13s" % key
1302 for nodeStr in ONOSIntents:
1303 node = json.loads( nodeStr )
1304 for intent in node:
1305 if intent.get( 'id', "Error" ) == key:
1306 row += "%-15s" % intent.get( 'state' )
1307 main.log.warn( row )
1308 # End table view
1309
1310 if intentsResults and not consistentIntents:
1311 # print the json objects
1312 n = len(ONOSIntents)
1313 main.log.debug( "ONOS" + str( n ) + " intents: " )
1314 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1315 sort_keys=True,
1316 indent=4,
1317 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001318 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001319 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1320 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1321 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1322 sort_keys=True,
1323 indent=4,
1324 separators=( ',', ': ' ) ) )
1325 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001326 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001327 str( n ) + " intents" )
1328 elif intentsResults and consistentIntents:
1329 intentCheck = main.TRUE
1330 intentState = ONOSIntents[ 0 ]
1331
1332 main.step( "Get the flows from each controller" )
1333 global flowState
1334 flowState = []
1335 ONOSFlows = []
1336 ONOSFlowsJson = []
1337 flowCheck = main.FALSE
1338 consistentFlows = True
1339 flowsResults = True
1340 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001341 for i in range( main.numCtrls ):
1342 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001343 name="flows-" + str( i ),
1344 args=[],
1345 kwargs={ 'jsonFormat': True } )
1346 threads.append( t )
1347 t.start()
1348
1349 # NOTE: Flows command can take some time to run
1350 time.sleep(30)
1351 for t in threads:
1352 t.join()
1353 result = t.result
1354 ONOSFlows.append( result )
1355
Jon Halle1a3b752015-07-22 13:02:46 -07001356 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001357 num = str( i + 1 )
1358 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1359 main.log.error( "Error in getting ONOS" + num + " flows" )
1360 main.log.warn( "ONOS" + num + " flows response: " +
1361 repr( ONOSFlows[ i ] ) )
1362 flowsResults = False
1363 ONOSFlowsJson.append( None )
1364 else:
1365 try:
1366 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1367 except ( ValueError, TypeError ):
1368 # FIXME: change this to log.error?
1369 main.log.exception( "Error in parsing ONOS" + num +
1370 " response as json." )
1371 main.log.error( repr( ONOSFlows[ i ] ) )
1372 ONOSFlowsJson.append( None )
1373 flowsResults = False
1374 utilities.assert_equals(
1375 expect=True,
1376 actual=flowsResults,
1377 onpass="No error in reading flows output",
1378 onfail="Error in reading flows from ONOS" )
1379
1380 main.step( "Check for consistency in Flows from each controller" )
1381 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1382 if all( tmp ):
1383 main.log.info( "Flow count is consistent across all ONOS nodes" )
1384 else:
1385 consistentFlows = False
1386 utilities.assert_equals(
1387 expect=True,
1388 actual=consistentFlows,
1389 onpass="The flow count is consistent across all ONOS nodes",
1390 onfail="ONOS nodes have different flow counts" )
1391
1392 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001393 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001394 try:
1395 main.log.warn(
1396 "ONOS" + str( i + 1 ) + " flows: " +
1397 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1398 indent=4, separators=( ',', ': ' ) ) )
1399 except ( ValueError, TypeError ):
1400 main.log.warn(
1401 "ONOS" + str( i + 1 ) + " flows: " +
1402 repr( ONOSFlows[ i ] ) )
1403 elif flowsResults and consistentFlows:
1404 flowCheck = main.TRUE
1405 flowState = ONOSFlows[ 0 ]
1406
1407 main.step( "Get the OF Table entries" )
1408 global flows
1409 flows = []
1410 for i in range( 1, 29 ):
Jon Hall9043c902015-07-30 14:23:44 -07001411 flows.append( main.Mininet1.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001412 if flowCheck == main.FALSE:
1413 for table in flows:
1414 main.log.warn( table )
1415 # TODO: Compare switch flow tables with ONOS flow tables
1416
1417 main.step( "Start continuous pings" )
1418 main.Mininet2.pingLong(
1419 src=main.params[ 'PING' ][ 'source1' ],
1420 target=main.params[ 'PING' ][ 'target1' ],
1421 pingTime=500 )
1422 main.Mininet2.pingLong(
1423 src=main.params[ 'PING' ][ 'source2' ],
1424 target=main.params[ 'PING' ][ 'target2' ],
1425 pingTime=500 )
1426 main.Mininet2.pingLong(
1427 src=main.params[ 'PING' ][ 'source3' ],
1428 target=main.params[ 'PING' ][ 'target3' ],
1429 pingTime=500 )
1430 main.Mininet2.pingLong(
1431 src=main.params[ 'PING' ][ 'source4' ],
1432 target=main.params[ 'PING' ][ 'target4' ],
1433 pingTime=500 )
1434 main.Mininet2.pingLong(
1435 src=main.params[ 'PING' ][ 'source5' ],
1436 target=main.params[ 'PING' ][ 'target5' ],
1437 pingTime=500 )
1438 main.Mininet2.pingLong(
1439 src=main.params[ 'PING' ][ 'source6' ],
1440 target=main.params[ 'PING' ][ 'target6' ],
1441 pingTime=500 )
1442 main.Mininet2.pingLong(
1443 src=main.params[ 'PING' ][ 'source7' ],
1444 target=main.params[ 'PING' ][ 'target7' ],
1445 pingTime=500 )
1446 main.Mininet2.pingLong(
1447 src=main.params[ 'PING' ][ 'source8' ],
1448 target=main.params[ 'PING' ][ 'target8' ],
1449 pingTime=500 )
1450 main.Mininet2.pingLong(
1451 src=main.params[ 'PING' ][ 'source9' ],
1452 target=main.params[ 'PING' ][ 'target9' ],
1453 pingTime=500 )
1454 main.Mininet2.pingLong(
1455 src=main.params[ 'PING' ][ 'source10' ],
1456 target=main.params[ 'PING' ][ 'target10' ],
1457 pingTime=500 )
1458
1459 main.step( "Collecting topology information from ONOS" )
1460 devices = []
1461 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001462 for i in range( main.numCtrls ):
1463 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001464 name="devices-" + str( i ),
1465 args=[ ] )
1466 threads.append( t )
1467 t.start()
1468
1469 for t in threads:
1470 t.join()
1471 devices.append( t.result )
1472 hosts = []
1473 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001474 for i in range( main.numCtrls ):
1475 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001476 name="hosts-" + str( i ),
1477 args=[ ] )
1478 threads.append( t )
1479 t.start()
1480
1481 for t in threads:
1482 t.join()
1483 try:
1484 hosts.append( json.loads( t.result ) )
1485 except ( ValueError, TypeError ):
1486 # FIXME: better handling of this, print which node
1487 # Maybe use thread name?
1488 main.log.exception( "Error parsing json output of hosts" )
1489 # FIXME: should this be an empty json object instead?
1490 hosts.append( None )
1491
1492 ports = []
1493 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001494 for i in range( main.numCtrls ):
1495 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001496 name="ports-" + str( i ),
1497 args=[ ] )
1498 threads.append( t )
1499 t.start()
1500
1501 for t in threads:
1502 t.join()
1503 ports.append( t.result )
1504 links = []
1505 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001506 for i in range( main.numCtrls ):
1507 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001508 name="links-" + str( i ),
1509 args=[ ] )
1510 threads.append( t )
1511 t.start()
1512
1513 for t in threads:
1514 t.join()
1515 links.append( t.result )
1516 clusters = []
1517 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001518 for i in range( main.numCtrls ):
1519 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001520 name="clusters-" + str( i ),
1521 args=[ ] )
1522 threads.append( t )
1523 t.start()
1524
1525 for t in threads:
1526 t.join()
1527 clusters.append( t.result )
1528 # Compare json objects for hosts and dataplane clusters
1529
1530 # hosts
1531 main.step( "Host view is consistent across ONOS nodes" )
1532 consistentHostsResult = main.TRUE
1533 for controller in range( len( hosts ) ):
1534 controllerStr = str( controller + 1 )
1535 if "Error" not in hosts[ controller ]:
1536 if hosts[ controller ] == hosts[ 0 ]:
1537 continue
1538 else: # hosts not consistent
1539 main.log.error( "hosts from ONOS" +
1540 controllerStr +
1541 " is inconsistent with ONOS1" )
1542 main.log.warn( repr( hosts[ controller ] ) )
1543 consistentHostsResult = main.FALSE
1544
1545 else:
1546 main.log.error( "Error in getting ONOS hosts from ONOS" +
1547 controllerStr )
1548 consistentHostsResult = main.FALSE
1549 main.log.warn( "ONOS" + controllerStr +
1550 " hosts response: " +
1551 repr( hosts[ controller ] ) )
1552 utilities.assert_equals(
1553 expect=main.TRUE,
1554 actual=consistentHostsResult,
1555 onpass="Hosts view is consistent across all ONOS nodes",
1556 onfail="ONOS nodes have different views of hosts" )
1557
1558 main.step( "Each host has an IP address" )
1559 ipResult = main.TRUE
1560 for controller in range( 0, len( hosts ) ):
1561 controllerStr = str( controller + 1 )
1562 for host in hosts[ controller ]:
1563 if not host.get( 'ipAddresses', [ ] ):
1564 main.log.error( "DEBUG:Error with host ips on controller" +
1565 controllerStr + ": " + str( host ) )
1566 ipResult = main.FALSE
1567 utilities.assert_equals(
1568 expect=main.TRUE,
1569 actual=ipResult,
1570 onpass="The ips of the hosts aren't empty",
1571 onfail="The ip of at least one host is missing" )
1572
1573 # Strongly connected clusters of devices
1574 main.step( "Cluster view is consistent across ONOS nodes" )
1575 consistentClustersResult = main.TRUE
1576 for controller in range( len( clusters ) ):
1577 controllerStr = str( controller + 1 )
1578 if "Error" not in clusters[ controller ]:
1579 if clusters[ controller ] == clusters[ 0 ]:
1580 continue
1581 else: # clusters not consistent
1582 main.log.error( "clusters from ONOS" + controllerStr +
1583 " is inconsistent with ONOS1" )
1584 consistentClustersResult = main.FALSE
1585
1586 else:
1587 main.log.error( "Error in getting dataplane clusters " +
1588 "from ONOS" + controllerStr )
1589 consistentClustersResult = main.FALSE
1590 main.log.warn( "ONOS" + controllerStr +
1591 " clusters response: " +
1592 repr( clusters[ controller ] ) )
1593 utilities.assert_equals(
1594 expect=main.TRUE,
1595 actual=consistentClustersResult,
1596 onpass="Clusters view is consistent across all ONOS nodes",
1597 onfail="ONOS nodes have different views of clusters" )
1598 # there should always only be one cluster
1599 main.step( "Cluster view correct across ONOS nodes" )
1600 try:
1601 numClusters = len( json.loads( clusters[ 0 ] ) )
1602 except ( ValueError, TypeError ):
1603 main.log.exception( "Error parsing clusters[0]: " +
1604 repr( clusters[ 0 ] ) )
1605 clusterResults = main.FALSE
1606 if numClusters == 1:
1607 clusterResults = main.TRUE
1608 utilities.assert_equals(
1609 expect=1,
1610 actual=numClusters,
1611 onpass="ONOS shows 1 SCC",
1612 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1613
1614 main.step( "Comparing ONOS topology to MN" )
1615 devicesResults = main.TRUE
1616 linksResults = main.TRUE
1617 hostsResults = main.TRUE
1618 mnSwitches = main.Mininet1.getSwitches()
1619 mnLinks = main.Mininet1.getLinks()
1620 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001621 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001622 controllerStr = str( controller + 1 )
1623 if devices[ controller ] and ports[ controller ] and\
1624 "Error" not in devices[ controller ] and\
1625 "Error" not in ports[ controller ]:
1626
1627 currentDevicesResult = main.Mininet1.compareSwitches(
1628 mnSwitches,
1629 json.loads( devices[ controller ] ),
1630 json.loads( ports[ controller ] ) )
1631 else:
1632 currentDevicesResult = main.FALSE
1633 utilities.assert_equals( expect=main.TRUE,
1634 actual=currentDevicesResult,
1635 onpass="ONOS" + controllerStr +
1636 " Switches view is correct",
1637 onfail="ONOS" + controllerStr +
1638 " Switches view is incorrect" )
1639 if links[ controller ] and "Error" not in links[ controller ]:
1640 currentLinksResult = main.Mininet1.compareLinks(
1641 mnSwitches, mnLinks,
1642 json.loads( links[ controller ] ) )
1643 else:
1644 currentLinksResult = main.FALSE
1645 utilities.assert_equals( expect=main.TRUE,
1646 actual=currentLinksResult,
1647 onpass="ONOS" + controllerStr +
1648 " links view is correct",
1649 onfail="ONOS" + controllerStr +
1650 " links view is incorrect" )
1651
1652 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1653 currentHostsResult = main.Mininet1.compareHosts(
1654 mnHosts,
1655 hosts[ controller ] )
1656 else:
1657 currentHostsResult = main.FALSE
1658 utilities.assert_equals( expect=main.TRUE,
1659 actual=currentHostsResult,
1660 onpass="ONOS" + controllerStr +
1661 " hosts exist in Mininet",
1662 onfail="ONOS" + controllerStr +
1663 " hosts don't match Mininet" )
1664
1665 devicesResults = devicesResults and currentDevicesResult
1666 linksResults = linksResults and currentLinksResult
1667 hostsResults = hostsResults and currentHostsResult
1668
1669 main.step( "Device information is correct" )
1670 utilities.assert_equals(
1671 expect=main.TRUE,
1672 actual=devicesResults,
1673 onpass="Device information is correct",
1674 onfail="Device information is incorrect" )
1675
1676 main.step( "Links are correct" )
1677 utilities.assert_equals(
1678 expect=main.TRUE,
1679 actual=linksResults,
1680 onpass="Link are correct",
1681 onfail="Links are incorrect" )
1682
1683 main.step( "Hosts are correct" )
1684 utilities.assert_equals(
1685 expect=main.TRUE,
1686 actual=hostsResults,
1687 onpass="Hosts are correct",
1688 onfail="Hosts are incorrect" )
1689
1690 def CASE6( self, main ):
1691 """
1692 The Failure case.
1693 """
1694 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001695 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001696 assert main, "main not defined"
1697 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001698 assert main.CLIs, "main.CLIs not defined"
1699 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001700 main.case( "Restart minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -07001701
1702 main.step( "Checking ONOS Logs for errors" )
1703 for node in main.nodes:
1704 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1705 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1706
Jon Hall3b489db2015-10-05 14:38:37 -07001707 n = len( main.nodes ) # Number of nodes
1708 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
1709 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
1710 if n > 3:
1711 main.kill.append( p - 1 )
1712 # NOTE: This only works for cluster sizes of 3,5, or 7.
1713
1714 main.step( "Killing " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001715 killTime = time.time()
Jon Hall3b489db2015-10-05 14:38:37 -07001716 killResults = main.TRUE
1717 for i in main.kill:
1718 killResults = killResults and\
1719 main.ONOSbench.onosKill( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001720 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1721 onpass="ONOS Killed successfully",
1722 onfail="ONOS kill NOT successful" )
1723
1724 main.step( "Checking if ONOS is up yet" )
1725 count = 0
1726 onosIsupResult = main.FALSE
1727 while onosIsupResult == main.FALSE and count < 10:
Jon Hall3b489db2015-10-05 14:38:37 -07001728 onosIsupResult = main.TRUE
1729 for i in main.kill:
1730 onosIsupResult = onosIsupResult and\
1731 main.ONOSbench.isup( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001732 count = count + 1
Jon Hall5cf14d52015-07-16 12:15:19 -07001733 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1734 onpass="ONOS restarted successfully",
1735 onfail="ONOS restart NOT successful" )
1736
Jon Halle1a3b752015-07-22 13:02:46 -07001737 main.step( "Restarting ONOS main.CLIs" )
Jon Hall3b489db2015-10-05 14:38:37 -07001738 cliResults = main.TRUE
1739 for i in main.kill:
1740 cliResults = cliResults and\
1741 main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001742 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1743 onpass="ONOS cli restarted",
1744 onfail="ONOS cli did not restart" )
1745
1746 # Grab the time of restart so we chan check how long the gossip
1747 # protocol has had time to work
1748 main.restartTime = time.time() - killTime
1749 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001750 # TODO: MAke this configurable. Also, we are breaking the above timer
1751 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001752 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1753 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1754 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001755
1756 def CASE7( self, main ):
1757 """
1758 Check state after ONOS failure
1759 """
1760 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001761 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001762 assert main, "main not defined"
1763 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001764 assert main.CLIs, "main.CLIs not defined"
1765 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001766 main.case( "Running ONOS Constant State Tests" )
1767
1768 main.step( "Check that each switch has a master" )
1769 # Assert that each device has a master
1770 rolesNotNull = main.TRUE
1771 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001772 for i in range( main.numCtrls ):
1773 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001774 name="rolesNotNull-" + str( i ),
1775 args=[ ] )
1776 threads.append( t )
1777 t.start()
1778
1779 for t in threads:
1780 t.join()
1781 rolesNotNull = rolesNotNull and t.result
1782 utilities.assert_equals(
1783 expect=main.TRUE,
1784 actual=rolesNotNull,
1785 onpass="Each device has a master",
1786 onfail="Some devices don't have a master assigned" )
1787
1788 main.step( "Read device roles from ONOS" )
1789 ONOSMastership = []
1790 consistentMastership = True
1791 rolesResults = True
1792 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001793 for i in range( main.numCtrls ):
1794 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001795 name="roles-" + str( i ),
1796 args=[] )
1797 threads.append( t )
1798 t.start()
1799
1800 for t in threads:
1801 t.join()
1802 ONOSMastership.append( t.result )
1803
Jon Halle1a3b752015-07-22 13:02:46 -07001804 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001805 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1806 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1807 " roles" )
1808 main.log.warn(
1809 "ONOS" + str( i + 1 ) + " mastership response: " +
1810 repr( ONOSMastership[i] ) )
1811 rolesResults = False
1812 utilities.assert_equals(
1813 expect=True,
1814 actual=rolesResults,
1815 onpass="No error in reading roles output",
1816 onfail="Error in reading roles from ONOS" )
1817
1818 main.step( "Check for consistency in roles from each controller" )
1819 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1820 main.log.info(
1821 "Switch roles are consistent across all ONOS nodes" )
1822 else:
1823 consistentMastership = False
1824 utilities.assert_equals(
1825 expect=True,
1826 actual=consistentMastership,
1827 onpass="Switch roles are consistent across all ONOS nodes",
1828 onfail="ONOS nodes have different views of switch roles" )
1829
1830 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001831 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001832 main.log.warn(
1833 "ONOS" + str( i + 1 ) + " roles: ",
1834 json.dumps(
1835 json.loads( ONOSMastership[ i ] ),
1836 sort_keys=True,
1837 indent=4,
1838 separators=( ',', ': ' ) ) )
1839
1840 # NOTE: we expect mastership to change on controller failure
1841 '''
1842 description2 = "Compare switch roles from before failure"
1843 main.step( description2 )
1844 try:
1845 currentJson = json.loads( ONOSMastership[0] )
1846 oldJson = json.loads( mastershipState )
1847 except ( ValueError, TypeError ):
1848 main.log.exception( "Something is wrong with parsing " +
1849 "ONOSMastership[0] or mastershipState" )
1850 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1851 main.log.error( "mastershipState" + repr( mastershipState ) )
1852 main.cleanup()
1853 main.exit()
1854 mastershipCheck = main.TRUE
1855 for i in range( 1, 29 ):
1856 switchDPID = str(
1857 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1858 current = [ switch[ 'master' ] for switch in currentJson
1859 if switchDPID in switch[ 'id' ] ]
1860 old = [ switch[ 'master' ] for switch in oldJson
1861 if switchDPID in switch[ 'id' ] ]
1862 if current == old:
1863 mastershipCheck = mastershipCheck and main.TRUE
1864 else:
1865 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1866 mastershipCheck = main.FALSE
1867 utilities.assert_equals(
1868 expect=main.TRUE,
1869 actual=mastershipCheck,
1870 onpass="Mastership of Switches was not changed",
1871 onfail="Mastership of some switches changed" )
1872 '''
1873
1874 main.step( "Get the intents and compare across all nodes" )
1875 ONOSIntents = []
1876 intentCheck = main.FALSE
1877 consistentIntents = True
1878 intentsResults = True
1879 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001880 for i in range( main.numCtrls ):
1881 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001882 name="intents-" + str( i ),
1883 args=[],
1884 kwargs={ 'jsonFormat': True } )
1885 threads.append( t )
1886 t.start()
1887
1888 for t in threads:
1889 t.join()
1890 ONOSIntents.append( t.result )
1891
Jon Halle1a3b752015-07-22 13:02:46 -07001892 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001893 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1894 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1895 " intents" )
1896 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1897 repr( ONOSIntents[ i ] ) )
1898 intentsResults = False
1899 utilities.assert_equals(
1900 expect=True,
1901 actual=intentsResults,
1902 onpass="No error in reading intents output",
1903 onfail="Error in reading intents from ONOS" )
1904
1905 main.step( "Check for consistency in Intents from each controller" )
1906 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1907 main.log.info( "Intents are consistent across all ONOS " +
1908 "nodes" )
1909 else:
1910 consistentIntents = False
1911
1912 # Try to make it easy to figure out what is happening
1913 #
1914 # Intent ONOS1 ONOS2 ...
1915 # 0x01 INSTALLED INSTALLING
1916 # ... ... ...
1917 # ... ... ...
1918 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001919 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001920 title += " " * 10 + "ONOS" + str( n + 1 )
1921 main.log.warn( title )
1922 # get all intent keys in the cluster
1923 keys = []
1924 for nodeStr in ONOSIntents:
1925 node = json.loads( nodeStr )
1926 for intent in node:
1927 keys.append( intent.get( 'id' ) )
1928 keys = set( keys )
1929 for key in keys:
1930 row = "%-13s" % key
1931 for nodeStr in ONOSIntents:
1932 node = json.loads( nodeStr )
1933 for intent in node:
1934 if intent.get( 'id' ) == key:
1935 row += "%-15s" % intent.get( 'state' )
1936 main.log.warn( row )
1937 # End table view
1938
1939 utilities.assert_equals(
1940 expect=True,
1941 actual=consistentIntents,
1942 onpass="Intents are consistent across all ONOS nodes",
1943 onfail="ONOS nodes have different views of intents" )
1944 intentStates = []
1945 for node in ONOSIntents: # Iter through ONOS nodes
1946 nodeStates = []
1947 # Iter through intents of a node
1948 try:
1949 for intent in json.loads( node ):
1950 nodeStates.append( intent[ 'state' ] )
1951 except ( ValueError, TypeError ):
1952 main.log.exception( "Error in parsing intents" )
1953 main.log.error( repr( node ) )
1954 intentStates.append( nodeStates )
1955 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1956 main.log.info( dict( out ) )
1957
1958 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07001959 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001960 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1961 main.log.warn( json.dumps(
1962 json.loads( ONOSIntents[ i ] ),
1963 sort_keys=True,
1964 indent=4,
1965 separators=( ',', ': ' ) ) )
1966 elif intentsResults and consistentIntents:
1967 intentCheck = main.TRUE
1968
1969 # NOTE: Store has no durability, so intents are lost across system
1970 # restarts
1971 main.step( "Compare current intents with intents before the failure" )
1972 # NOTE: this requires case 5 to pass for intentState to be set.
1973 # maybe we should stop the test if that fails?
1974 sameIntents = main.FALSE
1975 if intentState and intentState == ONOSIntents[ 0 ]:
1976 sameIntents = main.TRUE
1977 main.log.info( "Intents are consistent with before failure" )
1978 # TODO: possibly the states have changed? we may need to figure out
1979 # what the acceptable states are
1980 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1981 sameIntents = main.TRUE
1982 try:
1983 before = json.loads( intentState )
1984 after = json.loads( ONOSIntents[ 0 ] )
1985 for intent in before:
1986 if intent not in after:
1987 sameIntents = main.FALSE
1988 main.log.debug( "Intent is not currently in ONOS " +
1989 "(at least in the same form):" )
1990 main.log.debug( json.dumps( intent ) )
1991 except ( ValueError, TypeError ):
1992 main.log.exception( "Exception printing intents" )
1993 main.log.debug( repr( ONOSIntents[0] ) )
1994 main.log.debug( repr( intentState ) )
1995 if sameIntents == main.FALSE:
1996 try:
1997 main.log.debug( "ONOS intents before: " )
1998 main.log.debug( json.dumps( json.loads( intentState ),
1999 sort_keys=True, indent=4,
2000 separators=( ',', ': ' ) ) )
2001 main.log.debug( "Current ONOS intents: " )
2002 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2003 sort_keys=True, indent=4,
2004 separators=( ',', ': ' ) ) )
2005 except ( ValueError, TypeError ):
2006 main.log.exception( "Exception printing intents" )
2007 main.log.debug( repr( ONOSIntents[0] ) )
2008 main.log.debug( repr( intentState ) )
2009 utilities.assert_equals(
2010 expect=main.TRUE,
2011 actual=sameIntents,
2012 onpass="Intents are consistent with before failure",
2013 onfail="The Intents changed during failure" )
2014 intentCheck = intentCheck and sameIntents
2015
2016 main.step( "Get the OF Table entries and compare to before " +
2017 "component failure" )
2018 FlowTables = main.TRUE
2019 flows2 = []
2020 for i in range( 28 ):
2021 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall9043c902015-07-30 14:23:44 -07002022 tmpFlows = main.Mininet1.getFlowTable( 1.3, "s" + str( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002023 flows2.append( tmpFlows )
Jon Hall9043c902015-07-30 14:23:44 -07002024 tempResult = main.Mininet1.flowComp(
Jon Hall5cf14d52015-07-16 12:15:19 -07002025 flow1=flows[ i ],
2026 flow2=tmpFlows )
2027 FlowTables = FlowTables and tempResult
2028 if FlowTables == main.FALSE:
2029 main.log.info( "Differences in flow table for switch: s" +
2030 str( i + 1 ) )
2031 utilities.assert_equals(
2032 expect=main.TRUE,
2033 actual=FlowTables,
2034 onpass="No changes were found in the flow tables",
2035 onfail="Changes were found in the flow tables" )
2036
2037 main.Mininet2.pingLongKill()
2038 '''
2039 main.step( "Check the continuous pings to ensure that no packets " +
2040 "were dropped during component failure" )
2041 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2042 main.params[ 'TESTONIP' ] )
2043 LossInPings = main.FALSE
2044 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2045 for i in range( 8, 18 ):
2046 main.log.info(
2047 "Checking for a loss in pings along flow from s" +
2048 str( i ) )
2049 LossInPings = main.Mininet2.checkForLoss(
2050 "/tmp/ping.h" +
2051 str( i ) ) or LossInPings
2052 if LossInPings == main.TRUE:
2053 main.log.info( "Loss in ping detected" )
2054 elif LossInPings == main.ERROR:
2055 main.log.info( "There are multiple mininet process running" )
2056 elif LossInPings == main.FALSE:
2057 main.log.info( "No Loss in the pings" )
2058 main.log.info( "No loss of dataplane connectivity" )
2059 utilities.assert_equals(
2060 expect=main.FALSE,
2061 actual=LossInPings,
2062 onpass="No Loss of connectivity",
2063 onfail="Loss of dataplane connectivity detected" )
2064 '''
2065
2066 main.step( "Leadership Election is still functional" )
2067 # Test of LeadershipElection
2068 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -07002069
Jon Hall3b489db2015-10-05 14:38:37 -07002070 restarted = []
2071 for i in main.kill:
2072 restarted.append( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002073 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -07002074
Jon Halle1a3b752015-07-22 13:02:46 -07002075 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002076 leaderN = cli.electionTestLeader()
2077 leaderList.append( leaderN )
2078 if leaderN == main.FALSE:
2079 # error in response
2080 main.log.error( "Something is wrong with " +
2081 "electionTestLeader function, check the" +
2082 " error logs" )
2083 leaderResult = main.FALSE
2084 elif leaderN is None:
2085 main.log.error( cli.name +
2086 " shows no leader for the election-app was" +
2087 " elected after the old one died" )
2088 leaderResult = main.FALSE
2089 elif leaderN in restarted:
2090 main.log.error( cli.name + " shows " + str( leaderN ) +
2091 " as leader for the election-app, but it " +
2092 "was restarted" )
2093 leaderResult = main.FALSE
2094 if len( set( leaderList ) ) != 1:
2095 leaderResult = main.FALSE
2096 main.log.error(
2097 "Inconsistent view of leader for the election test app" )
2098 # TODO: print the list
2099 utilities.assert_equals(
2100 expect=main.TRUE,
2101 actual=leaderResult,
2102 onpass="Leadership election passed",
2103 onfail="Something went wrong with Leadership election" )
2104
2105 def CASE8( self, main ):
2106 """
2107 Compare topo
2108 """
2109 import json
2110 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002111 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002112 assert main, "main not defined"
2113 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002114 assert main.CLIs, "main.CLIs not defined"
2115 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002116
2117 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002118 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002119 " and ONOS"
2120
2121 main.step( "Comparing ONOS topology to MN" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002122 topoResult = main.FALSE
2123 elapsed = 0
2124 count = 0
2125 main.step( "Collecting topology information from ONOS" )
2126 startTime = time.time()
2127 # Give time for Gossip to work
2128 while topoResult == main.FALSE and elapsed < 60:
Jon Hall96091e62015-09-21 17:34:17 -07002129 devicesResults = main.TRUE
2130 linksResults = main.TRUE
2131 hostsResults = main.TRUE
2132 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002133 count += 1
2134 cliStart = time.time()
2135 devices = []
2136 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002137 for i in range( main.numCtrls ):
2138 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002139 name="devices-" + str( i ),
2140 args=[ ] )
2141 threads.append( t )
2142 t.start()
2143
2144 for t in threads:
2145 t.join()
2146 devices.append( t.result )
2147 hosts = []
2148 ipResult = main.TRUE
2149 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002150 for i in range( main.numCtrls ):
2151 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002152 name="hosts-" + str( i ),
2153 args=[ ] )
2154 threads.append( t )
2155 t.start()
2156
2157 for t in threads:
2158 t.join()
2159 try:
2160 hosts.append( json.loads( t.result ) )
2161 except ( ValueError, TypeError ):
2162 main.log.exception( "Error parsing hosts results" )
2163 main.log.error( repr( t.result ) )
2164 for controller in range( 0, len( hosts ) ):
2165 controllerStr = str( controller + 1 )
2166 for host in hosts[ controller ]:
2167 if host is None or host.get( 'ipAddresses', [] ) == []:
2168 main.log.error(
2169 "DEBUG:Error with host ipAddresses on controller" +
2170 controllerStr + ": " + str( host ) )
2171 ipResult = main.FALSE
2172 ports = []
2173 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002174 for i in range( main.numCtrls ):
2175 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002176 name="ports-" + str( i ),
2177 args=[ ] )
2178 threads.append( t )
2179 t.start()
2180
2181 for t in threads:
2182 t.join()
2183 ports.append( t.result )
2184 links = []
2185 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002186 for i in range( main.numCtrls ):
2187 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002188 name="links-" + str( i ),
2189 args=[ ] )
2190 threads.append( t )
2191 t.start()
2192
2193 for t in threads:
2194 t.join()
2195 links.append( t.result )
2196 clusters = []
2197 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002198 for i in range( main.numCtrls ):
2199 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002200 name="clusters-" + str( i ),
2201 args=[ ] )
2202 threads.append( t )
2203 t.start()
2204
2205 for t in threads:
2206 t.join()
2207 clusters.append( t.result )
2208
2209 elapsed = time.time() - startTime
2210 cliTime = time.time() - cliStart
2211 print "Elapsed time: " + str( elapsed )
2212 print "CLI time: " + str( cliTime )
2213
2214 mnSwitches = main.Mininet1.getSwitches()
2215 mnLinks = main.Mininet1.getLinks()
2216 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002217 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002218 controllerStr = str( controller + 1 )
2219 if devices[ controller ] and ports[ controller ] and\
2220 "Error" not in devices[ controller ] and\
2221 "Error" not in ports[ controller ]:
2222
2223 currentDevicesResult = main.Mininet1.compareSwitches(
2224 mnSwitches,
2225 json.loads( devices[ controller ] ),
2226 json.loads( ports[ controller ] ) )
2227 else:
2228 currentDevicesResult = main.FALSE
2229 utilities.assert_equals( expect=main.TRUE,
2230 actual=currentDevicesResult,
2231 onpass="ONOS" + controllerStr +
2232 " Switches view is correct",
2233 onfail="ONOS" + controllerStr +
2234 " Switches view is incorrect" )
2235
2236 if links[ controller ] and "Error" not in links[ controller ]:
2237 currentLinksResult = main.Mininet1.compareLinks(
2238 mnSwitches, mnLinks,
2239 json.loads( links[ controller ] ) )
2240 else:
2241 currentLinksResult = main.FALSE
2242 utilities.assert_equals( expect=main.TRUE,
2243 actual=currentLinksResult,
2244 onpass="ONOS" + controllerStr +
2245 " links view is correct",
2246 onfail="ONOS" + controllerStr +
2247 " links view is incorrect" )
2248
2249 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2250 currentHostsResult = main.Mininet1.compareHosts(
2251 mnHosts,
2252 hosts[ controller ] )
2253 else:
2254 currentHostsResult = main.FALSE
2255 utilities.assert_equals( expect=main.TRUE,
2256 actual=currentHostsResult,
2257 onpass="ONOS" + controllerStr +
2258 " hosts exist in Mininet",
2259 onfail="ONOS" + controllerStr +
2260 " hosts don't match Mininet" )
2261 # CHECKING HOST ATTACHMENT POINTS
2262 hostAttachment = True
2263 zeroHosts = False
2264 # FIXME: topo-HA/obelisk specific mappings:
2265 # key is mac and value is dpid
2266 mappings = {}
2267 for i in range( 1, 29 ): # hosts 1 through 28
2268 # set up correct variables:
2269 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2270 if i == 1:
2271 deviceId = "1000".zfill(16)
2272 elif i == 2:
2273 deviceId = "2000".zfill(16)
2274 elif i == 3:
2275 deviceId = "3000".zfill(16)
2276 elif i == 4:
2277 deviceId = "3004".zfill(16)
2278 elif i == 5:
2279 deviceId = "5000".zfill(16)
2280 elif i == 6:
2281 deviceId = "6000".zfill(16)
2282 elif i == 7:
2283 deviceId = "6007".zfill(16)
2284 elif i >= 8 and i <= 17:
2285 dpid = '3' + str( i ).zfill( 3 )
2286 deviceId = dpid.zfill(16)
2287 elif i >= 18 and i <= 27:
2288 dpid = '6' + str( i ).zfill( 3 )
2289 deviceId = dpid.zfill(16)
2290 elif i == 28:
2291 deviceId = "2800".zfill(16)
2292 mappings[ macId ] = deviceId
2293 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2294 if hosts[ controller ] == []:
2295 main.log.warn( "There are no hosts discovered" )
2296 zeroHosts = True
2297 else:
2298 for host in hosts[ controller ]:
2299 mac = None
2300 location = None
2301 device = None
2302 port = None
2303 try:
2304 mac = host.get( 'mac' )
2305 assert mac, "mac field could not be found for this host object"
2306
2307 location = host.get( 'location' )
2308 assert location, "location field could not be found for this host object"
2309
2310 # Trim the protocol identifier off deviceId
2311 device = str( location.get( 'elementId' ) ).split(':')[1]
2312 assert device, "elementId field could not be found for this host location object"
2313
2314 port = location.get( 'port' )
2315 assert port, "port field could not be found for this host location object"
2316
2317 # Now check if this matches where they should be
2318 if mac and device and port:
2319 if str( port ) != "1":
2320 main.log.error( "The attachment port is incorrect for " +
2321 "host " + str( mac ) +
2322 ". Expected: 1 Actual: " + str( port) )
2323 hostAttachment = False
2324 if device != mappings[ str( mac ) ]:
2325 main.log.error( "The attachment device is incorrect for " +
2326 "host " + str( mac ) +
2327 ". Expected: " + mappings[ str( mac ) ] +
2328 " Actual: " + device )
2329 hostAttachment = False
2330 else:
2331 hostAttachment = False
2332 except AssertionError:
2333 main.log.exception( "Json object not as expected" )
2334 main.log.error( repr( host ) )
2335 hostAttachment = False
2336 else:
2337 main.log.error( "No hosts json output or \"Error\"" +
2338 " in output. hosts = " +
2339 repr( hosts[ controller ] ) )
2340 if zeroHosts is False:
2341 hostAttachment = True
2342
2343 # END CHECKING HOST ATTACHMENT POINTS
2344 devicesResults = devicesResults and currentDevicesResult
2345 linksResults = linksResults and currentLinksResult
2346 hostsResults = hostsResults and currentHostsResult
2347 hostAttachmentResults = hostAttachmentResults and\
2348 hostAttachment
2349
2350 # Compare json objects for hosts and dataplane clusters
2351
2352 # hosts
2353 main.step( "Hosts view is consistent across all ONOS nodes" )
2354 consistentHostsResult = main.TRUE
2355 for controller in range( len( hosts ) ):
2356 controllerStr = str( controller + 1 )
2357 if "Error" not in hosts[ controller ]:
2358 if hosts[ controller ] == hosts[ 0 ]:
2359 continue
2360 else: # hosts not consistent
2361 main.log.error( "hosts from ONOS" + controllerStr +
2362 " is inconsistent with ONOS1" )
2363 main.log.warn( repr( hosts[ controller ] ) )
2364 consistentHostsResult = main.FALSE
2365
2366 else:
2367 main.log.error( "Error in getting ONOS hosts from ONOS" +
2368 controllerStr )
2369 consistentHostsResult = main.FALSE
2370 main.log.warn( "ONOS" + controllerStr +
2371 " hosts response: " +
2372 repr( hosts[ controller ] ) )
2373 utilities.assert_equals(
2374 expect=main.TRUE,
2375 actual=consistentHostsResult,
2376 onpass="Hosts view is consistent across all ONOS nodes",
2377 onfail="ONOS nodes have different views of hosts" )
2378
2379 main.step( "Hosts information is correct" )
2380 hostsResults = hostsResults and ipResult
2381 utilities.assert_equals(
2382 expect=main.TRUE,
2383 actual=hostsResults,
2384 onpass="Host information is correct",
2385 onfail="Host information is incorrect" )
2386
2387 main.step( "Host attachment points to the network" )
2388 utilities.assert_equals(
2389 expect=True,
2390 actual=hostAttachmentResults,
2391 onpass="Hosts are correctly attached to the network",
2392 onfail="ONOS did not correctly attach hosts to the network" )
2393
2394 # Strongly connected clusters of devices
2395 main.step( "Clusters view is consistent across all ONOS nodes" )
2396 consistentClustersResult = main.TRUE
2397 for controller in range( len( clusters ) ):
2398 controllerStr = str( controller + 1 )
2399 if "Error" not in clusters[ controller ]:
2400 if clusters[ controller ] == clusters[ 0 ]:
2401 continue
2402 else: # clusters not consistent
2403 main.log.error( "clusters from ONOS" +
2404 controllerStr +
2405 " is inconsistent with ONOS1" )
2406 consistentClustersResult = main.FALSE
2407
2408 else:
2409 main.log.error( "Error in getting dataplane clusters " +
2410 "from ONOS" + controllerStr )
2411 consistentClustersResult = main.FALSE
2412 main.log.warn( "ONOS" + controllerStr +
2413 " clusters response: " +
2414 repr( clusters[ controller ] ) )
2415 utilities.assert_equals(
2416 expect=main.TRUE,
2417 actual=consistentClustersResult,
2418 onpass="Clusters view is consistent across all ONOS nodes",
2419 onfail="ONOS nodes have different views of clusters" )
2420
2421 main.step( "There is only one SCC" )
2422 # there should always only be one cluster
2423 try:
2424 numClusters = len( json.loads( clusters[ 0 ] ) )
2425 except ( ValueError, TypeError ):
2426 main.log.exception( "Error parsing clusters[0]: " +
2427 repr( clusters[0] ) )
2428 clusterResults = main.FALSE
2429 if numClusters == 1:
2430 clusterResults = main.TRUE
2431 utilities.assert_equals(
2432 expect=1,
2433 actual=numClusters,
2434 onpass="ONOS shows 1 SCC",
2435 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2436
2437 topoResult = ( devicesResults and linksResults
2438 and hostsResults and consistentHostsResult
2439 and consistentClustersResult and clusterResults
2440 and ipResult and hostAttachmentResults )
2441
2442 topoResult = topoResult and int( count <= 2 )
2443 note = "note it takes about " + str( int( cliTime ) ) + \
2444 " seconds for the test to make all the cli calls to fetch " +\
2445 "the topology from each ONOS instance"
2446 main.log.info(
2447 "Very crass estimate for topology discovery/convergence( " +
2448 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2449 str( count ) + " tries" )
2450
2451 main.step( "Device information is correct" )
2452 utilities.assert_equals(
2453 expect=main.TRUE,
2454 actual=devicesResults,
2455 onpass="Device information is correct",
2456 onfail="Device information is incorrect" )
2457
2458 main.step( "Links are correct" )
2459 utilities.assert_equals(
2460 expect=main.TRUE,
2461 actual=linksResults,
2462 onpass="Link are correct",
2463 onfail="Links are incorrect" )
2464
2465 # FIXME: move this to an ONOS state case
2466 main.step( "Checking ONOS nodes" )
2467 nodesOutput = []
2468 nodeResults = main.TRUE
2469 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002470 for i in range( main.numCtrls ):
2471 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002472 name="nodes-" + str( i ),
2473 args=[ ] )
2474 threads.append( t )
2475 t.start()
2476
2477 for t in threads:
2478 t.join()
2479 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002480 ips = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002481 for i in nodesOutput:
2482 try:
2483 current = json.loads( i )
2484 for node in current:
2485 currentResult = main.FALSE
2486 if node['ip'] in ips: # node in nodes() output is in cell
2487 if node['state'] == 'ACTIVE':
2488 currentResult = main.TRUE
2489 else:
2490 main.log.error( "Error in ONOS node availability" )
2491 main.log.error(
2492 json.dumps( current,
2493 sort_keys=True,
2494 indent=4,
2495 separators=( ',', ': ' ) ) )
2496 break
2497 nodeResults = nodeResults and currentResult
2498 except ( ValueError, TypeError ):
2499 main.log.error( "Error parsing nodes output" )
2500 main.log.warn( repr( i ) )
2501 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2502 onpass="Nodes check successful",
2503 onfail="Nodes check NOT successful" )
2504
2505 def CASE9( self, main ):
2506 """
2507 Link s3-s28 down
2508 """
2509 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002510 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002511 assert main, "main not defined"
2512 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002513 assert main.CLIs, "main.CLIs not defined"
2514 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002515 # NOTE: You should probably run a topology check after this
2516
2517 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2518
2519 description = "Turn off a link to ensure that Link Discovery " +\
2520 "is working properly"
2521 main.case( description )
2522
2523 main.step( "Kill Link between s3 and s28" )
2524 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2525 main.log.info( "Waiting " + str( linkSleep ) +
2526 " seconds for link down to be discovered" )
2527 time.sleep( linkSleep )
2528 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2529 onpass="Link down successful",
2530 onfail="Failed to bring link down" )
2531 # TODO do some sort of check here
2532
2533 def CASE10( self, main ):
2534 """
2535 Link s3-s28 up
2536 """
2537 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002538 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002539 assert main, "main not defined"
2540 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002541 assert main.CLIs, "main.CLIs not defined"
2542 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002543 # NOTE: You should probably run a topology check after this
2544
2545 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2546
2547 description = "Restore a link to ensure that Link Discovery is " + \
2548 "working properly"
2549 main.case( description )
2550
2551 main.step( "Bring link between s3 and s28 back up" )
2552 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2553 main.log.info( "Waiting " + str( linkSleep ) +
2554 " seconds for link up to be discovered" )
2555 time.sleep( linkSleep )
2556 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2557 onpass="Link up successful",
2558 onfail="Failed to bring link up" )
2559 # TODO do some sort of check here
2560
2561 def CASE11( self, main ):
2562 """
2563 Switch Down
2564 """
2565 # NOTE: You should probably run a topology check after this
2566 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002567 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002568 assert main, "main not defined"
2569 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002570 assert main.CLIs, "main.CLIs not defined"
2571 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002572
2573 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2574
2575 description = "Killing a switch to ensure it is discovered correctly"
2576 main.case( description )
2577 switch = main.params[ 'kill' ][ 'switch' ]
2578 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2579
2580 # TODO: Make this switch parameterizable
2581 main.step( "Kill " + switch )
2582 main.log.info( "Deleting " + switch )
2583 main.Mininet1.delSwitch( switch )
2584 main.log.info( "Waiting " + str( switchSleep ) +
2585 " seconds for switch down to be discovered" )
2586 time.sleep( switchSleep )
2587 device = main.ONOScli1.getDevice( dpid=switchDPID )
2588 # Peek at the deleted switch
2589 main.log.warn( str( device ) )
2590 result = main.FALSE
2591 if device and device[ 'available' ] is False:
2592 result = main.TRUE
2593 utilities.assert_equals( expect=main.TRUE, actual=result,
2594 onpass="Kill switch successful",
2595 onfail="Failed to kill switch?" )
2596
2597 def CASE12( self, main ):
2598 """
2599 Switch Up
2600 """
2601 # NOTE: You should probably run a topology check after this
2602 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002603 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002604 assert main, "main not defined"
2605 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002606 assert main.CLIs, "main.CLIs not defined"
2607 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002608 assert ONOS1Port, "ONOS1Port not defined"
2609 assert ONOS2Port, "ONOS2Port not defined"
2610 assert ONOS3Port, "ONOS3Port not defined"
2611 assert ONOS4Port, "ONOS4Port not defined"
2612 assert ONOS5Port, "ONOS5Port not defined"
2613 assert ONOS6Port, "ONOS6Port not defined"
2614 assert ONOS7Port, "ONOS7Port not defined"
2615
2616 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2617 switch = main.params[ 'kill' ][ 'switch' ]
2618 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2619 links = main.params[ 'kill' ][ 'links' ].split()
2620 description = "Adding a switch to ensure it is discovered correctly"
2621 main.case( description )
2622
2623 main.step( "Add back " + switch )
2624 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2625 for peer in links:
2626 main.Mininet1.addLink( switch, peer )
2627 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002628 for i in range( main.numCtrls ):
2629 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002630 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2631 main.log.info( "Waiting " + str( switchSleep ) +
2632 " seconds for switch up to be discovered" )
2633 time.sleep( switchSleep )
2634 device = main.ONOScli1.getDevice( dpid=switchDPID )
2635 # Peek at the deleted switch
2636 main.log.warn( str( device ) )
2637 result = main.FALSE
2638 if device and device[ 'available' ]:
2639 result = main.TRUE
2640 utilities.assert_equals( expect=main.TRUE, actual=result,
2641 onpass="add switch successful",
2642 onfail="Failed to add switch?" )
2643
2644 def CASE13( self, main ):
2645 """
2646 Clean up
2647 """
2648 import os
2649 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002650 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002651 assert main, "main not defined"
2652 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002653 assert main.CLIs, "main.CLIs not defined"
2654 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002655
2656 # printing colors to terminal
2657 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2658 'blue': '\033[94m', 'green': '\033[92m',
2659 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2660 main.case( "Test Cleanup" )
2661 main.step( "Killing tcpdumps" )
2662 main.Mininet2.stopTcpdump()
2663
2664 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002665 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002666 main.step( "Copying MN pcap and ONOS log files to test station" )
2667 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2668 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002669 # NOTE: MN Pcap file is being saved to logdir.
2670 # We scp this file as MN and TestON aren't necessarily the same vm
2671
2672 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002673 # TODO: Load these from params
2674 # NOTE: must end in /
2675 logFolder = "/opt/onos/log/"
2676 logFiles = [ "karaf.log", "karaf.log.1" ]
2677 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002678 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002679 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002680 dstName = main.logdir + "/" + node.name + "-" + f
2681 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2682 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002683 # std*.log's
2684 # NOTE: must end in /
2685 logFolder = "/opt/onos/var/"
2686 logFiles = [ "stderr.log", "stdout.log" ]
2687 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002688 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002689 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002690 dstName = main.logdir + "/" + node.name + "-" + f
2691 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2692 logFolder + f, dstName )
2693 else:
2694 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002695
2696 main.step( "Stopping Mininet" )
2697 mnResult = main.Mininet1.stopNet()
2698 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2699 onpass="Mininet stopped",
2700 onfail="MN cleanup NOT successful" )
2701
2702 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002703 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002704 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2705 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002706
2707 try:
2708 timerLog = open( main.logdir + "/Timers.csv", 'w')
2709 # Overwrite with empty line and close
2710 labels = "Gossip Intents, Restart"
2711 data = str( gossipTime ) + ", " + str( main.restartTime )
2712 timerLog.write( labels + "\n" + data )
2713 timerLog.close()
2714 except NameError, e:
2715 main.log.exception(e)
2716
2717 def CASE14( self, main ):
2718 """
2719 start election app on all onos nodes
2720 """
Jon Halle1a3b752015-07-22 13:02:46 -07002721 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002722 assert main, "main not defined"
2723 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002724 assert main.CLIs, "main.CLIs not defined"
2725 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002726
2727 main.case("Start Leadership Election app")
2728 main.step( "Install leadership election app" )
2729 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2730 utilities.assert_equals(
2731 expect=main.TRUE,
2732 actual=appResult,
2733 onpass="Election app installed",
2734 onfail="Something went wrong with installing Leadership election" )
2735
2736 main.step( "Run for election on each node" )
2737 leaderResult = main.TRUE
2738 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002739 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002740 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002741 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002742 leader = cli.electionTestLeader()
2743 if leader is None or leader == main.FALSE:
2744 main.log.error( cli.name + ": Leader for the election app " +
2745 "should be an ONOS node, instead got '" +
2746 str( leader ) + "'" )
2747 leaderResult = main.FALSE
2748 leaders.append( leader )
2749 utilities.assert_equals(
2750 expect=main.TRUE,
2751 actual=leaderResult,
2752 onpass="Successfully ran for leadership",
2753 onfail="Failed to run for leadership" )
2754
2755 main.step( "Check that each node shows the same leader" )
2756 sameLeader = main.TRUE
2757 if len( set( leaders ) ) != 1:
2758 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002759 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002760 str( leaders ) )
2761 utilities.assert_equals(
2762 expect=main.TRUE,
2763 actual=sameLeader,
2764 onpass="Leadership is consistent for the election topic",
2765 onfail="Nodes have different leaders" )
2766
2767 def CASE15( self, main ):
2768 """
2769 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002770 15.1 Run election on each node
2771 15.2 Check that each node has the same leaders and candidates
2772 15.3 Find current leader and withdraw
2773 15.4 Check that a new node was elected leader
2774 15.5 Check that that new leader was the candidate of old leader
2775 15.6 Run for election on old leader
2776 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2777 15.8 Make sure that the old leader was added to the candidate list
2778
2779 old and new variable prefixes refer to data from before vs after
2780 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002781 """
2782 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002783 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002784 assert main, "main not defined"
2785 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002786 assert main.CLIs, "main.CLIs not defined"
2787 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002788
Jon Hall5cf14d52015-07-16 12:15:19 -07002789 description = "Check that Leadership Election is still functional"
2790 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002791 # NOTE: Need to re-run since being a canidate is not persistant
2792 # TODO: add check for "Command not found:" in the driver, this
2793 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002794
acsmars71adceb2015-08-31 15:09:26 -07002795 oldLeaders = [] # leaders by node before withdrawl from candidates
2796 newLeaders = [] # leaders by node after withdrawl from candidates
2797 oldAllCandidates = [] # list of lists of each nodes' candidates before
2798 newAllCandidates = [] # list of lists of each nodes' candidates after
2799 oldCandidates = [] # list of candidates from node 0 before withdrawl
2800 newCandidates = [] # list of candidates from node 0 after withdrawl
2801 oldLeader = '' # the old leader from oldLeaders, None if not same
2802 newLeader = '' # the new leaders fron newLoeaders, None if not same
2803 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2804 expectNoLeader = False # True when there is only one leader
2805 if main.numCtrls == 1:
2806 expectNoLeader = True
2807
2808 main.step( "Run for election on each node" )
2809 electionResult = main.TRUE
2810
2811 for cli in main.CLIs: # run test election on each node
2812 if cli.electionTestRun() == main.FALSE:
2813 electionResult = main.FALSE
2814
Jon Hall5cf14d52015-07-16 12:15:19 -07002815 utilities.assert_equals(
2816 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002817 actual=electionResult,
2818 onpass="All nodes successfully ran for leadership",
2819 onfail="At least one node failed to run for leadership" )
2820
acsmars3a72bde2015-09-02 14:16:22 -07002821 if electionResult == main.FALSE:
2822 main.log.error(
2823 "Skipping Test Case because Election Test App isn't loaded" )
2824 main.skipCase()
2825
acsmars71adceb2015-08-31 15:09:26 -07002826 main.step( "Check that each node shows the same leader and candidates" )
2827 sameResult = main.TRUE
2828 failMessage = "Nodes have different leaders"
2829 for cli in main.CLIs:
2830 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2831 oldAllCandidates.append( node )
2832 oldLeaders.append( node[ 0 ] )
2833 oldCandidates = oldAllCandidates[ 0 ]
2834
2835 # Check that each node has the same leader. Defines oldLeader
2836 if len( set( oldLeaders ) ) != 1:
2837 sameResult = main.FALSE
2838 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2839 oldLeader = None
2840 else:
2841 oldLeader = oldLeaders[ 0 ]
2842
2843 # Check that each node's candidate list is the same
2844 for candidates in oldAllCandidates:
2845 if set( candidates ) != set( oldCandidates ):
2846 sameResult = main.FALSE
2847 failMessage += "and candidates"
2848
2849 utilities.assert_equals(
2850 expect=main.TRUE,
2851 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002852 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002853 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002854
2855 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002856 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002857 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002858 if oldLeader is None:
2859 main.log.error( "Leadership isn't consistent." )
2860 withdrawResult = main.FALSE
2861 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002862 for i in range( len( main.CLIs ) ):
acsmars71adceb2015-08-31 15:09:26 -07002863 if oldLeader == main.nodes[ i ].ip_address:
2864 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002865 break
2866 else: # FOR/ELSE statement
2867 main.log.error( "Leader election, could not find current leader" )
2868 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002869 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002870 utilities.assert_equals(
2871 expect=main.TRUE,
2872 actual=withdrawResult,
2873 onpass="Node was withdrawn from election",
2874 onfail="Node was not withdrawn from election" )
2875
acsmars71adceb2015-08-31 15:09:26 -07002876 main.step( "Check that a new node was elected leader" )
2877
Jon Hall5cf14d52015-07-16 12:15:19 -07002878 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002879 newLeaderResult = main.TRUE
2880 failMessage = "Nodes have different leaders"
2881
2882 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002883 for cli in main.CLIs:
acsmars71adceb2015-08-31 15:09:26 -07002884 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2885 # elections might no have finished yet
2886 if node[ 0 ] == 'none' and not expectNoLeader:
2887 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2888 "sure elections are complete." )
2889 time.sleep(5)
2890 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2891 # election still isn't done or there is a problem
2892 if node[ 0 ] == 'none':
2893 main.log.error( "No leader was elected on at least 1 node" )
2894 newLeaderResult = main.FALSE
2895 newAllCandidates.append( node )
2896 newLeaders.append( node[ 0 ] )
2897 newCandidates = newAllCandidates[ 0 ]
2898
2899 # Check that each node has the same leader. Defines newLeader
2900 if len( set( newLeaders ) ) != 1:
2901 newLeaderResult = main.FALSE
2902 main.log.error( "Nodes have different leaders: " +
2903 str( newLeaders ) )
2904 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002905 else:
acsmars71adceb2015-08-31 15:09:26 -07002906 newLeader = newLeaders[ 0 ]
2907
2908 # Check that each node's candidate list is the same
2909 for candidates in newAllCandidates:
2910 if set( candidates ) != set( newCandidates ):
2911 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002912 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002913
2914 # Check that the new leader is not the older leader, which was withdrawn
2915 if newLeader == oldLeader:
2916 newLeaderResult = main.FALSE
2917 main.log.error( "All nodes still see old leader: " + oldLeader +
2918 " as the current leader" )
2919
Jon Hall5cf14d52015-07-16 12:15:19 -07002920 utilities.assert_equals(
2921 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002922 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002923 onpass="Leadership election passed",
2924 onfail="Something went wrong with Leadership election" )
2925
acsmars71adceb2015-08-31 15:09:26 -07002926 main.step( "Check that that new leader was the candidate of old leader")
2927 # candidates[ 2 ] should be come the top candidate after withdrawl
2928 correctCandidateResult = main.TRUE
2929 if expectNoLeader:
2930 if newLeader == 'none':
2931 main.log.info( "No leader expected. None found. Pass" )
2932 correctCandidateResult = main.TRUE
2933 else:
2934 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2935 correctCandidateResult = main.FALSE
2936 elif newLeader != oldCandidates[ 2 ]:
2937 correctCandidateResult = main.FALSE
2938 main.log.error( "Candidate " + newLeader + " was elected. " +
2939 oldCandidates[ 2 ] + " should have had priority." )
2940
2941 utilities.assert_equals(
2942 expect=main.TRUE,
2943 actual=correctCandidateResult,
2944 onpass="Correct Candidate Elected",
2945 onfail="Incorrect Candidate Elected" )
2946
Jon Hall5cf14d52015-07-16 12:15:19 -07002947 main.step( "Run for election on old leader( just so everyone " +
2948 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002949 if oldLeaderCLI is not None:
2950 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002951 else:
acsmars71adceb2015-08-31 15:09:26 -07002952 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002953 runResult = main.FALSE
2954 utilities.assert_equals(
2955 expect=main.TRUE,
2956 actual=runResult,
2957 onpass="App re-ran for election",
2958 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002959 main.step(
2960 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002961 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07002962 positionResult = main.TRUE
2963 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
2964
2965 # Reset and reuse the new candidate and leaders lists
2966 newAllCandidates = []
2967 newCandidates = []
2968 newLeaders = []
2969 for cli in main.CLIs:
2970 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2971 if oldLeader not in node: # election might no have finished yet
2972 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2973 "be sure elections are complete" )
2974 time.sleep(5)
2975 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2976 if oldLeader not in node: # election still isn't done, errors
2977 main.log.error(
2978 "Old leader was not elected on at least one node" )
2979 positionResult = main.FALSE
2980 newAllCandidates.append( node )
2981 newLeaders.append( node[ 0 ] )
2982 newCandidates = newAllCandidates[ 0 ]
2983
2984 # Check that each node has the same leader. Defines newLeader
2985 if len( set( newLeaders ) ) != 1:
2986 positionResult = main.FALSE
2987 main.log.error( "Nodes have different leaders: " +
2988 str( newLeaders ) )
2989 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002990 else:
acsmars71adceb2015-08-31 15:09:26 -07002991 newLeader = newLeaders[ 0 ]
2992
2993 # Check that each node's candidate list is the same
2994 for candidates in newAllCandidates:
2995 if set( candidates ) != set( newCandidates ):
2996 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002997 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002998
2999 # Check that the re-elected node is last on the candidate List
3000 if oldLeader != newCandidates[ -1 ]:
3001 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3002 str( newCandidates ) )
3003 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003004
3005 utilities.assert_equals(
3006 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07003007 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003008 onpass="Old leader successfully re-ran for election",
3009 onfail="Something went wrong with Leadership election after " +
3010 "the old leader re-ran for election" )
3011
3012 def CASE16( self, main ):
3013 """
3014 Install Distributed Primitives app
3015 """
3016 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003017 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003018 assert main, "main not defined"
3019 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003020 assert main.CLIs, "main.CLIs not defined"
3021 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003022
3023 # Variables for the distributed primitives tests
3024 global pCounterName
3025 global iCounterName
3026 global pCounterValue
3027 global iCounterValue
3028 global onosSet
3029 global onosSetName
3030 pCounterName = "TestON-Partitions"
3031 iCounterName = "TestON-inMemory"
3032 pCounterValue = 0
3033 iCounterValue = 0
3034 onosSet = set([])
3035 onosSetName = "TestON-set"
3036
3037 description = "Install Primitives app"
3038 main.case( description )
3039 main.step( "Install Primitives app" )
3040 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003041 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003042 utilities.assert_equals( expect=main.TRUE,
3043 actual=appResults,
3044 onpass="Primitives app activated",
3045 onfail="Primitives app not activated" )
3046 time.sleep( 5 ) # To allow all nodes to activate
3047
3048 def CASE17( self, main ):
3049 """
3050 Check for basic functionality with distributed primitives
3051 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003052 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003053 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003054 assert main, "main not defined"
3055 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003056 assert main.CLIs, "main.CLIs not defined"
3057 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003058 assert pCounterName, "pCounterName not defined"
3059 assert iCounterName, "iCounterName not defined"
3060 assert onosSetName, "onosSetName not defined"
3061 # NOTE: assert fails if value is 0/None/Empty/False
3062 try:
3063 pCounterValue
3064 except NameError:
3065 main.log.error( "pCounterValue not defined, setting to 0" )
3066 pCounterValue = 0
3067 try:
3068 iCounterValue
3069 except NameError:
3070 main.log.error( "iCounterValue not defined, setting to 0" )
3071 iCounterValue = 0
3072 try:
3073 onosSet
3074 except NameError:
3075 main.log.error( "onosSet not defined, setting to empty Set" )
3076 onosSet = set([])
3077 # Variables for the distributed primitives tests. These are local only
3078 addValue = "a"
3079 addAllValue = "a b c d e f"
3080 retainValue = "c d e f"
3081
3082 description = "Check for basic functionality with distributed " +\
3083 "primitives"
3084 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003085 main.caseExplanation = "Test the methods of the distributed " +\
3086 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003087 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003088 # Partitioned counters
3089 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003090 pCounters = []
3091 threads = []
3092 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003093 for i in range( main.numCtrls ):
3094 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3095 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003096 args=[ pCounterName ] )
3097 pCounterValue += 1
3098 addedPValues.append( pCounterValue )
3099 threads.append( t )
3100 t.start()
3101
3102 for t in threads:
3103 t.join()
3104 pCounters.append( t.result )
3105 # Check that counter incremented numController times
3106 pCounterResults = True
3107 for i in addedPValues:
3108 tmpResult = i in pCounters
3109 pCounterResults = pCounterResults and tmpResult
3110 if not tmpResult:
3111 main.log.error( str( i ) + " is not in partitioned "
3112 "counter incremented results" )
3113 utilities.assert_equals( expect=True,
3114 actual=pCounterResults,
3115 onpass="Default counter incremented",
3116 onfail="Error incrementing default" +
3117 " counter" )
3118
Jon Halle1a3b752015-07-22 13:02:46 -07003119 main.step( "Get then Increment a default counter on each node" )
3120 pCounters = []
3121 threads = []
3122 addedPValues = []
3123 for i in range( main.numCtrls ):
3124 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3125 name="counterGetAndAdd-" + str( i ),
3126 args=[ pCounterName ] )
3127 addedPValues.append( pCounterValue )
3128 pCounterValue += 1
3129 threads.append( t )
3130 t.start()
3131
3132 for t in threads:
3133 t.join()
3134 pCounters.append( t.result )
3135 # Check that counter incremented numController times
3136 pCounterResults = True
3137 for i in addedPValues:
3138 tmpResult = i in pCounters
3139 pCounterResults = pCounterResults and tmpResult
3140 if not tmpResult:
3141 main.log.error( str( i ) + " is not in partitioned "
3142 "counter incremented results" )
3143 utilities.assert_equals( expect=True,
3144 actual=pCounterResults,
3145 onpass="Default counter incremented",
3146 onfail="Error incrementing default" +
3147 " counter" )
3148
3149 main.step( "Counters we added have the correct values" )
3150 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3151 utilities.assert_equals( expect=main.TRUE,
3152 actual=incrementCheck,
3153 onpass="Added counters are correct",
3154 onfail="Added counters are incorrect" )
3155
3156 main.step( "Add -8 to then get a default counter on each node" )
3157 pCounters = []
3158 threads = []
3159 addedPValues = []
3160 for i in range( main.numCtrls ):
3161 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3162 name="counterIncrement-" + str( i ),
3163 args=[ pCounterName ],
3164 kwargs={ "delta": -8 } )
3165 pCounterValue += -8
3166 addedPValues.append( pCounterValue )
3167 threads.append( t )
3168 t.start()
3169
3170 for t in threads:
3171 t.join()
3172 pCounters.append( t.result )
3173 # Check that counter incremented numController times
3174 pCounterResults = True
3175 for i in addedPValues:
3176 tmpResult = i in pCounters
3177 pCounterResults = pCounterResults and tmpResult
3178 if not tmpResult:
3179 main.log.error( str( i ) + " is not in partitioned "
3180 "counter incremented results" )
3181 utilities.assert_equals( expect=True,
3182 actual=pCounterResults,
3183 onpass="Default counter incremented",
3184 onfail="Error incrementing default" +
3185 " counter" )
3186
3187 main.step( "Add 5 to then get a default counter on each node" )
3188 pCounters = []
3189 threads = []
3190 addedPValues = []
3191 for i in range( main.numCtrls ):
3192 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3193 name="counterIncrement-" + str( i ),
3194 args=[ pCounterName ],
3195 kwargs={ "delta": 5 } )
3196 pCounterValue += 5
3197 addedPValues.append( pCounterValue )
3198 threads.append( t )
3199 t.start()
3200
3201 for t in threads:
3202 t.join()
3203 pCounters.append( t.result )
3204 # Check that counter incremented numController times
3205 pCounterResults = True
3206 for i in addedPValues:
3207 tmpResult = i in pCounters
3208 pCounterResults = pCounterResults and tmpResult
3209 if not tmpResult:
3210 main.log.error( str( i ) + " is not in partitioned "
3211 "counter incremented results" )
3212 utilities.assert_equals( expect=True,
3213 actual=pCounterResults,
3214 onpass="Default counter incremented",
3215 onfail="Error incrementing default" +
3216 " counter" )
3217
3218 main.step( "Get then add 5 to a default counter on each node" )
3219 pCounters = []
3220 threads = []
3221 addedPValues = []
3222 for i in range( main.numCtrls ):
3223 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3224 name="counterIncrement-" + str( i ),
3225 args=[ pCounterName ],
3226 kwargs={ "delta": 5 } )
3227 addedPValues.append( pCounterValue )
3228 pCounterValue += 5
3229 threads.append( t )
3230 t.start()
3231
3232 for t in threads:
3233 t.join()
3234 pCounters.append( t.result )
3235 # Check that counter incremented numController times
3236 pCounterResults = True
3237 for i in addedPValues:
3238 tmpResult = i in pCounters
3239 pCounterResults = pCounterResults and tmpResult
3240 if not tmpResult:
3241 main.log.error( str( i ) + " is not in partitioned "
3242 "counter incremented results" )
3243 utilities.assert_equals( expect=True,
3244 actual=pCounterResults,
3245 onpass="Default counter incremented",
3246 onfail="Error incrementing default" +
3247 " counter" )
3248
3249 main.step( "Counters we added have the correct values" )
3250 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3251 utilities.assert_equals( expect=main.TRUE,
3252 actual=incrementCheck,
3253 onpass="Added counters are correct",
3254 onfail="Added counters are incorrect" )
3255
3256 # In-Memory counters
3257 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003258 iCounters = []
3259 addedIValues = []
3260 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003261 for i in range( main.numCtrls ):
3262 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003263 name="icounterIncrement-" + str( i ),
3264 args=[ iCounterName ],
3265 kwargs={ "inMemory": True } )
3266 iCounterValue += 1
3267 addedIValues.append( iCounterValue )
3268 threads.append( t )
3269 t.start()
3270
3271 for t in threads:
3272 t.join()
3273 iCounters.append( t.result )
3274 # Check that counter incremented numController times
3275 iCounterResults = True
3276 for i in addedIValues:
3277 tmpResult = i in iCounters
3278 iCounterResults = iCounterResults and tmpResult
3279 if not tmpResult:
3280 main.log.error( str( i ) + " is not in the in-memory "
3281 "counter incremented results" )
3282 utilities.assert_equals( expect=True,
3283 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003284 onpass="In-memory counter incremented",
3285 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003286 " counter" )
3287
Jon Halle1a3b752015-07-22 13:02:46 -07003288 main.step( "Get then Increment a in-memory counter on each node" )
3289 iCounters = []
3290 threads = []
3291 addedIValues = []
3292 for i in range( main.numCtrls ):
3293 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3294 name="counterGetAndAdd-" + str( i ),
3295 args=[ iCounterName ],
3296 kwargs={ "inMemory": True } )
3297 addedIValues.append( iCounterValue )
3298 iCounterValue += 1
3299 threads.append( t )
3300 t.start()
3301
3302 for t in threads:
3303 t.join()
3304 iCounters.append( t.result )
3305 # Check that counter incremented numController times
3306 iCounterResults = True
3307 for i in addedIValues:
3308 tmpResult = i in iCounters
3309 iCounterResults = iCounterResults and tmpResult
3310 if not tmpResult:
3311 main.log.error( str( i ) + " is not in in-memory "
3312 "counter incremented results" )
3313 utilities.assert_equals( expect=True,
3314 actual=iCounterResults,
3315 onpass="In-memory counter incremented",
3316 onfail="Error incrementing in-memory" +
3317 " counter" )
3318
3319 main.step( "Counters we added have the correct values" )
3320 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3321 utilities.assert_equals( expect=main.TRUE,
3322 actual=incrementCheck,
3323 onpass="Added counters are correct",
3324 onfail="Added counters are incorrect" )
3325
3326 main.step( "Add -8 to then get a in-memory counter on each node" )
3327 iCounters = []
3328 threads = []
3329 addedIValues = []
3330 for i in range( main.numCtrls ):
3331 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3332 name="counterIncrement-" + str( i ),
3333 args=[ iCounterName ],
3334 kwargs={ "delta": -8, "inMemory": True } )
3335 iCounterValue += -8
3336 addedIValues.append( iCounterValue )
3337 threads.append( t )
3338 t.start()
3339
3340 for t in threads:
3341 t.join()
3342 iCounters.append( t.result )
3343 # Check that counter incremented numController times
3344 iCounterResults = True
3345 for i in addedIValues:
3346 tmpResult = i in iCounters
3347 iCounterResults = iCounterResults and tmpResult
3348 if not tmpResult:
3349 main.log.error( str( i ) + " is not in in-memory "
3350 "counter incremented results" )
3351 utilities.assert_equals( expect=True,
3352 actual=pCounterResults,
3353 onpass="In-memory counter incremented",
3354 onfail="Error incrementing in-memory" +
3355 " counter" )
3356
3357 main.step( "Add 5 to then get a in-memory counter on each node" )
3358 iCounters = []
3359 threads = []
3360 addedIValues = []
3361 for i in range( main.numCtrls ):
3362 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3363 name="counterIncrement-" + str( i ),
3364 args=[ iCounterName ],
3365 kwargs={ "delta": 5, "inMemory": True } )
3366 iCounterValue += 5
3367 addedIValues.append( iCounterValue )
3368 threads.append( t )
3369 t.start()
3370
3371 for t in threads:
3372 t.join()
3373 iCounters.append( t.result )
3374 # Check that counter incremented numController times
3375 iCounterResults = True
3376 for i in addedIValues:
3377 tmpResult = i in iCounters
3378 iCounterResults = iCounterResults and tmpResult
3379 if not tmpResult:
3380 main.log.error( str( i ) + " is not in in-memory "
3381 "counter incremented results" )
3382 utilities.assert_equals( expect=True,
3383 actual=pCounterResults,
3384 onpass="In-memory counter incremented",
3385 onfail="Error incrementing in-memory" +
3386 " counter" )
3387
3388 main.step( "Get then add 5 to a in-memory counter on each node" )
3389 iCounters = []
3390 threads = []
3391 addedIValues = []
3392 for i in range( main.numCtrls ):
3393 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3394 name="counterIncrement-" + str( i ),
3395 args=[ iCounterName ],
3396 kwargs={ "delta": 5, "inMemory": True } )
3397 addedIValues.append( iCounterValue )
3398 iCounterValue += 5
3399 threads.append( t )
3400 t.start()
3401
3402 for t in threads:
3403 t.join()
3404 iCounters.append( t.result )
3405 # Check that counter incremented numController times
3406 iCounterResults = True
3407 for i in addedIValues:
3408 tmpResult = i in iCounters
3409 iCounterResults = iCounterResults and tmpResult
3410 if not tmpResult:
3411 main.log.error( str( i ) + " is not in in-memory "
3412 "counter incremented results" )
3413 utilities.assert_equals( expect=True,
3414 actual=iCounterResults,
3415 onpass="In-memory counter incremented",
3416 onfail="Error incrementing in-memory" +
3417 " counter" )
3418
3419 main.step( "Counters we added have the correct values" )
3420 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3421 utilities.assert_equals( expect=main.TRUE,
3422 actual=incrementCheck,
3423 onpass="Added counters are correct",
3424 onfail="Added counters are incorrect" )
3425
Jon Hall5cf14d52015-07-16 12:15:19 -07003426 main.step( "Check counters are consistant across nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07003427 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003428 utilities.assert_equals( expect=main.TRUE,
3429 actual=consistentCounterResults,
3430 onpass="ONOS counters are consistent " +
3431 "across nodes",
3432 onfail="ONOS Counters are inconsistent " +
3433 "across nodes" )
3434
3435 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003436 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3437 incrementCheck = incrementCheck and \
3438 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003439 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003440 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003441 onpass="Added counters are correct",
3442 onfail="Added counters are incorrect" )
3443 # DISTRIBUTED SETS
3444 main.step( "Distributed Set get" )
3445 size = len( onosSet )
3446 getResponses = []
3447 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003448 for i in range( main.numCtrls ):
3449 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003450 name="setTestGet-" + str( i ),
3451 args=[ onosSetName ] )
3452 threads.append( t )
3453 t.start()
3454 for t in threads:
3455 t.join()
3456 getResponses.append( t.result )
3457
3458 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003459 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003460 if isinstance( getResponses[ i ], list):
3461 current = set( getResponses[ i ] )
3462 if len( current ) == len( getResponses[ i ] ):
3463 # no repeats
3464 if onosSet != current:
3465 main.log.error( "ONOS" + str( i + 1 ) +
3466 " has incorrect view" +
3467 " of set " + onosSetName + ":\n" +
3468 str( getResponses[ i ] ) )
3469 main.log.debug( "Expected: " + str( onosSet ) )
3470 main.log.debug( "Actual: " + str( current ) )
3471 getResults = main.FALSE
3472 else:
3473 # error, set is not a set
3474 main.log.error( "ONOS" + str( i + 1 ) +
3475 " has repeat elements in" +
3476 " set " + onosSetName + ":\n" +
3477 str( getResponses[ i ] ) )
3478 getResults = main.FALSE
3479 elif getResponses[ i ] == main.ERROR:
3480 getResults = main.FALSE
3481 utilities.assert_equals( expect=main.TRUE,
3482 actual=getResults,
3483 onpass="Set elements are correct",
3484 onfail="Set elements are incorrect" )
3485
3486 main.step( "Distributed Set size" )
3487 sizeResponses = []
3488 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003489 for i in range( main.numCtrls ):
3490 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003491 name="setTestSize-" + str( i ),
3492 args=[ onosSetName ] )
3493 threads.append( t )
3494 t.start()
3495 for t in threads:
3496 t.join()
3497 sizeResponses.append( t.result )
3498
3499 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003500 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003501 if size != sizeResponses[ i ]:
3502 sizeResults = main.FALSE
3503 main.log.error( "ONOS" + str( i + 1 ) +
3504 " expected a size of " + str( size ) +
3505 " for set " + onosSetName +
3506 " but got " + str( sizeResponses[ i ] ) )
3507 utilities.assert_equals( expect=main.TRUE,
3508 actual=sizeResults,
3509 onpass="Set sizes are correct",
3510 onfail="Set sizes are incorrect" )
3511
3512 main.step( "Distributed Set add()" )
3513 onosSet.add( addValue )
3514 addResponses = []
3515 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003516 for i in range( main.numCtrls ):
3517 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003518 name="setTestAdd-" + str( i ),
3519 args=[ onosSetName, addValue ] )
3520 threads.append( t )
3521 t.start()
3522 for t in threads:
3523 t.join()
3524 addResponses.append( t.result )
3525
3526 # main.TRUE = successfully changed the set
3527 # main.FALSE = action resulted in no change in set
3528 # main.ERROR - Some error in executing the function
3529 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003530 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003531 if addResponses[ i ] == main.TRUE:
3532 # All is well
3533 pass
3534 elif addResponses[ i ] == main.FALSE:
3535 # Already in set, probably fine
3536 pass
3537 elif addResponses[ i ] == main.ERROR:
3538 # Error in execution
3539 addResults = main.FALSE
3540 else:
3541 # unexpected result
3542 addResults = main.FALSE
3543 if addResults != main.TRUE:
3544 main.log.error( "Error executing set add" )
3545
3546 # Check if set is still correct
3547 size = len( onosSet )
3548 getResponses = []
3549 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003550 for i in range( main.numCtrls ):
3551 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003552 name="setTestGet-" + str( i ),
3553 args=[ onosSetName ] )
3554 threads.append( t )
3555 t.start()
3556 for t in threads:
3557 t.join()
3558 getResponses.append( t.result )
3559 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003560 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003561 if isinstance( getResponses[ i ], list):
3562 current = set( getResponses[ i ] )
3563 if len( current ) == len( getResponses[ i ] ):
3564 # no repeats
3565 if onosSet != current:
3566 main.log.error( "ONOS" + str( i + 1 ) +
3567 " has incorrect view" +
3568 " of set " + onosSetName + ":\n" +
3569 str( getResponses[ i ] ) )
3570 main.log.debug( "Expected: " + str( onosSet ) )
3571 main.log.debug( "Actual: " + str( current ) )
3572 getResults = main.FALSE
3573 else:
3574 # error, set is not a set
3575 main.log.error( "ONOS" + str( i + 1 ) +
3576 " has repeat elements in" +
3577 " set " + onosSetName + ":\n" +
3578 str( getResponses[ i ] ) )
3579 getResults = main.FALSE
3580 elif getResponses[ i ] == main.ERROR:
3581 getResults = main.FALSE
3582 sizeResponses = []
3583 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003584 for i in range( main.numCtrls ):
3585 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003586 name="setTestSize-" + str( i ),
3587 args=[ onosSetName ] )
3588 threads.append( t )
3589 t.start()
3590 for t in threads:
3591 t.join()
3592 sizeResponses.append( t.result )
3593 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003594 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003595 if size != sizeResponses[ i ]:
3596 sizeResults = main.FALSE
3597 main.log.error( "ONOS" + str( i + 1 ) +
3598 " expected a size of " + str( size ) +
3599 " for set " + onosSetName +
3600 " but got " + str( sizeResponses[ i ] ) )
3601 addResults = addResults and getResults and sizeResults
3602 utilities.assert_equals( expect=main.TRUE,
3603 actual=addResults,
3604 onpass="Set add correct",
3605 onfail="Set add was incorrect" )
3606
3607 main.step( "Distributed Set addAll()" )
3608 onosSet.update( addAllValue.split() )
3609 addResponses = []
3610 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003611 for i in range( main.numCtrls ):
3612 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003613 name="setTestAddAll-" + str( i ),
3614 args=[ onosSetName, addAllValue ] )
3615 threads.append( t )
3616 t.start()
3617 for t in threads:
3618 t.join()
3619 addResponses.append( t.result )
3620
3621 # main.TRUE = successfully changed the set
3622 # main.FALSE = action resulted in no change in set
3623 # main.ERROR - Some error in executing the function
3624 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003625 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003626 if addResponses[ i ] == main.TRUE:
3627 # All is well
3628 pass
3629 elif addResponses[ i ] == main.FALSE:
3630 # Already in set, probably fine
3631 pass
3632 elif addResponses[ i ] == main.ERROR:
3633 # Error in execution
3634 addAllResults = main.FALSE
3635 else:
3636 # unexpected result
3637 addAllResults = main.FALSE
3638 if addAllResults != main.TRUE:
3639 main.log.error( "Error executing set addAll" )
3640
3641 # Check if set is still correct
3642 size = len( onosSet )
3643 getResponses = []
3644 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003645 for i in range( main.numCtrls ):
3646 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003647 name="setTestGet-" + str( i ),
3648 args=[ onosSetName ] )
3649 threads.append( t )
3650 t.start()
3651 for t in threads:
3652 t.join()
3653 getResponses.append( t.result )
3654 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003655 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003656 if isinstance( getResponses[ i ], list):
3657 current = set( getResponses[ i ] )
3658 if len( current ) == len( getResponses[ i ] ):
3659 # no repeats
3660 if onosSet != current:
3661 main.log.error( "ONOS" + str( i + 1 ) +
3662 " has incorrect view" +
3663 " of set " + onosSetName + ":\n" +
3664 str( getResponses[ i ] ) )
3665 main.log.debug( "Expected: " + str( onosSet ) )
3666 main.log.debug( "Actual: " + str( current ) )
3667 getResults = main.FALSE
3668 else:
3669 # error, set is not a set
3670 main.log.error( "ONOS" + str( i + 1 ) +
3671 " has repeat elements in" +
3672 " set " + onosSetName + ":\n" +
3673 str( getResponses[ i ] ) )
3674 getResults = main.FALSE
3675 elif getResponses[ i ] == main.ERROR:
3676 getResults = main.FALSE
3677 sizeResponses = []
3678 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003679 for i in range( main.numCtrls ):
3680 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003681 name="setTestSize-" + str( i ),
3682 args=[ onosSetName ] )
3683 threads.append( t )
3684 t.start()
3685 for t in threads:
3686 t.join()
3687 sizeResponses.append( t.result )
3688 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003689 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003690 if size != sizeResponses[ i ]:
3691 sizeResults = main.FALSE
3692 main.log.error( "ONOS" + str( i + 1 ) +
3693 " expected a size of " + str( size ) +
3694 " for set " + onosSetName +
3695 " but got " + str( sizeResponses[ i ] ) )
3696 addAllResults = addAllResults and getResults and sizeResults
3697 utilities.assert_equals( expect=main.TRUE,
3698 actual=addAllResults,
3699 onpass="Set addAll correct",
3700 onfail="Set addAll was incorrect" )
3701
3702 main.step( "Distributed Set contains()" )
3703 containsResponses = []
3704 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003705 for i in range( main.numCtrls ):
3706 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003707 name="setContains-" + str( i ),
3708 args=[ onosSetName ],
3709 kwargs={ "values": addValue } )
3710 threads.append( t )
3711 t.start()
3712 for t in threads:
3713 t.join()
3714 # NOTE: This is the tuple
3715 containsResponses.append( t.result )
3716
3717 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003718 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003719 if containsResponses[ i ] == main.ERROR:
3720 containsResults = main.FALSE
3721 else:
3722 containsResults = containsResults and\
3723 containsResponses[ i ][ 1 ]
3724 utilities.assert_equals( expect=main.TRUE,
3725 actual=containsResults,
3726 onpass="Set contains is functional",
3727 onfail="Set contains failed" )
3728
3729 main.step( "Distributed Set containsAll()" )
3730 containsAllResponses = []
3731 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003732 for i in range( main.numCtrls ):
3733 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003734 name="setContainsAll-" + str( i ),
3735 args=[ onosSetName ],
3736 kwargs={ "values": addAllValue } )
3737 threads.append( t )
3738 t.start()
3739 for t in threads:
3740 t.join()
3741 # NOTE: This is the tuple
3742 containsAllResponses.append( t.result )
3743
3744 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003745 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003746 if containsResponses[ i ] == main.ERROR:
3747 containsResults = main.FALSE
3748 else:
3749 containsResults = containsResults and\
3750 containsResponses[ i ][ 1 ]
3751 utilities.assert_equals( expect=main.TRUE,
3752 actual=containsAllResults,
3753 onpass="Set containsAll is functional",
3754 onfail="Set containsAll failed" )
3755
3756 main.step( "Distributed Set remove()" )
3757 onosSet.remove( addValue )
3758 removeResponses = []
3759 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003760 for i in range( main.numCtrls ):
3761 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003762 name="setTestRemove-" + str( i ),
3763 args=[ onosSetName, addValue ] )
3764 threads.append( t )
3765 t.start()
3766 for t in threads:
3767 t.join()
3768 removeResponses.append( t.result )
3769
3770 # main.TRUE = successfully changed the set
3771 # main.FALSE = action resulted in no change in set
3772 # main.ERROR - Some error in executing the function
3773 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003774 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003775 if removeResponses[ i ] == main.TRUE:
3776 # All is well
3777 pass
3778 elif removeResponses[ i ] == main.FALSE:
3779 # not in set, probably fine
3780 pass
3781 elif removeResponses[ i ] == main.ERROR:
3782 # Error in execution
3783 removeResults = main.FALSE
3784 else:
3785 # unexpected result
3786 removeResults = main.FALSE
3787 if removeResults != main.TRUE:
3788 main.log.error( "Error executing set remove" )
3789
3790 # Check if set is still correct
3791 size = len( onosSet )
3792 getResponses = []
3793 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003794 for i in range( main.numCtrls ):
3795 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003796 name="setTestGet-" + str( i ),
3797 args=[ onosSetName ] )
3798 threads.append( t )
3799 t.start()
3800 for t in threads:
3801 t.join()
3802 getResponses.append( t.result )
3803 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003804 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003805 if isinstance( getResponses[ i ], list):
3806 current = set( getResponses[ i ] )
3807 if len( current ) == len( getResponses[ i ] ):
3808 # no repeats
3809 if onosSet != current:
3810 main.log.error( "ONOS" + str( i + 1 ) +
3811 " has incorrect view" +
3812 " of set " + onosSetName + ":\n" +
3813 str( getResponses[ i ] ) )
3814 main.log.debug( "Expected: " + str( onosSet ) )
3815 main.log.debug( "Actual: " + str( current ) )
3816 getResults = main.FALSE
3817 else:
3818 # error, set is not a set
3819 main.log.error( "ONOS" + str( i + 1 ) +
3820 " has repeat elements in" +
3821 " set " + onosSetName + ":\n" +
3822 str( getResponses[ i ] ) )
3823 getResults = main.FALSE
3824 elif getResponses[ i ] == main.ERROR:
3825 getResults = main.FALSE
3826 sizeResponses = []
3827 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003828 for i in range( main.numCtrls ):
3829 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003830 name="setTestSize-" + str( i ),
3831 args=[ onosSetName ] )
3832 threads.append( t )
3833 t.start()
3834 for t in threads:
3835 t.join()
3836 sizeResponses.append( t.result )
3837 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003838 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003839 if size != sizeResponses[ i ]:
3840 sizeResults = main.FALSE
3841 main.log.error( "ONOS" + str( i + 1 ) +
3842 " expected a size of " + str( size ) +
3843 " for set " + onosSetName +
3844 " but got " + str( sizeResponses[ i ] ) )
3845 removeResults = removeResults and getResults and sizeResults
3846 utilities.assert_equals( expect=main.TRUE,
3847 actual=removeResults,
3848 onpass="Set remove correct",
3849 onfail="Set remove was incorrect" )
3850
3851 main.step( "Distributed Set removeAll()" )
3852 onosSet.difference_update( addAllValue.split() )
3853 removeAllResponses = []
3854 threads = []
3855 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003856 for i in range( main.numCtrls ):
3857 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003858 name="setTestRemoveAll-" + str( i ),
3859 args=[ onosSetName, addAllValue ] )
3860 threads.append( t )
3861 t.start()
3862 for t in threads:
3863 t.join()
3864 removeAllResponses.append( t.result )
3865 except Exception, e:
3866 main.log.exception(e)
3867
3868 # main.TRUE = successfully changed the set
3869 # main.FALSE = action resulted in no change in set
3870 # main.ERROR - Some error in executing the function
3871 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003872 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003873 if removeAllResponses[ i ] == main.TRUE:
3874 # All is well
3875 pass
3876 elif removeAllResponses[ i ] == main.FALSE:
3877 # not in set, probably fine
3878 pass
3879 elif removeAllResponses[ i ] == main.ERROR:
3880 # Error in execution
3881 removeAllResults = main.FALSE
3882 else:
3883 # unexpected result
3884 removeAllResults = main.FALSE
3885 if removeAllResults != main.TRUE:
3886 main.log.error( "Error executing set removeAll" )
3887
3888 # Check if set is still correct
3889 size = len( onosSet )
3890 getResponses = []
3891 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003892 for i in range( main.numCtrls ):
3893 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003894 name="setTestGet-" + str( i ),
3895 args=[ onosSetName ] )
3896 threads.append( t )
3897 t.start()
3898 for t in threads:
3899 t.join()
3900 getResponses.append( t.result )
3901 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003902 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003903 if isinstance( getResponses[ i ], list):
3904 current = set( getResponses[ i ] )
3905 if len( current ) == len( getResponses[ i ] ):
3906 # no repeats
3907 if onosSet != current:
3908 main.log.error( "ONOS" + str( i + 1 ) +
3909 " has incorrect view" +
3910 " of set " + onosSetName + ":\n" +
3911 str( getResponses[ i ] ) )
3912 main.log.debug( "Expected: " + str( onosSet ) )
3913 main.log.debug( "Actual: " + str( current ) )
3914 getResults = main.FALSE
3915 else:
3916 # error, set is not a set
3917 main.log.error( "ONOS" + str( i + 1 ) +
3918 " has repeat elements in" +
3919 " set " + onosSetName + ":\n" +
3920 str( getResponses[ i ] ) )
3921 getResults = main.FALSE
3922 elif getResponses[ i ] == main.ERROR:
3923 getResults = main.FALSE
3924 sizeResponses = []
3925 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003926 for i in range( main.numCtrls ):
3927 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003928 name="setTestSize-" + str( i ),
3929 args=[ onosSetName ] )
3930 threads.append( t )
3931 t.start()
3932 for t in threads:
3933 t.join()
3934 sizeResponses.append( t.result )
3935 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003936 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003937 if size != sizeResponses[ i ]:
3938 sizeResults = main.FALSE
3939 main.log.error( "ONOS" + str( i + 1 ) +
3940 " expected a size of " + str( size ) +
3941 " for set " + onosSetName +
3942 " but got " + str( sizeResponses[ i ] ) )
3943 removeAllResults = removeAllResults and getResults and sizeResults
3944 utilities.assert_equals( expect=main.TRUE,
3945 actual=removeAllResults,
3946 onpass="Set removeAll correct",
3947 onfail="Set removeAll was incorrect" )
3948
3949 main.step( "Distributed Set addAll()" )
3950 onosSet.update( addAllValue.split() )
3951 addResponses = []
3952 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003953 for i in range( main.numCtrls ):
3954 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003955 name="setTestAddAll-" + str( i ),
3956 args=[ onosSetName, addAllValue ] )
3957 threads.append( t )
3958 t.start()
3959 for t in threads:
3960 t.join()
3961 addResponses.append( t.result )
3962
3963 # main.TRUE = successfully changed the set
3964 # main.FALSE = action resulted in no change in set
3965 # main.ERROR - Some error in executing the function
3966 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003967 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003968 if addResponses[ i ] == main.TRUE:
3969 # All is well
3970 pass
3971 elif addResponses[ i ] == main.FALSE:
3972 # Already in set, probably fine
3973 pass
3974 elif addResponses[ i ] == main.ERROR:
3975 # Error in execution
3976 addAllResults = main.FALSE
3977 else:
3978 # unexpected result
3979 addAllResults = main.FALSE
3980 if addAllResults != main.TRUE:
3981 main.log.error( "Error executing set addAll" )
3982
3983 # Check if set is still correct
3984 size = len( onosSet )
3985 getResponses = []
3986 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003987 for i in range( main.numCtrls ):
3988 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003989 name="setTestGet-" + str( i ),
3990 args=[ onosSetName ] )
3991 threads.append( t )
3992 t.start()
3993 for t in threads:
3994 t.join()
3995 getResponses.append( t.result )
3996 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003997 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003998 if isinstance( getResponses[ i ], list):
3999 current = set( getResponses[ i ] )
4000 if len( current ) == len( getResponses[ i ] ):
4001 # no repeats
4002 if onosSet != current:
4003 main.log.error( "ONOS" + str( i + 1 ) +
4004 " has incorrect view" +
4005 " of set " + onosSetName + ":\n" +
4006 str( getResponses[ i ] ) )
4007 main.log.debug( "Expected: " + str( onosSet ) )
4008 main.log.debug( "Actual: " + str( current ) )
4009 getResults = main.FALSE
4010 else:
4011 # error, set is not a set
4012 main.log.error( "ONOS" + str( i + 1 ) +
4013 " has repeat elements in" +
4014 " set " + onosSetName + ":\n" +
4015 str( getResponses[ i ] ) )
4016 getResults = main.FALSE
4017 elif getResponses[ i ] == main.ERROR:
4018 getResults = main.FALSE
4019 sizeResponses = []
4020 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004021 for i in range( main.numCtrls ):
4022 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004023 name="setTestSize-" + str( i ),
4024 args=[ onosSetName ] )
4025 threads.append( t )
4026 t.start()
4027 for t in threads:
4028 t.join()
4029 sizeResponses.append( t.result )
4030 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004031 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004032 if size != sizeResponses[ i ]:
4033 sizeResults = main.FALSE
4034 main.log.error( "ONOS" + str( i + 1 ) +
4035 " expected a size of " + str( size ) +
4036 " for set " + onosSetName +
4037 " but got " + str( sizeResponses[ i ] ) )
4038 addAllResults = addAllResults and getResults and sizeResults
4039 utilities.assert_equals( expect=main.TRUE,
4040 actual=addAllResults,
4041 onpass="Set addAll correct",
4042 onfail="Set addAll was incorrect" )
4043
4044 main.step( "Distributed Set clear()" )
4045 onosSet.clear()
4046 clearResponses = []
4047 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004048 for i in range( main.numCtrls ):
4049 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004050 name="setTestClear-" + str( i ),
4051 args=[ onosSetName, " "], # Values doesn't matter
4052 kwargs={ "clear": True } )
4053 threads.append( t )
4054 t.start()
4055 for t in threads:
4056 t.join()
4057 clearResponses.append( t.result )
4058
4059 # main.TRUE = successfully changed the set
4060 # main.FALSE = action resulted in no change in set
4061 # main.ERROR - Some error in executing the function
4062 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004063 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004064 if clearResponses[ i ] == main.TRUE:
4065 # All is well
4066 pass
4067 elif clearResponses[ i ] == main.FALSE:
4068 # Nothing set, probably fine
4069 pass
4070 elif clearResponses[ i ] == main.ERROR:
4071 # Error in execution
4072 clearResults = main.FALSE
4073 else:
4074 # unexpected result
4075 clearResults = main.FALSE
4076 if clearResults != main.TRUE:
4077 main.log.error( "Error executing set clear" )
4078
4079 # Check if set is still correct
4080 size = len( onosSet )
4081 getResponses = []
4082 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004083 for i in range( main.numCtrls ):
4084 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004085 name="setTestGet-" + str( i ),
4086 args=[ onosSetName ] )
4087 threads.append( t )
4088 t.start()
4089 for t in threads:
4090 t.join()
4091 getResponses.append( t.result )
4092 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004093 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004094 if isinstance( getResponses[ i ], list):
4095 current = set( getResponses[ i ] )
4096 if len( current ) == len( getResponses[ i ] ):
4097 # no repeats
4098 if onosSet != current:
4099 main.log.error( "ONOS" + str( i + 1 ) +
4100 " has incorrect view" +
4101 " of set " + onosSetName + ":\n" +
4102 str( getResponses[ i ] ) )
4103 main.log.debug( "Expected: " + str( onosSet ) )
4104 main.log.debug( "Actual: " + str( current ) )
4105 getResults = main.FALSE
4106 else:
4107 # error, set is not a set
4108 main.log.error( "ONOS" + str( i + 1 ) +
4109 " has repeat elements in" +
4110 " set " + onosSetName + ":\n" +
4111 str( getResponses[ i ] ) )
4112 getResults = main.FALSE
4113 elif getResponses[ i ] == main.ERROR:
4114 getResults = main.FALSE
4115 sizeResponses = []
4116 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004117 for i in range( main.numCtrls ):
4118 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004119 name="setTestSize-" + str( i ),
4120 args=[ onosSetName ] )
4121 threads.append( t )
4122 t.start()
4123 for t in threads:
4124 t.join()
4125 sizeResponses.append( t.result )
4126 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004127 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004128 if size != sizeResponses[ i ]:
4129 sizeResults = main.FALSE
4130 main.log.error( "ONOS" + str( i + 1 ) +
4131 " expected a size of " + str( size ) +
4132 " for set " + onosSetName +
4133 " but got " + str( sizeResponses[ i ] ) )
4134 clearResults = clearResults and getResults and sizeResults
4135 utilities.assert_equals( expect=main.TRUE,
4136 actual=clearResults,
4137 onpass="Set clear correct",
4138 onfail="Set clear was incorrect" )
4139
4140 main.step( "Distributed Set addAll()" )
4141 onosSet.update( addAllValue.split() )
4142 addResponses = []
4143 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004144 for i in range( main.numCtrls ):
4145 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004146 name="setTestAddAll-" + str( i ),
4147 args=[ onosSetName, addAllValue ] )
4148 threads.append( t )
4149 t.start()
4150 for t in threads:
4151 t.join()
4152 addResponses.append( t.result )
4153
4154 # main.TRUE = successfully changed the set
4155 # main.FALSE = action resulted in no change in set
4156 # main.ERROR - Some error in executing the function
4157 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004158 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004159 if addResponses[ i ] == main.TRUE:
4160 # All is well
4161 pass
4162 elif addResponses[ i ] == main.FALSE:
4163 # Already in set, probably fine
4164 pass
4165 elif addResponses[ i ] == main.ERROR:
4166 # Error in execution
4167 addAllResults = main.FALSE
4168 else:
4169 # unexpected result
4170 addAllResults = main.FALSE
4171 if addAllResults != main.TRUE:
4172 main.log.error( "Error executing set addAll" )
4173
4174 # Check if set is still correct
4175 size = len( onosSet )
4176 getResponses = []
4177 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004178 for i in range( main.numCtrls ):
4179 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004180 name="setTestGet-" + str( i ),
4181 args=[ onosSetName ] )
4182 threads.append( t )
4183 t.start()
4184 for t in threads:
4185 t.join()
4186 getResponses.append( t.result )
4187 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004188 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004189 if isinstance( getResponses[ i ], list):
4190 current = set( getResponses[ i ] )
4191 if len( current ) == len( getResponses[ i ] ):
4192 # no repeats
4193 if onosSet != current:
4194 main.log.error( "ONOS" + str( i + 1 ) +
4195 " has incorrect view" +
4196 " of set " + onosSetName + ":\n" +
4197 str( getResponses[ i ] ) )
4198 main.log.debug( "Expected: " + str( onosSet ) )
4199 main.log.debug( "Actual: " + str( current ) )
4200 getResults = main.FALSE
4201 else:
4202 # error, set is not a set
4203 main.log.error( "ONOS" + str( i + 1 ) +
4204 " has repeat elements in" +
4205 " set " + onosSetName + ":\n" +
4206 str( getResponses[ i ] ) )
4207 getResults = main.FALSE
4208 elif getResponses[ i ] == main.ERROR:
4209 getResults = main.FALSE
4210 sizeResponses = []
4211 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004212 for i in range( main.numCtrls ):
4213 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004214 name="setTestSize-" + str( i ),
4215 args=[ onosSetName ] )
4216 threads.append( t )
4217 t.start()
4218 for t in threads:
4219 t.join()
4220 sizeResponses.append( t.result )
4221 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004222 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004223 if size != sizeResponses[ i ]:
4224 sizeResults = main.FALSE
4225 main.log.error( "ONOS" + str( i + 1 ) +
4226 " expected a size of " + str( size ) +
4227 " for set " + onosSetName +
4228 " but got " + str( sizeResponses[ i ] ) )
4229 addAllResults = addAllResults and getResults and sizeResults
4230 utilities.assert_equals( expect=main.TRUE,
4231 actual=addAllResults,
4232 onpass="Set addAll correct",
4233 onfail="Set addAll was incorrect" )
4234
4235 main.step( "Distributed Set retain()" )
4236 onosSet.intersection_update( retainValue.split() )
4237 retainResponses = []
4238 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004239 for i in range( main.numCtrls ):
4240 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004241 name="setTestRetain-" + str( i ),
4242 args=[ onosSetName, retainValue ],
4243 kwargs={ "retain": True } )
4244 threads.append( t )
4245 t.start()
4246 for t in threads:
4247 t.join()
4248 retainResponses.append( t.result )
4249
4250 # main.TRUE = successfully changed the set
4251 # main.FALSE = action resulted in no change in set
4252 # main.ERROR - Some error in executing the function
4253 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004254 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004255 if retainResponses[ i ] == main.TRUE:
4256 # All is well
4257 pass
4258 elif retainResponses[ i ] == main.FALSE:
4259 # Already in set, probably fine
4260 pass
4261 elif retainResponses[ i ] == main.ERROR:
4262 # Error in execution
4263 retainResults = main.FALSE
4264 else:
4265 # unexpected result
4266 retainResults = main.FALSE
4267 if retainResults != main.TRUE:
4268 main.log.error( "Error executing set retain" )
4269
4270 # Check if set is still correct
4271 size = len( onosSet )
4272 getResponses = []
4273 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004274 for i in range( main.numCtrls ):
4275 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004276 name="setTestGet-" + str( i ),
4277 args=[ onosSetName ] )
4278 threads.append( t )
4279 t.start()
4280 for t in threads:
4281 t.join()
4282 getResponses.append( t.result )
4283 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004284 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004285 if isinstance( getResponses[ i ], list):
4286 current = set( getResponses[ i ] )
4287 if len( current ) == len( getResponses[ i ] ):
4288 # no repeats
4289 if onosSet != current:
4290 main.log.error( "ONOS" + str( i + 1 ) +
4291 " has incorrect view" +
4292 " of set " + onosSetName + ":\n" +
4293 str( getResponses[ i ] ) )
4294 main.log.debug( "Expected: " + str( onosSet ) )
4295 main.log.debug( "Actual: " + str( current ) )
4296 getResults = main.FALSE
4297 else:
4298 # error, set is not a set
4299 main.log.error( "ONOS" + str( i + 1 ) +
4300 " has repeat elements in" +
4301 " set " + onosSetName + ":\n" +
4302 str( getResponses[ i ] ) )
4303 getResults = main.FALSE
4304 elif getResponses[ i ] == main.ERROR:
4305 getResults = main.FALSE
4306 sizeResponses = []
4307 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004308 for i in range( main.numCtrls ):
4309 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004310 name="setTestSize-" + str( i ),
4311 args=[ onosSetName ] )
4312 threads.append( t )
4313 t.start()
4314 for t in threads:
4315 t.join()
4316 sizeResponses.append( t.result )
4317 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004318 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004319 if size != sizeResponses[ i ]:
4320 sizeResults = main.FALSE
4321 main.log.error( "ONOS" + str( i + 1 ) +
4322 " expected a size of " +
4323 str( size ) + " for set " + onosSetName +
4324 " but got " + str( sizeResponses[ i ] ) )
4325 retainResults = retainResults and getResults and sizeResults
4326 utilities.assert_equals( expect=main.TRUE,
4327 actual=retainResults,
4328 onpass="Set retain correct",
4329 onfail="Set retain was incorrect" )
4330
Jon Hall2a5002c2015-08-21 16:49:11 -07004331 # Transactional maps
4332 main.step( "Partitioned Transactional maps put" )
4333 tMapValue = "Testing"
4334 numKeys = 100
4335 putResult = True
4336 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4337 if len( putResponses ) == 100:
4338 for i in putResponses:
4339 if putResponses[ i ][ 'value' ] != tMapValue:
4340 putResult = False
4341 else:
4342 putResult = False
4343 if not putResult:
4344 main.log.debug( "Put response values: " + str( putResponses ) )
4345 utilities.assert_equals( expect=True,
4346 actual=putResult,
4347 onpass="Partitioned Transactional Map put successful",
4348 onfail="Partitioned Transactional Map put values are incorrect" )
4349
4350 main.step( "Partitioned Transactional maps get" )
4351 getCheck = True
4352 for n in range( 1, numKeys + 1 ):
4353 getResponses = []
4354 threads = []
4355 valueCheck = True
4356 for i in range( main.numCtrls ):
4357 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4358 name="TMap-get-" + str( i ),
4359 args=[ "Key" + str ( n ) ] )
4360 threads.append( t )
4361 t.start()
4362 for t in threads:
4363 t.join()
4364 getResponses.append( t.result )
4365 for node in getResponses:
4366 if node != tMapValue:
4367 valueCheck = False
4368 if not valueCheck:
4369 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4370 main.log.warn( getResponses )
4371 getCheck = getCheck and valueCheck
4372 utilities.assert_equals( expect=True,
4373 actual=getCheck,
4374 onpass="Partitioned Transactional Map get values were correct",
4375 onfail="Partitioned Transactional Map values incorrect" )
4376
4377 main.step( "In-memory Transactional maps put" )
4378 tMapValue = "Testing"
4379 numKeys = 100
4380 putResult = True
4381 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4382 if len( putResponses ) == 100:
4383 for i in putResponses:
4384 if putResponses[ i ][ 'value' ] != tMapValue:
4385 putResult = False
4386 else:
4387 putResult = False
4388 if not putResult:
4389 main.log.debug( "Put response values: " + str( putResponses ) )
4390 utilities.assert_equals( expect=True,
4391 actual=putResult,
4392 onpass="In-Memory Transactional Map put successful",
4393 onfail="In-Memory Transactional Map put values are incorrect" )
4394
4395 main.step( "In-Memory Transactional maps get" )
4396 getCheck = True
4397 for n in range( 1, numKeys + 1 ):
4398 getResponses = []
4399 threads = []
4400 valueCheck = True
4401 for i in range( main.numCtrls ):
4402 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4403 name="TMap-get-" + str( i ),
4404 args=[ "Key" + str ( n ) ],
4405 kwargs={ "inMemory": True } )
4406 threads.append( t )
4407 t.start()
4408 for t in threads:
4409 t.join()
4410 getResponses.append( t.result )
4411 for node in getResponses:
4412 if node != tMapValue:
4413 valueCheck = False
4414 if not valueCheck:
4415 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4416 main.log.warn( getResponses )
4417 getCheck = getCheck and valueCheck
4418 utilities.assert_equals( expect=True,
4419 actual=getCheck,
4420 onpass="In-Memory Transactional Map get values were correct",
4421 onfail="In-Memory Transactional Map values incorrect" )