blob: c16fbb7d9cc719b2adb9c902a5a18b230db2dd88 [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 Hall5cf14d52015-07-16 12:15:19 -070051 main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
52 "initialization" )
53 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070054 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070055 "installing ONOS, starting Mininet and ONOS" +\
56 "cli sessions."
57 # TODO: save all the timers and output them for plotting
58
59 # load some variables from the params file
60 PULLCODE = False
61 if main.params[ 'Git' ] == 'True':
62 PULLCODE = True
63 gitBranch = main.params[ 'branch' ]
64 cellName = main.params[ 'ENV' ][ 'cellName' ]
65
Jon Halle1a3b752015-07-22 13:02:46 -070066 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070067 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070068 if main.ONOSbench.maxNodes < main.numCtrls:
69 main.numCtrls = int( main.ONOSbench.maxNodes )
70 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070071 global ONOS1Port
72 global ONOS2Port
73 global ONOS3Port
74 global ONOS4Port
75 global ONOS5Port
76 global ONOS6Port
77 global ONOS7Port
78
79 # FIXME: just get controller port from params?
80 # TODO: do we really need all these?
81 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
82 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
83 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
84 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
85 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
86 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
87 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
88
Jon Halle1a3b752015-07-22 13:02:46 -070089 try:
90 fileName = "Counters"
91 # TODO: Maybe make a library folder somewhere?
92 path = main.params[ 'imports' ][ 'path' ]
93 main.Counters = imp.load_source( fileName,
94 path + fileName + ".py" )
95 except Exception as e:
96 main.log.exception( e )
97 main.cleanup()
98 main.exit()
99
100 main.CLIs = []
101 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700102 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700103 for i in range( 1, main.numCtrls + 1 ):
104 try:
105 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
106 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
107 ipList.append( main.nodes[ -1 ].ip_address )
108 except AttributeError:
109 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700110
111 main.step( "Create cell file" )
112 cellAppString = main.params[ 'ENV' ][ 'appString' ]
113 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
114 main.Mininet1.ip_address,
115 cellAppString, ipList )
116 main.step( "Applying cell variable to environment" )
117 cellResult = main.ONOSbench.setCell( cellName )
118 verifyResult = main.ONOSbench.verifyCell()
119
120 # FIXME:this is short term fix
121 main.log.info( "Removing raft logs" )
122 main.ONOSbench.onosRemoveRaftLogs()
123
124 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700125 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700126 main.ONOSbench.onosUninstall( node.ip_address )
127
128 # Make sure ONOS is DEAD
129 main.log.info( "Killing any ONOS processes" )
130 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700131 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700132 killed = main.ONOSbench.onosKill( node.ip_address )
133 killResults = killResults and killed
134
135 cleanInstallResult = main.TRUE
136 gitPullResult = main.TRUE
137
138 main.step( "Starting Mininet" )
139 # scp topo file to mininet
140 # TODO: move to params?
141 topoName = "obelisk.py"
142 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700143 main.ONOSbench.scp( main.Mininet1,
144 filePath + topoName,
145 main.Mininet1.home,
146 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700147 mnResult = main.Mininet1.startNet( )
148 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
149 onpass="Mininet Started",
150 onfail="Error starting Mininet" )
151
152 main.step( "Git checkout and pull " + gitBranch )
153 if PULLCODE:
154 main.ONOSbench.gitCheckout( gitBranch )
155 gitPullResult = main.ONOSbench.gitPull()
156 # values of 1 or 3 are good
157 utilities.assert_lesser( expect=0, actual=gitPullResult,
158 onpass="Git pull successful",
159 onfail="Git pull failed" )
160 main.ONOSbench.getVersion( report=True )
161
162 main.step( "Using mvn clean install" )
163 cleanInstallResult = main.TRUE
164 if PULLCODE and gitPullResult == main.TRUE:
165 cleanInstallResult = main.ONOSbench.cleanInstall()
166 else:
167 main.log.warn( "Did not pull new code so skipping mvn " +
168 "clean install" )
169 utilities.assert_equals( expect=main.TRUE,
170 actual=cleanInstallResult,
171 onpass="MCI successful",
172 onfail="MCI failed" )
173 # GRAPHS
174 # NOTE: important params here:
175 # job = name of Jenkins job
176 # Plot Name = Plot-HA, only can be used if multiple plots
177 # index = The number of the graph under plot name
178 job = "HAminorityRestart"
179 plotName = "Plot-HA"
180 graphs = '<ac:structured-macro ac:name="html">\n'
181 graphs += '<ac:plain-text-body><![CDATA[\n'
182 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
183 '/plot/' + plotName + '/getPlot?index=0' +\
184 '&width=500&height=300"' +\
185 'noborder="0" width="500" height="300" scrolling="yes" ' +\
186 'seamless="seamless"></iframe>\n'
187 graphs += ']]></ac:plain-text-body>\n'
188 graphs += '</ac:structured-macro>\n'
189 main.log.wiki(graphs)
190
191 main.step( "Creating ONOS package" )
192 packageResult = main.ONOSbench.onosPackage()
193 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
194 onpass="ONOS package successful",
195 onfail="ONOS package failed" )
196
197 main.step( "Installing ONOS package" )
198 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700199 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700200 tmpResult = main.ONOSbench.onosInstall( options="-f",
201 node=node.ip_address )
202 onosInstallResult = onosInstallResult and tmpResult
203 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
204 onpass="ONOS install successful",
205 onfail="ONOS install failed" )
206
207 main.step( "Checking if ONOS is up yet" )
208 for i in range( 2 ):
209 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700210 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700211 started = main.ONOSbench.isup( node.ip_address )
212 if not started:
213 main.log.error( node.name + " didn't start!" )
214 main.ONOSbench.onosStop( node.ip_address )
215 main.ONOSbench.onosStart( node.ip_address )
216 onosIsupResult = onosIsupResult and started
217 if onosIsupResult == main.TRUE:
218 break
219 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
220 onpass="ONOS startup successful",
221 onfail="ONOS startup failed" )
222
223 main.log.step( "Starting ONOS CLI sessions" )
224 cliResults = main.TRUE
225 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700226 for i in range( main.numCtrls ):
227 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700228 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700229 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700230 threads.append( t )
231 t.start()
232
233 for t in threads:
234 t.join()
235 cliResults = cliResults and t.result
236 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
237 onpass="ONOS cli startup successful",
238 onfail="ONOS cli startup failed" )
239
240 if main.params[ 'tcpdump' ].lower() == "true":
241 main.step( "Start Packet Capture MN" )
242 main.Mininet2.startTcpdump(
243 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
244 + "-MN.pcap",
245 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
246 port=main.params[ 'MNtcpdump' ][ 'port' ] )
247
248 main.step( "App Ids check" )
249 appCheck = main.TRUE
250 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700251 for i in range( main.numCtrls ):
252 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700253 name="appToIDCheck-" + str( i ),
254 args=[] )
255 threads.append( t )
256 t.start()
257
258 for t in threads:
259 t.join()
260 appCheck = appCheck and t.result
261 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700262 main.log.warn( main.CLIs[0].apps() )
263 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700264 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
265 onpass="App Ids seem to be correct",
266 onfail="Something is wrong with app Ids" )
267
268 if cliResults == main.FALSE:
269 main.log.error( "Failed to start ONOS, stopping test" )
270 main.cleanup()
271 main.exit()
272
273 def CASE2( self, main ):
274 """
275 Assign devices to controllers
276 """
277 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700278 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700279 assert main, "main not defined"
280 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700281 assert main.CLIs, "main.CLIs not defined"
282 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700283 assert ONOS1Port, "ONOS1Port not defined"
284 assert ONOS2Port, "ONOS2Port not defined"
285 assert ONOS3Port, "ONOS3Port not defined"
286 assert ONOS4Port, "ONOS4Port not defined"
287 assert ONOS5Port, "ONOS5Port not defined"
288 assert ONOS6Port, "ONOS6Port not defined"
289 assert ONOS7Port, "ONOS7Port not defined"
290
291 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700292 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700293 "and check that an ONOS node becomes the " +\
294 "master of the device."
295 main.step( "Assign switches to controllers" )
296
297 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700298 for i in range( main.numCtrls ):
299 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700300 swList = []
301 for i in range( 1, 29 ):
302 swList.append( "s" + str( i ) )
303 main.Mininet1.assignSwController( sw=swList, ip=ipList )
304
305 mastershipCheck = main.TRUE
306 for i in range( 1, 29 ):
307 response = main.Mininet1.getSwController( "s" + str( i ) )
308 try:
309 main.log.info( str( response ) )
310 except Exception:
311 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700312 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700313 if re.search( "tcp:" + node.ip_address, response ):
314 mastershipCheck = mastershipCheck and main.TRUE
315 else:
316 main.log.error( "Error, node " + node.ip_address + " is " +
317 "not in the list of controllers s" +
318 str( i ) + " is connecting to." )
319 mastershipCheck = main.FALSE
320 utilities.assert_equals(
321 expect=main.TRUE,
322 actual=mastershipCheck,
323 onpass="Switch mastership assigned correctly",
324 onfail="Switches not assigned correctly to controllers" )
325
326 def CASE21( self, main ):
327 """
328 Assign mastership to controllers
329 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700330 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700331 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700332 assert main, "main not defined"
333 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700334 assert main.CLIs, "main.CLIs not defined"
335 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700336 assert ONOS1Port, "ONOS1Port not defined"
337 assert ONOS2Port, "ONOS2Port not defined"
338 assert ONOS3Port, "ONOS3Port not defined"
339 assert ONOS4Port, "ONOS4Port not defined"
340 assert ONOS5Port, "ONOS5Port not defined"
341 assert ONOS6Port, "ONOS6Port not defined"
342 assert ONOS7Port, "ONOS7Port not defined"
343
344 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700345 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700346 "device. Then manually assign" +\
347 " mastership to specific ONOS nodes using" +\
348 " 'device-role'"
349 main.step( "Assign mastership of switches to specific controllers" )
350 # Manually assign mastership to the controller we want
351 roleCall = main.TRUE
352
353 ipList = [ ]
354 deviceList = []
355 try:
356 # Assign mastership to specific controllers. This assignment was
357 # determined for a 7 node cluser, but will work with any sized
358 # cluster
359 for i in range( 1, 29 ): # switches 1 through 28
360 # set up correct variables:
361 if i == 1:
362 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700363 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700364 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
365 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700366 c = 1 % main.numCtrls
367 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700368 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
369 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700370 c = 1 % main.numCtrls
371 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700372 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
373 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700374 c = 3 % main.numCtrls
375 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700376 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
377 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700378 c = 2 % main.numCtrls
379 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700380 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
381 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700382 c = 2 % main.numCtrls
383 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700384 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
385 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700386 c = 5 % main.numCtrls
387 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700388 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
389 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700390 c = 4 % main.numCtrls
391 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700392 dpid = '3' + str( i ).zfill( 3 )
393 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
394 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700395 c = 6 % main.numCtrls
396 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700397 dpid = '6' + str( i ).zfill( 3 )
398 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
399 elif i == 28:
400 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700401 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700402 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
403 else:
404 main.log.error( "You didn't write an else statement for " +
405 "switch s" + str( i ) )
406 roleCall = main.FALSE
407 # Assign switch
408 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
409 # TODO: make this controller dynamic
410 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
411 ip )
412 ipList.append( ip )
413 deviceList.append( deviceId )
414 except ( AttributeError, AssertionError ):
415 main.log.exception( "Something is wrong with ONOS device view" )
416 main.log.info( main.ONOScli1.devices() )
417 utilities.assert_equals(
418 expect=main.TRUE,
419 actual=roleCall,
420 onpass="Re-assigned switch mastership to designated controller",
421 onfail="Something wrong with deviceRole calls" )
422
423 main.step( "Check mastership was correctly assigned" )
424 roleCheck = main.TRUE
425 # NOTE: This is due to the fact that device mastership change is not
426 # atomic and is actually a multi step process
427 time.sleep( 5 )
428 for i in range( len( ipList ) ):
429 ip = ipList[i]
430 deviceId = deviceList[i]
431 # Check assignment
432 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
433 if ip in master:
434 roleCheck = roleCheck and main.TRUE
435 else:
436 roleCheck = roleCheck and main.FALSE
437 main.log.error( "Error, controller " + ip + " is not" +
438 " master " + "of device " +
439 str( deviceId ) + ". Master is " +
440 repr( master ) + "." )
441 utilities.assert_equals(
442 expect=main.TRUE,
443 actual=roleCheck,
444 onpass="Switches were successfully reassigned to designated " +
445 "controller",
446 onfail="Switches were not successfully reassigned" )
447
448 def CASE3( self, main ):
449 """
450 Assign intents
451 """
452 import time
453 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700454 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700455 assert main, "main not defined"
456 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700457 assert main.CLIs, "main.CLIs not defined"
458 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700460 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700461 "assign predetermined host-to-host intents." +\
462 " After installation, check that the intent" +\
463 " is distributed to all nodes and the state" +\
464 " is INSTALLED"
465
466 # install onos-app-fwd
467 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700468 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700469 utilities.assert_equals( expect=main.TRUE, actual=installResults,
470 onpass="Install fwd successful",
471 onfail="Install fwd failed" )
472
473 main.step( "Check app ids" )
474 appCheck = main.TRUE
475 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700476 for i in range( main.numCtrls ):
477 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700478 name="appToIDCheck-" + str( i ),
479 args=[] )
480 threads.append( t )
481 t.start()
482
483 for t in threads:
484 t.join()
485 appCheck = appCheck and t.result
486 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700487 main.log.warn( main.CLIs[0].apps() )
488 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700489 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
490 onpass="App Ids seem to be correct",
491 onfail="Something is wrong with app Ids" )
492
493 main.step( "Discovering Hosts( Via pingall for now )" )
494 # FIXME: Once we have a host discovery mechanism, use that instead
495 # REACTIVE FWD test
496 pingResult = main.FALSE
497 for i in range(2): # Retry if pingall fails first time
498 time1 = time.time()
499 pingResult = main.Mininet1.pingall()
500 if i == 0:
501 utilities.assert_equals(
502 expect=main.TRUE,
503 actual=pingResult,
504 onpass="Reactive Pingall test passed",
505 onfail="Reactive Pingall failed, " +
506 "one or more ping pairs failed" )
507 time2 = time.time()
508 main.log.info( "Time for pingall: %2f seconds" %
509 ( time2 - time1 ) )
510 # timeout for fwd flows
511 time.sleep( 11 )
512 # uninstall onos-app-fwd
513 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700514 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700515 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
516 onpass="Uninstall fwd successful",
517 onfail="Uninstall fwd failed" )
518
519 main.step( "Check app ids" )
520 threads = []
521 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700522 for i in range( main.numCtrls ):
523 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700524 name="appToIDCheck-" + str( i ),
525 args=[] )
526 threads.append( t )
527 t.start()
528
529 for t in threads:
530 t.join()
531 appCheck2 = appCheck2 and t.result
532 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700533 main.log.warn( main.CLIs[0].apps() )
534 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700535 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
536 onpass="App Ids seem to be correct",
537 onfail="Something is wrong with app Ids" )
538
539 main.step( "Add host intents via cli" )
540 intentIds = []
541 # TODO: move the host numbers to params
542 # Maybe look at all the paths we ping?
543 intentAddResult = True
544 hostResult = main.TRUE
545 for i in range( 8, 18 ):
546 main.log.info( "Adding host intent between h" + str( i ) +
547 " and h" + str( i + 10 ) )
548 host1 = "00:00:00:00:00:" + \
549 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
550 host2 = "00:00:00:00:00:" + \
551 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
552 # NOTE: getHost can return None
553 host1Dict = main.ONOScli1.getHost( host1 )
554 host2Dict = main.ONOScli1.getHost( host2 )
555 host1Id = None
556 host2Id = None
557 if host1Dict and host2Dict:
558 host1Id = host1Dict.get( 'id', None )
559 host2Id = host2Dict.get( 'id', None )
560 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700561 nodeNum = ( i % main.numCtrls )
562 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700563 if tmpId:
564 main.log.info( "Added intent with id: " + tmpId )
565 intentIds.append( tmpId )
566 else:
567 main.log.error( "addHostIntent returned: " +
568 repr( tmpId ) )
569 else:
570 main.log.error( "Error, getHost() failed for h" + str( i ) +
571 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700572 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700573 main.log.warn( "Hosts output: " )
574 try:
575 main.log.warn( json.dumps( json.loads( hosts ),
576 sort_keys=True,
577 indent=4,
578 separators=( ',', ': ' ) ) )
579 except ( ValueError, TypeError ):
580 main.log.warn( repr( hosts ) )
581 hostResult = main.FALSE
582 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
583 onpass="Found a host id for each host",
584 onfail="Error looking up host ids" )
585
586 intentStart = time.time()
587 onosIds = main.ONOScli1.getAllIntentsId()
588 main.log.info( "Submitted intents: " + str( intentIds ) )
589 main.log.info( "Intents in ONOS: " + str( onosIds ) )
590 for intent in intentIds:
591 if intent in onosIds:
592 pass # intent submitted is in onos
593 else:
594 intentAddResult = False
595 if intentAddResult:
596 intentStop = time.time()
597 else:
598 intentStop = None
599 # Print the intent states
600 intents = main.ONOScli1.intents()
601 intentStates = []
602 installedCheck = True
603 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
604 count = 0
605 try:
606 for intent in json.loads( intents ):
607 state = intent.get( 'state', None )
608 if "INSTALLED" not in state:
609 installedCheck = False
610 intentId = intent.get( 'id', None )
611 intentStates.append( ( intentId, state ) )
612 except ( ValueError, TypeError ):
613 main.log.exception( "Error parsing intents" )
614 # add submitted intents not in the store
615 tmplist = [ i for i, s in intentStates ]
616 missingIntents = False
617 for i in intentIds:
618 if i not in tmplist:
619 intentStates.append( ( i, " - " ) )
620 missingIntents = True
621 intentStates.sort()
622 for i, s in intentStates:
623 count += 1
624 main.log.info( "%-6s%-15s%-15s" %
625 ( str( count ), str( i ), str( s ) ) )
626 leaders = main.ONOScli1.leaders()
627 try:
628 missing = False
629 if leaders:
630 parsedLeaders = json.loads( leaders )
631 main.log.warn( json.dumps( parsedLeaders,
632 sort_keys=True,
633 indent=4,
634 separators=( ',', ': ' ) ) )
635 # check for all intent partitions
636 topics = []
637 for i in range( 14 ):
638 topics.append( "intent-partition-" + str( i ) )
639 main.log.debug( topics )
640 ONOStopics = [ j['topic'] for j in parsedLeaders ]
641 for topic in topics:
642 if topic not in ONOStopics:
643 main.log.error( "Error: " + topic +
644 " not in leaders" )
645 missing = True
646 else:
647 main.log.error( "leaders() returned None" )
648 except ( ValueError, TypeError ):
649 main.log.exception( "Error parsing leaders" )
650 main.log.error( repr( leaders ) )
651 # Check all nodes
652 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700653 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700654 response = node.leaders( jsonFormat=False)
655 main.log.warn( str( node.name ) + " leaders output: \n" +
656 str( response ) )
657
658 partitions = main.ONOScli1.partitions()
659 try:
660 if partitions :
661 parsedPartitions = json.loads( partitions )
662 main.log.warn( json.dumps( parsedPartitions,
663 sort_keys=True,
664 indent=4,
665 separators=( ',', ': ' ) ) )
666 # TODO check for a leader in all paritions
667 # TODO check for consistency among nodes
668 else:
669 main.log.error( "partitions() returned None" )
670 except ( ValueError, TypeError ):
671 main.log.exception( "Error parsing partitions" )
672 main.log.error( repr( partitions ) )
673 pendingMap = main.ONOScli1.pendingMap()
674 try:
675 if pendingMap :
676 parsedPending = json.loads( pendingMap )
677 main.log.warn( json.dumps( parsedPending,
678 sort_keys=True,
679 indent=4,
680 separators=( ',', ': ' ) ) )
681 # TODO check something here?
682 else:
683 main.log.error( "pendingMap() returned None" )
684 except ( ValueError, TypeError ):
685 main.log.exception( "Error parsing pending map" )
686 main.log.error( repr( pendingMap ) )
687
688 intentAddResult = bool( intentAddResult and not missingIntents and
689 installedCheck )
690 if not intentAddResult:
691 main.log.error( "Error in pushing host intents to ONOS" )
692
693 main.step( "Intent Anti-Entropy dispersion" )
694 for i in range(100):
695 correct = True
696 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700697 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700698 onosIds = []
699 ids = cli.getAllIntentsId()
700 onosIds.append( ids )
701 main.log.debug( "Intents in " + cli.name + ": " +
702 str( sorted( onosIds ) ) )
703 if sorted( ids ) != sorted( intentIds ):
704 main.log.warn( "Set of intent IDs doesn't match" )
705 correct = False
706 break
707 else:
708 intents = json.loads( cli.intents() )
709 for intent in intents:
710 if intent[ 'state' ] != "INSTALLED":
711 main.log.warn( "Intent " + intent[ 'id' ] +
712 " is " + intent[ 'state' ] )
713 correct = False
714 break
715 if correct:
716 break
717 else:
718 time.sleep(1)
719 if not intentStop:
720 intentStop = time.time()
721 global gossipTime
722 gossipTime = intentStop - intentStart
723 main.log.info( "It took about " + str( gossipTime ) +
724 " seconds for all intents to appear in each node" )
725 # FIXME: make this time configurable/calculate based off of number of
726 # nodes and gossip rounds
727 utilities.assert_greater_equals(
728 expect=40, actual=gossipTime,
729 onpass="ECM anti-entropy for intents worked within " +
730 "expected time",
731 onfail="Intent ECM anti-entropy took too long" )
732 if gossipTime <= 40:
733 intentAddResult = True
734
735 if not intentAddResult or "key" in pendingMap:
736 import time
737 installedCheck = True
738 main.log.info( "Sleeping 60 seconds to see if intents are found" )
739 time.sleep( 60 )
740 onosIds = main.ONOScli1.getAllIntentsId()
741 main.log.info( "Submitted intents: " + str( intentIds ) )
742 main.log.info( "Intents in ONOS: " + str( onosIds ) )
743 # Print the intent states
744 intents = main.ONOScli1.intents()
745 intentStates = []
746 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
747 count = 0
748 try:
749 for intent in json.loads( intents ):
750 # Iter through intents of a node
751 state = intent.get( 'state', None )
752 if "INSTALLED" not in state:
753 installedCheck = False
754 intentId = intent.get( 'id', None )
755 intentStates.append( ( intentId, state ) )
756 except ( ValueError, TypeError ):
757 main.log.exception( "Error parsing intents" )
758 # add submitted intents not in the store
759 tmplist = [ i for i, s in intentStates ]
760 for i in intentIds:
761 if i not in tmplist:
762 intentStates.append( ( i, " - " ) )
763 intentStates.sort()
764 for i, s in intentStates:
765 count += 1
766 main.log.info( "%-6s%-15s%-15s" %
767 ( str( count ), str( i ), str( s ) ) )
768 leaders = main.ONOScli1.leaders()
769 try:
770 missing = False
771 if leaders:
772 parsedLeaders = json.loads( leaders )
773 main.log.warn( json.dumps( parsedLeaders,
774 sort_keys=True,
775 indent=4,
776 separators=( ',', ': ' ) ) )
777 # check for all intent partitions
778 # check for election
779 topics = []
780 for i in range( 14 ):
781 topics.append( "intent-partition-" + str( i ) )
782 # FIXME: this should only be after we start the app
783 topics.append( "org.onosproject.election" )
784 main.log.debug( topics )
785 ONOStopics = [ j['topic'] for j in parsedLeaders ]
786 for topic in topics:
787 if topic not in ONOStopics:
788 main.log.error( "Error: " + topic +
789 " not in leaders" )
790 missing = True
791 else:
792 main.log.error( "leaders() returned None" )
793 except ( ValueError, TypeError ):
794 main.log.exception( "Error parsing leaders" )
795 main.log.error( repr( leaders ) )
796 # Check all nodes
797 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700798 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700799 response = node.leaders( jsonFormat=False)
800 main.log.warn( str( node.name ) + " leaders output: \n" +
801 str( response ) )
802
803 partitions = main.ONOScli1.partitions()
804 try:
805 if partitions :
806 parsedPartitions = json.loads( partitions )
807 main.log.warn( json.dumps( parsedPartitions,
808 sort_keys=True,
809 indent=4,
810 separators=( ',', ': ' ) ) )
811 # TODO check for a leader in all paritions
812 # TODO check for consistency among nodes
813 else:
814 main.log.error( "partitions() returned None" )
815 except ( ValueError, TypeError ):
816 main.log.exception( "Error parsing partitions" )
817 main.log.error( repr( partitions ) )
818 pendingMap = main.ONOScli1.pendingMap()
819 try:
820 if pendingMap :
821 parsedPending = json.loads( pendingMap )
822 main.log.warn( json.dumps( parsedPending,
823 sort_keys=True,
824 indent=4,
825 separators=( ',', ': ' ) ) )
826 # TODO check something here?
827 else:
828 main.log.error( "pendingMap() returned None" )
829 except ( ValueError, TypeError ):
830 main.log.exception( "Error parsing pending map" )
831 main.log.error( repr( pendingMap ) )
832
833 def CASE4( self, main ):
834 """
835 Ping across added host intents
836 """
837 import json
838 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700839 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700840 assert main, "main not defined"
841 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700842 assert main.CLIs, "main.CLIs not defined"
843 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700844 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700845 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700846 "functionality and check the state of " +\
847 "the intent"
848 main.step( "Ping across added host intents" )
849 PingResult = main.TRUE
850 for i in range( 8, 18 ):
851 ping = main.Mininet1.pingHost( src="h" + str( i ),
852 target="h" + str( i + 10 ) )
853 PingResult = PingResult and ping
854 if ping == main.FALSE:
855 main.log.warn( "Ping failed between h" + str( i ) +
856 " and h" + str( i + 10 ) )
857 elif ping == main.TRUE:
858 main.log.info( "Ping test passed!" )
859 # Don't set PingResult or you'd override failures
860 if PingResult == main.FALSE:
861 main.log.error(
862 "Intents have not been installed correctly, pings failed." )
863 # TODO: pretty print
864 main.log.warn( "ONOS1 intents: " )
865 try:
866 tmpIntents = main.ONOScli1.intents()
867 main.log.warn( json.dumps( json.loads( tmpIntents ),
868 sort_keys=True,
869 indent=4,
870 separators=( ',', ': ' ) ) )
871 except ( ValueError, TypeError ):
872 main.log.warn( repr( tmpIntents ) )
873 utilities.assert_equals(
874 expect=main.TRUE,
875 actual=PingResult,
876 onpass="Intents have been installed correctly and pings work",
877 onfail="Intents have not been installed correctly, pings failed." )
878
879 main.step( "Check Intent state" )
880 installedCheck = False
881 loopCount = 0
882 while not installedCheck and loopCount < 40:
883 installedCheck = True
884 # Print the intent states
885 intents = main.ONOScli1.intents()
886 intentStates = []
887 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
888 count = 0
889 # Iter through intents of a node
890 try:
891 for intent in json.loads( intents ):
892 state = intent.get( 'state', None )
893 if "INSTALLED" not in state:
894 installedCheck = False
895 intentId = intent.get( 'id', None )
896 intentStates.append( ( intentId, state ) )
897 except ( ValueError, TypeError ):
898 main.log.exception( "Error parsing intents." )
899 # Print states
900 intentStates.sort()
901 for i, s in intentStates:
902 count += 1
903 main.log.info( "%-6s%-15s%-15s" %
904 ( str( count ), str( i ), str( s ) ) )
905 if not installedCheck:
906 time.sleep( 1 )
907 loopCount += 1
908 utilities.assert_equals( expect=True, actual=installedCheck,
909 onpass="Intents are all INSTALLED",
910 onfail="Intents are not all in " +
911 "INSTALLED state" )
912
913 main.step( "Check leadership of topics" )
914 leaders = main.ONOScli1.leaders()
915 topicCheck = main.TRUE
916 try:
917 if leaders:
918 parsedLeaders = json.loads( leaders )
919 main.log.warn( json.dumps( parsedLeaders,
920 sort_keys=True,
921 indent=4,
922 separators=( ',', ': ' ) ) )
923 # check for all intent partitions
924 # check for election
925 # TODO: Look at Devices as topics now that it uses this system
926 topics = []
927 for i in range( 14 ):
928 topics.append( "intent-partition-" + str( i ) )
929 # FIXME: this should only be after we start the app
930 # FIXME: topics.append( "org.onosproject.election" )
931 # Print leaders output
932 main.log.debug( topics )
933 ONOStopics = [ j['topic'] for j in parsedLeaders ]
934 for topic in topics:
935 if topic not in ONOStopics:
936 main.log.error( "Error: " + topic +
937 " not in leaders" )
938 topicCheck = main.FALSE
939 else:
940 main.log.error( "leaders() returned None" )
941 topicCheck = main.FALSE
942 except ( ValueError, TypeError ):
943 topicCheck = main.FALSE
944 main.log.exception( "Error parsing leaders" )
945 main.log.error( repr( leaders ) )
946 # TODO: Check for a leader of these topics
947 # Check all nodes
948 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700949 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700950 response = node.leaders( jsonFormat=False)
951 main.log.warn( str( node.name ) + " leaders output: \n" +
952 str( response ) )
953
954 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
955 onpass="intent Partitions is in leaders",
956 onfail="Some topics were lost " )
957 # Print partitions
958 partitions = main.ONOScli1.partitions()
959 try:
960 if partitions :
961 parsedPartitions = json.loads( partitions )
962 main.log.warn( json.dumps( parsedPartitions,
963 sort_keys=True,
964 indent=4,
965 separators=( ',', ': ' ) ) )
966 # TODO check for a leader in all paritions
967 # TODO check for consistency among nodes
968 else:
969 main.log.error( "partitions() returned None" )
970 except ( ValueError, TypeError ):
971 main.log.exception( "Error parsing partitions" )
972 main.log.error( repr( partitions ) )
973 # Print Pending Map
974 pendingMap = main.ONOScli1.pendingMap()
975 try:
976 if pendingMap :
977 parsedPending = json.loads( pendingMap )
978 main.log.warn( json.dumps( parsedPending,
979 sort_keys=True,
980 indent=4,
981 separators=( ',', ': ' ) ) )
982 # TODO check something here?
983 else:
984 main.log.error( "pendingMap() returned None" )
985 except ( ValueError, TypeError ):
986 main.log.exception( "Error parsing pending map" )
987 main.log.error( repr( pendingMap ) )
988
989 if not installedCheck:
990 main.log.info( "Waiting 60 seconds to see if the state of " +
991 "intents change" )
992 time.sleep( 60 )
993 # Print the intent states
994 intents = main.ONOScli1.intents()
995 intentStates = []
996 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
997 count = 0
998 # Iter through intents of a node
999 try:
1000 for intent in json.loads( intents ):
1001 state = intent.get( 'state', None )
1002 if "INSTALLED" not in state:
1003 installedCheck = False
1004 intentId = intent.get( 'id', None )
1005 intentStates.append( ( intentId, state ) )
1006 except ( ValueError, TypeError ):
1007 main.log.exception( "Error parsing intents." )
1008 intentStates.sort()
1009 for i, s in intentStates:
1010 count += 1
1011 main.log.info( "%-6s%-15s%-15s" %
1012 ( str( count ), str( i ), str( s ) ) )
1013 leaders = main.ONOScli1.leaders()
1014 try:
1015 missing = False
1016 if leaders:
1017 parsedLeaders = json.loads( leaders )
1018 main.log.warn( json.dumps( parsedLeaders,
1019 sort_keys=True,
1020 indent=4,
1021 separators=( ',', ': ' ) ) )
1022 # check for all intent partitions
1023 # check for election
1024 topics = []
1025 for i in range( 14 ):
1026 topics.append( "intent-partition-" + str( i ) )
1027 # FIXME: this should only be after we start the app
1028 topics.append( "org.onosproject.election" )
1029 main.log.debug( topics )
1030 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1031 for topic in topics:
1032 if topic not in ONOStopics:
1033 main.log.error( "Error: " + topic +
1034 " not in leaders" )
1035 missing = True
1036 else:
1037 main.log.error( "leaders() returned None" )
1038 except ( ValueError, TypeError ):
1039 main.log.exception( "Error parsing leaders" )
1040 main.log.error( repr( leaders ) )
1041 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001042 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001043 response = node.leaders( jsonFormat=False)
1044 main.log.warn( str( node.name ) + " leaders output: \n" +
1045 str( response ) )
1046
1047 partitions = main.ONOScli1.partitions()
1048 try:
1049 if partitions :
1050 parsedPartitions = json.loads( partitions )
1051 main.log.warn( json.dumps( parsedPartitions,
1052 sort_keys=True,
1053 indent=4,
1054 separators=( ',', ': ' ) ) )
1055 # TODO check for a leader in all paritions
1056 # TODO check for consistency among nodes
1057 else:
1058 main.log.error( "partitions() returned None" )
1059 except ( ValueError, TypeError ):
1060 main.log.exception( "Error parsing partitions" )
1061 main.log.error( repr( partitions ) )
1062 pendingMap = main.ONOScli1.pendingMap()
1063 try:
1064 if pendingMap :
1065 parsedPending = json.loads( pendingMap )
1066 main.log.warn( json.dumps( parsedPending,
1067 sort_keys=True,
1068 indent=4,
1069 separators=( ',', ': ' ) ) )
1070 # TODO check something here?
1071 else:
1072 main.log.error( "pendingMap() returned None" )
1073 except ( ValueError, TypeError ):
1074 main.log.exception( "Error parsing pending map" )
1075 main.log.error( repr( pendingMap ) )
1076 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001077 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001078 main.step( "Wait a minute then ping again" )
1079 # the wait is above
1080 PingResult = main.TRUE
1081 for i in range( 8, 18 ):
1082 ping = main.Mininet1.pingHost( src="h" + str( i ),
1083 target="h" + str( i + 10 ) )
1084 PingResult = PingResult and ping
1085 if ping == main.FALSE:
1086 main.log.warn( "Ping failed between h" + str( i ) +
1087 " and h" + str( i + 10 ) )
1088 elif ping == main.TRUE:
1089 main.log.info( "Ping test passed!" )
1090 # Don't set PingResult or you'd override failures
1091 if PingResult == main.FALSE:
1092 main.log.error(
1093 "Intents have not been installed correctly, pings failed." )
1094 # TODO: pretty print
1095 main.log.warn( "ONOS1 intents: " )
1096 try:
1097 tmpIntents = main.ONOScli1.intents()
1098 main.log.warn( json.dumps( json.loads( tmpIntents ),
1099 sort_keys=True,
1100 indent=4,
1101 separators=( ',', ': ' ) ) )
1102 except ( ValueError, TypeError ):
1103 main.log.warn( repr( tmpIntents ) )
1104 utilities.assert_equals(
1105 expect=main.TRUE,
1106 actual=PingResult,
1107 onpass="Intents have been installed correctly and pings work",
1108 onfail="Intents have not been installed correctly, pings failed." )
1109
1110 def CASE5( self, main ):
1111 """
1112 Reading state of ONOS
1113 """
1114 import json
1115 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001116 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001117 assert main, "main not defined"
1118 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001119 assert main.CLIs, "main.CLIs not defined"
1120 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001121
1122 main.case( "Setting up and gathering data for current state" )
1123 # The general idea for this test case is to pull the state of
1124 # ( intents,flows, topology,... ) from each ONOS node
1125 # We can then compare them with each other and also with past states
1126
1127 main.step( "Check that each switch has a master" )
1128 global mastershipState
1129 mastershipState = '[]'
1130
1131 # Assert that each device has a master
1132 rolesNotNull = main.TRUE
1133 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001134 for i in range( main.numCtrls ):
1135 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001136 name="rolesNotNull-" + str( i ),
1137 args=[] )
1138 threads.append( t )
1139 t.start()
1140
1141 for t in threads:
1142 t.join()
1143 rolesNotNull = rolesNotNull and t.result
1144 utilities.assert_equals(
1145 expect=main.TRUE,
1146 actual=rolesNotNull,
1147 onpass="Each device has a master",
1148 onfail="Some devices don't have a master assigned" )
1149
1150 main.step( "Get the Mastership of each switch from each controller" )
1151 ONOSMastership = []
1152 mastershipCheck = main.FALSE
1153 consistentMastership = True
1154 rolesResults = True
1155 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001156 for i in range( main.numCtrls ):
1157 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001158 name="roles-" + str( i ),
1159 args=[] )
1160 threads.append( t )
1161 t.start()
1162
1163 for t in threads:
1164 t.join()
1165 ONOSMastership.append( t.result )
1166
Jon Halle1a3b752015-07-22 13:02:46 -07001167 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001168 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1169 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1170 " roles" )
1171 main.log.warn(
1172 "ONOS" + str( i + 1 ) + " mastership response: " +
1173 repr( ONOSMastership[i] ) )
1174 rolesResults = False
1175 utilities.assert_equals(
1176 expect=True,
1177 actual=rolesResults,
1178 onpass="No error in reading roles output",
1179 onfail="Error in reading roles from ONOS" )
1180
1181 main.step( "Check for consistency in roles from each controller" )
1182 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1183 main.log.info(
1184 "Switch roles are consistent across all ONOS nodes" )
1185 else:
1186 consistentMastership = False
1187 utilities.assert_equals(
1188 expect=True,
1189 actual=consistentMastership,
1190 onpass="Switch roles are consistent across all ONOS nodes",
1191 onfail="ONOS nodes have different views of switch roles" )
1192
1193 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001194 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001195 try:
1196 main.log.warn(
1197 "ONOS" + str( i + 1 ) + " roles: ",
1198 json.dumps(
1199 json.loads( ONOSMastership[ i ] ),
1200 sort_keys=True,
1201 indent=4,
1202 separators=( ',', ': ' ) ) )
1203 except ( ValueError, TypeError ):
1204 main.log.warn( repr( ONOSMastership[ i ] ) )
1205 elif rolesResults and consistentMastership:
1206 mastershipCheck = main.TRUE
1207 mastershipState = ONOSMastership[ 0 ]
1208
1209 main.step( "Get the intents from each controller" )
1210 global intentState
1211 intentState = []
1212 ONOSIntents = []
1213 intentCheck = main.FALSE
1214 consistentIntents = True
1215 intentsResults = True
1216 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001217 for i in range( main.numCtrls ):
1218 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001219 name="intents-" + str( i ),
1220 args=[],
1221 kwargs={ 'jsonFormat': True } )
1222 threads.append( t )
1223 t.start()
1224
1225 for t in threads:
1226 t.join()
1227 ONOSIntents.append( t.result )
1228
Jon Halle1a3b752015-07-22 13:02:46 -07001229 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001230 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1231 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1232 " intents" )
1233 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1234 repr( ONOSIntents[ i ] ) )
1235 intentsResults = False
1236 utilities.assert_equals(
1237 expect=True,
1238 actual=intentsResults,
1239 onpass="No error in reading intents output",
1240 onfail="Error in reading intents from ONOS" )
1241
1242 main.step( "Check for consistency in Intents from each controller" )
1243 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1244 main.log.info( "Intents are consistent across all ONOS " +
1245 "nodes" )
1246 else:
1247 consistentIntents = False
1248 main.log.error( "Intents not consistent" )
1249 utilities.assert_equals(
1250 expect=True,
1251 actual=consistentIntents,
1252 onpass="Intents are consistent across all ONOS nodes",
1253 onfail="ONOS nodes have different views of intents" )
1254
1255 if intentsResults:
1256 # Try to make it easy to figure out what is happening
1257 #
1258 # Intent ONOS1 ONOS2 ...
1259 # 0x01 INSTALLED INSTALLING
1260 # ... ... ...
1261 # ... ... ...
1262 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001263 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001264 title += " " * 10 + "ONOS" + str( n + 1 )
1265 main.log.warn( title )
1266 # get all intent keys in the cluster
1267 keys = []
1268 for nodeStr in ONOSIntents:
1269 node = json.loads( nodeStr )
1270 for intent in node:
1271 keys.append( intent.get( 'id' ) )
1272 keys = set( keys )
1273 for key in keys:
1274 row = "%-13s" % key
1275 for nodeStr in ONOSIntents:
1276 node = json.loads( nodeStr )
1277 for intent in node:
1278 if intent.get( 'id', "Error" ) == key:
1279 row += "%-15s" % intent.get( 'state' )
1280 main.log.warn( row )
1281 # End table view
1282
1283 if intentsResults and not consistentIntents:
1284 # print the json objects
1285 n = len(ONOSIntents)
1286 main.log.debug( "ONOS" + str( n ) + " intents: " )
1287 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1288 sort_keys=True,
1289 indent=4,
1290 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001291 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001292 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1293 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1294 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1295 sort_keys=True,
1296 indent=4,
1297 separators=( ',', ': ' ) ) )
1298 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001299 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001300 str( n ) + " intents" )
1301 elif intentsResults and consistentIntents:
1302 intentCheck = main.TRUE
1303 intentState = ONOSIntents[ 0 ]
1304
1305 main.step( "Get the flows from each controller" )
1306 global flowState
1307 flowState = []
1308 ONOSFlows = []
1309 ONOSFlowsJson = []
1310 flowCheck = main.FALSE
1311 consistentFlows = True
1312 flowsResults = True
1313 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001314 for i in range( main.numCtrls ):
1315 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001316 name="flows-" + str( i ),
1317 args=[],
1318 kwargs={ 'jsonFormat': True } )
1319 threads.append( t )
1320 t.start()
1321
1322 # NOTE: Flows command can take some time to run
1323 time.sleep(30)
1324 for t in threads:
1325 t.join()
1326 result = t.result
1327 ONOSFlows.append( result )
1328
Jon Halle1a3b752015-07-22 13:02:46 -07001329 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001330 num = str( i + 1 )
1331 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1332 main.log.error( "Error in getting ONOS" + num + " flows" )
1333 main.log.warn( "ONOS" + num + " flows response: " +
1334 repr( ONOSFlows[ i ] ) )
1335 flowsResults = False
1336 ONOSFlowsJson.append( None )
1337 else:
1338 try:
1339 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1340 except ( ValueError, TypeError ):
1341 # FIXME: change this to log.error?
1342 main.log.exception( "Error in parsing ONOS" + num +
1343 " response as json." )
1344 main.log.error( repr( ONOSFlows[ i ] ) )
1345 ONOSFlowsJson.append( None )
1346 flowsResults = False
1347 utilities.assert_equals(
1348 expect=True,
1349 actual=flowsResults,
1350 onpass="No error in reading flows output",
1351 onfail="Error in reading flows from ONOS" )
1352
1353 main.step( "Check for consistency in Flows from each controller" )
1354 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1355 if all( tmp ):
1356 main.log.info( "Flow count is consistent across all ONOS nodes" )
1357 else:
1358 consistentFlows = False
1359 utilities.assert_equals(
1360 expect=True,
1361 actual=consistentFlows,
1362 onpass="The flow count is consistent across all ONOS nodes",
1363 onfail="ONOS nodes have different flow counts" )
1364
1365 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001366 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001367 try:
1368 main.log.warn(
1369 "ONOS" + str( i + 1 ) + " flows: " +
1370 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1371 indent=4, separators=( ',', ': ' ) ) )
1372 except ( ValueError, TypeError ):
1373 main.log.warn(
1374 "ONOS" + str( i + 1 ) + " flows: " +
1375 repr( ONOSFlows[ i ] ) )
1376 elif flowsResults and consistentFlows:
1377 flowCheck = main.TRUE
1378 flowState = ONOSFlows[ 0 ]
1379
1380 main.step( "Get the OF Table entries" )
1381 global flows
1382 flows = []
1383 for i in range( 1, 29 ):
Jon Hall9043c902015-07-30 14:23:44 -07001384 flows.append( main.Mininet1.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001385 if flowCheck == main.FALSE:
1386 for table in flows:
1387 main.log.warn( table )
1388 # TODO: Compare switch flow tables with ONOS flow tables
1389
1390 main.step( "Start continuous pings" )
1391 main.Mininet2.pingLong(
1392 src=main.params[ 'PING' ][ 'source1' ],
1393 target=main.params[ 'PING' ][ 'target1' ],
1394 pingTime=500 )
1395 main.Mininet2.pingLong(
1396 src=main.params[ 'PING' ][ 'source2' ],
1397 target=main.params[ 'PING' ][ 'target2' ],
1398 pingTime=500 )
1399 main.Mininet2.pingLong(
1400 src=main.params[ 'PING' ][ 'source3' ],
1401 target=main.params[ 'PING' ][ 'target3' ],
1402 pingTime=500 )
1403 main.Mininet2.pingLong(
1404 src=main.params[ 'PING' ][ 'source4' ],
1405 target=main.params[ 'PING' ][ 'target4' ],
1406 pingTime=500 )
1407 main.Mininet2.pingLong(
1408 src=main.params[ 'PING' ][ 'source5' ],
1409 target=main.params[ 'PING' ][ 'target5' ],
1410 pingTime=500 )
1411 main.Mininet2.pingLong(
1412 src=main.params[ 'PING' ][ 'source6' ],
1413 target=main.params[ 'PING' ][ 'target6' ],
1414 pingTime=500 )
1415 main.Mininet2.pingLong(
1416 src=main.params[ 'PING' ][ 'source7' ],
1417 target=main.params[ 'PING' ][ 'target7' ],
1418 pingTime=500 )
1419 main.Mininet2.pingLong(
1420 src=main.params[ 'PING' ][ 'source8' ],
1421 target=main.params[ 'PING' ][ 'target8' ],
1422 pingTime=500 )
1423 main.Mininet2.pingLong(
1424 src=main.params[ 'PING' ][ 'source9' ],
1425 target=main.params[ 'PING' ][ 'target9' ],
1426 pingTime=500 )
1427 main.Mininet2.pingLong(
1428 src=main.params[ 'PING' ][ 'source10' ],
1429 target=main.params[ 'PING' ][ 'target10' ],
1430 pingTime=500 )
1431
1432 main.step( "Collecting topology information from ONOS" )
1433 devices = []
1434 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001435 for i in range( main.numCtrls ):
1436 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001437 name="devices-" + str( i ),
1438 args=[ ] )
1439 threads.append( t )
1440 t.start()
1441
1442 for t in threads:
1443 t.join()
1444 devices.append( t.result )
1445 hosts = []
1446 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001447 for i in range( main.numCtrls ):
1448 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001449 name="hosts-" + str( i ),
1450 args=[ ] )
1451 threads.append( t )
1452 t.start()
1453
1454 for t in threads:
1455 t.join()
1456 try:
1457 hosts.append( json.loads( t.result ) )
1458 except ( ValueError, TypeError ):
1459 # FIXME: better handling of this, print which node
1460 # Maybe use thread name?
1461 main.log.exception( "Error parsing json output of hosts" )
1462 # FIXME: should this be an empty json object instead?
1463 hosts.append( None )
1464
1465 ports = []
1466 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001467 for i in range( main.numCtrls ):
1468 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001469 name="ports-" + str( i ),
1470 args=[ ] )
1471 threads.append( t )
1472 t.start()
1473
1474 for t in threads:
1475 t.join()
1476 ports.append( t.result )
1477 links = []
1478 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001479 for i in range( main.numCtrls ):
1480 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001481 name="links-" + str( i ),
1482 args=[ ] )
1483 threads.append( t )
1484 t.start()
1485
1486 for t in threads:
1487 t.join()
1488 links.append( t.result )
1489 clusters = []
1490 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001491 for i in range( main.numCtrls ):
1492 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001493 name="clusters-" + str( i ),
1494 args=[ ] )
1495 threads.append( t )
1496 t.start()
1497
1498 for t in threads:
1499 t.join()
1500 clusters.append( t.result )
1501 # Compare json objects for hosts and dataplane clusters
1502
1503 # hosts
1504 main.step( "Host view is consistent across ONOS nodes" )
1505 consistentHostsResult = main.TRUE
1506 for controller in range( len( hosts ) ):
1507 controllerStr = str( controller + 1 )
1508 if "Error" not in hosts[ controller ]:
1509 if hosts[ controller ] == hosts[ 0 ]:
1510 continue
1511 else: # hosts not consistent
1512 main.log.error( "hosts from ONOS" +
1513 controllerStr +
1514 " is inconsistent with ONOS1" )
1515 main.log.warn( repr( hosts[ controller ] ) )
1516 consistentHostsResult = main.FALSE
1517
1518 else:
1519 main.log.error( "Error in getting ONOS hosts from ONOS" +
1520 controllerStr )
1521 consistentHostsResult = main.FALSE
1522 main.log.warn( "ONOS" + controllerStr +
1523 " hosts response: " +
1524 repr( hosts[ controller ] ) )
1525 utilities.assert_equals(
1526 expect=main.TRUE,
1527 actual=consistentHostsResult,
1528 onpass="Hosts view is consistent across all ONOS nodes",
1529 onfail="ONOS nodes have different views of hosts" )
1530
1531 main.step( "Each host has an IP address" )
1532 ipResult = main.TRUE
1533 for controller in range( 0, len( hosts ) ):
1534 controllerStr = str( controller + 1 )
1535 for host in hosts[ controller ]:
1536 if not host.get( 'ipAddresses', [ ] ):
1537 main.log.error( "DEBUG:Error with host ips on controller" +
1538 controllerStr + ": " + str( host ) )
1539 ipResult = main.FALSE
1540 utilities.assert_equals(
1541 expect=main.TRUE,
1542 actual=ipResult,
1543 onpass="The ips of the hosts aren't empty",
1544 onfail="The ip of at least one host is missing" )
1545
1546 # Strongly connected clusters of devices
1547 main.step( "Cluster view is consistent across ONOS nodes" )
1548 consistentClustersResult = main.TRUE
1549 for controller in range( len( clusters ) ):
1550 controllerStr = str( controller + 1 )
1551 if "Error" not in clusters[ controller ]:
1552 if clusters[ controller ] == clusters[ 0 ]:
1553 continue
1554 else: # clusters not consistent
1555 main.log.error( "clusters from ONOS" + controllerStr +
1556 " is inconsistent with ONOS1" )
1557 consistentClustersResult = main.FALSE
1558
1559 else:
1560 main.log.error( "Error in getting dataplane clusters " +
1561 "from ONOS" + controllerStr )
1562 consistentClustersResult = main.FALSE
1563 main.log.warn( "ONOS" + controllerStr +
1564 " clusters response: " +
1565 repr( clusters[ controller ] ) )
1566 utilities.assert_equals(
1567 expect=main.TRUE,
1568 actual=consistentClustersResult,
1569 onpass="Clusters view is consistent across all ONOS nodes",
1570 onfail="ONOS nodes have different views of clusters" )
1571 # there should always only be one cluster
1572 main.step( "Cluster view correct across ONOS nodes" )
1573 try:
1574 numClusters = len( json.loads( clusters[ 0 ] ) )
1575 except ( ValueError, TypeError ):
1576 main.log.exception( "Error parsing clusters[0]: " +
1577 repr( clusters[ 0 ] ) )
1578 clusterResults = main.FALSE
1579 if numClusters == 1:
1580 clusterResults = main.TRUE
1581 utilities.assert_equals(
1582 expect=1,
1583 actual=numClusters,
1584 onpass="ONOS shows 1 SCC",
1585 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1586
1587 main.step( "Comparing ONOS topology to MN" )
1588 devicesResults = main.TRUE
1589 linksResults = main.TRUE
1590 hostsResults = main.TRUE
1591 mnSwitches = main.Mininet1.getSwitches()
1592 mnLinks = main.Mininet1.getLinks()
1593 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001594 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001595 controllerStr = str( controller + 1 )
1596 if devices[ controller ] and ports[ controller ] and\
1597 "Error" not in devices[ controller ] and\
1598 "Error" not in ports[ controller ]:
1599
1600 currentDevicesResult = main.Mininet1.compareSwitches(
1601 mnSwitches,
1602 json.loads( devices[ controller ] ),
1603 json.loads( ports[ controller ] ) )
1604 else:
1605 currentDevicesResult = main.FALSE
1606 utilities.assert_equals( expect=main.TRUE,
1607 actual=currentDevicesResult,
1608 onpass="ONOS" + controllerStr +
1609 " Switches view is correct",
1610 onfail="ONOS" + controllerStr +
1611 " Switches view is incorrect" )
1612 if links[ controller ] and "Error" not in links[ controller ]:
1613 currentLinksResult = main.Mininet1.compareLinks(
1614 mnSwitches, mnLinks,
1615 json.loads( links[ controller ] ) )
1616 else:
1617 currentLinksResult = main.FALSE
1618 utilities.assert_equals( expect=main.TRUE,
1619 actual=currentLinksResult,
1620 onpass="ONOS" + controllerStr +
1621 " links view is correct",
1622 onfail="ONOS" + controllerStr +
1623 " links view is incorrect" )
1624
1625 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1626 currentHostsResult = main.Mininet1.compareHosts(
1627 mnHosts,
1628 hosts[ controller ] )
1629 else:
1630 currentHostsResult = main.FALSE
1631 utilities.assert_equals( expect=main.TRUE,
1632 actual=currentHostsResult,
1633 onpass="ONOS" + controllerStr +
1634 " hosts exist in Mininet",
1635 onfail="ONOS" + controllerStr +
1636 " hosts don't match Mininet" )
1637
1638 devicesResults = devicesResults and currentDevicesResult
1639 linksResults = linksResults and currentLinksResult
1640 hostsResults = hostsResults and currentHostsResult
1641
1642 main.step( "Device information is correct" )
1643 utilities.assert_equals(
1644 expect=main.TRUE,
1645 actual=devicesResults,
1646 onpass="Device information is correct",
1647 onfail="Device information is incorrect" )
1648
1649 main.step( "Links are correct" )
1650 utilities.assert_equals(
1651 expect=main.TRUE,
1652 actual=linksResults,
1653 onpass="Link are correct",
1654 onfail="Links are incorrect" )
1655
1656 main.step( "Hosts are correct" )
1657 utilities.assert_equals(
1658 expect=main.TRUE,
1659 actual=hostsResults,
1660 onpass="Hosts are correct",
1661 onfail="Hosts are incorrect" )
1662
1663 def CASE6( self, main ):
1664 """
1665 The Failure case.
1666 """
1667 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001668 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001669 assert main, "main not defined"
1670 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001671 assert main.CLIs, "main.CLIs not defined"
1672 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001673 main.case( "Restart minority of ONOS nodes" )
1674 main.step( "Killing 3 ONOS nodes" )
1675 killTime = time.time()
1676 # TODO: Randomize these nodes or base this on partitions
1677 # TODO: use threads in this case
Jon Halle1a3b752015-07-22 13:02:46 -07001678 killResults = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001679 time.sleep( 10 )
1680 killResults = killResults and\
Jon Halle1a3b752015-07-22 13:02:46 -07001681 main.ONOSbench.onosKill( main.nodes[1].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001682 time.sleep( 10 )
1683 killResults = killResults and\
Jon Halle1a3b752015-07-22 13:02:46 -07001684 main.ONOSbench.onosKill( main.nodes[2].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001685 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1686 onpass="ONOS Killed successfully",
1687 onfail="ONOS kill NOT successful" )
1688
1689 main.step( "Checking if ONOS is up yet" )
1690 count = 0
1691 onosIsupResult = main.FALSE
1692 while onosIsupResult == main.FALSE and count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001693 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
1694 onos2Isup = main.ONOSbench.isup( main.nodes[1].ip_address )
1695 onos3Isup = main.ONOSbench.isup( main.nodes[2].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001696 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
1697 count = count + 1
1698 # TODO: if it becomes an issue, we can retry this step a few times
1699 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1700 onpass="ONOS restarted successfully",
1701 onfail="ONOS restart NOT successful" )
1702
Jon Halle1a3b752015-07-22 13:02:46 -07001703 main.step( "Restarting ONOS main.CLIs" )
1704 cliResult1 = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
1705 cliResult2 = main.ONOScli2.startOnosCli( main.nodes[1].ip_address )
1706 cliResult3 = main.ONOScli3.startOnosCli( main.nodes[2].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001707 cliResults = cliResult1 and cliResult2 and cliResult3
1708 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1709 onpass="ONOS cli restarted",
1710 onfail="ONOS cli did not restart" )
1711
1712 # Grab the time of restart so we chan check how long the gossip
1713 # protocol has had time to work
1714 main.restartTime = time.time() - killTime
1715 main.log.debug( "Restart time: " + str( main.restartTime ) )
1716 '''
1717 # FIXME: revisit test plan for election with madan
1718 # Rerun for election on restarted nodes
Jon Halle1a3b752015-07-22 13:02:46 -07001719 run1 = main.CLIs[0].electionTestRun()
1720 run2 = main.CLIs[1].electionTestRun()
1721 run3 = main.CLIs[2].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001722 runResults = run1 and run2 and run3
1723 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1724 onpass="Reran for election",
1725 onfail="Failed to rerun for election" )
1726 '''
1727 # TODO: MAke this configurable. Also, we are breaking the above timer
1728 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001729 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1730 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1731 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001732
1733 def CASE7( self, main ):
1734 """
1735 Check state after ONOS failure
1736 """
1737 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001738 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001739 assert main, "main not defined"
1740 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001741 assert main.CLIs, "main.CLIs not defined"
1742 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001743 main.case( "Running ONOS Constant State Tests" )
1744
1745 main.step( "Check that each switch has a master" )
1746 # Assert that each device has a master
1747 rolesNotNull = main.TRUE
1748 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001749 for i in range( main.numCtrls ):
1750 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001751 name="rolesNotNull-" + str( i ),
1752 args=[ ] )
1753 threads.append( t )
1754 t.start()
1755
1756 for t in threads:
1757 t.join()
1758 rolesNotNull = rolesNotNull and t.result
1759 utilities.assert_equals(
1760 expect=main.TRUE,
1761 actual=rolesNotNull,
1762 onpass="Each device has a master",
1763 onfail="Some devices don't have a master assigned" )
1764
1765 main.step( "Read device roles from ONOS" )
1766 ONOSMastership = []
1767 consistentMastership = True
1768 rolesResults = True
1769 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001770 for i in range( main.numCtrls ):
1771 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001772 name="roles-" + str( i ),
1773 args=[] )
1774 threads.append( t )
1775 t.start()
1776
1777 for t in threads:
1778 t.join()
1779 ONOSMastership.append( t.result )
1780
Jon Halle1a3b752015-07-22 13:02:46 -07001781 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001782 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1783 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1784 " roles" )
1785 main.log.warn(
1786 "ONOS" + str( i + 1 ) + " mastership response: " +
1787 repr( ONOSMastership[i] ) )
1788 rolesResults = False
1789 utilities.assert_equals(
1790 expect=True,
1791 actual=rolesResults,
1792 onpass="No error in reading roles output",
1793 onfail="Error in reading roles from ONOS" )
1794
1795 main.step( "Check for consistency in roles from each controller" )
1796 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1797 main.log.info(
1798 "Switch roles are consistent across all ONOS nodes" )
1799 else:
1800 consistentMastership = False
1801 utilities.assert_equals(
1802 expect=True,
1803 actual=consistentMastership,
1804 onpass="Switch roles are consistent across all ONOS nodes",
1805 onfail="ONOS nodes have different views of switch roles" )
1806
1807 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001808 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001809 main.log.warn(
1810 "ONOS" + str( i + 1 ) + " roles: ",
1811 json.dumps(
1812 json.loads( ONOSMastership[ i ] ),
1813 sort_keys=True,
1814 indent=4,
1815 separators=( ',', ': ' ) ) )
1816
1817 # NOTE: we expect mastership to change on controller failure
1818 '''
1819 description2 = "Compare switch roles from before failure"
1820 main.step( description2 )
1821 try:
1822 currentJson = json.loads( ONOSMastership[0] )
1823 oldJson = json.loads( mastershipState )
1824 except ( ValueError, TypeError ):
1825 main.log.exception( "Something is wrong with parsing " +
1826 "ONOSMastership[0] or mastershipState" )
1827 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1828 main.log.error( "mastershipState" + repr( mastershipState ) )
1829 main.cleanup()
1830 main.exit()
1831 mastershipCheck = main.TRUE
1832 for i in range( 1, 29 ):
1833 switchDPID = str(
1834 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1835 current = [ switch[ 'master' ] for switch in currentJson
1836 if switchDPID in switch[ 'id' ] ]
1837 old = [ switch[ 'master' ] for switch in oldJson
1838 if switchDPID in switch[ 'id' ] ]
1839 if current == old:
1840 mastershipCheck = mastershipCheck and main.TRUE
1841 else:
1842 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1843 mastershipCheck = main.FALSE
1844 utilities.assert_equals(
1845 expect=main.TRUE,
1846 actual=mastershipCheck,
1847 onpass="Mastership of Switches was not changed",
1848 onfail="Mastership of some switches changed" )
1849 '''
1850
1851 main.step( "Get the intents and compare across all nodes" )
1852 ONOSIntents = []
1853 intentCheck = main.FALSE
1854 consistentIntents = True
1855 intentsResults = True
1856 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001857 for i in range( main.numCtrls ):
1858 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001859 name="intents-" + str( i ),
1860 args=[],
1861 kwargs={ 'jsonFormat': True } )
1862 threads.append( t )
1863 t.start()
1864
1865 for t in threads:
1866 t.join()
1867 ONOSIntents.append( t.result )
1868
Jon Halle1a3b752015-07-22 13:02:46 -07001869 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001870 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1871 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1872 " intents" )
1873 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1874 repr( ONOSIntents[ i ] ) )
1875 intentsResults = False
1876 utilities.assert_equals(
1877 expect=True,
1878 actual=intentsResults,
1879 onpass="No error in reading intents output",
1880 onfail="Error in reading intents from ONOS" )
1881
1882 main.step( "Check for consistency in Intents from each controller" )
1883 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1884 main.log.info( "Intents are consistent across all ONOS " +
1885 "nodes" )
1886 else:
1887 consistentIntents = False
1888
1889 # Try to make it easy to figure out what is happening
1890 #
1891 # Intent ONOS1 ONOS2 ...
1892 # 0x01 INSTALLED INSTALLING
1893 # ... ... ...
1894 # ... ... ...
1895 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001896 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001897 title += " " * 10 + "ONOS" + str( n + 1 )
1898 main.log.warn( title )
1899 # get all intent keys in the cluster
1900 keys = []
1901 for nodeStr in ONOSIntents:
1902 node = json.loads( nodeStr )
1903 for intent in node:
1904 keys.append( intent.get( 'id' ) )
1905 keys = set( keys )
1906 for key in keys:
1907 row = "%-13s" % key
1908 for nodeStr in ONOSIntents:
1909 node = json.loads( nodeStr )
1910 for intent in node:
1911 if intent.get( 'id' ) == key:
1912 row += "%-15s" % intent.get( 'state' )
1913 main.log.warn( row )
1914 # End table view
1915
1916 utilities.assert_equals(
1917 expect=True,
1918 actual=consistentIntents,
1919 onpass="Intents are consistent across all ONOS nodes",
1920 onfail="ONOS nodes have different views of intents" )
1921 intentStates = []
1922 for node in ONOSIntents: # Iter through ONOS nodes
1923 nodeStates = []
1924 # Iter through intents of a node
1925 try:
1926 for intent in json.loads( node ):
1927 nodeStates.append( intent[ 'state' ] )
1928 except ( ValueError, TypeError ):
1929 main.log.exception( "Error in parsing intents" )
1930 main.log.error( repr( node ) )
1931 intentStates.append( nodeStates )
1932 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1933 main.log.info( dict( out ) )
1934
1935 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07001936 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001937 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1938 main.log.warn( json.dumps(
1939 json.loads( ONOSIntents[ i ] ),
1940 sort_keys=True,
1941 indent=4,
1942 separators=( ',', ': ' ) ) )
1943 elif intentsResults and consistentIntents:
1944 intentCheck = main.TRUE
1945
1946 # NOTE: Store has no durability, so intents are lost across system
1947 # restarts
1948 main.step( "Compare current intents with intents before the failure" )
1949 # NOTE: this requires case 5 to pass for intentState to be set.
1950 # maybe we should stop the test if that fails?
1951 sameIntents = main.FALSE
1952 if intentState and intentState == ONOSIntents[ 0 ]:
1953 sameIntents = main.TRUE
1954 main.log.info( "Intents are consistent with before failure" )
1955 # TODO: possibly the states have changed? we may need to figure out
1956 # what the acceptable states are
1957 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1958 sameIntents = main.TRUE
1959 try:
1960 before = json.loads( intentState )
1961 after = json.loads( ONOSIntents[ 0 ] )
1962 for intent in before:
1963 if intent not in after:
1964 sameIntents = main.FALSE
1965 main.log.debug( "Intent is not currently in ONOS " +
1966 "(at least in the same form):" )
1967 main.log.debug( json.dumps( intent ) )
1968 except ( ValueError, TypeError ):
1969 main.log.exception( "Exception printing intents" )
1970 main.log.debug( repr( ONOSIntents[0] ) )
1971 main.log.debug( repr( intentState ) )
1972 if sameIntents == main.FALSE:
1973 try:
1974 main.log.debug( "ONOS intents before: " )
1975 main.log.debug( json.dumps( json.loads( intentState ),
1976 sort_keys=True, indent=4,
1977 separators=( ',', ': ' ) ) )
1978 main.log.debug( "Current ONOS intents: " )
1979 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1980 sort_keys=True, indent=4,
1981 separators=( ',', ': ' ) ) )
1982 except ( ValueError, TypeError ):
1983 main.log.exception( "Exception printing intents" )
1984 main.log.debug( repr( ONOSIntents[0] ) )
1985 main.log.debug( repr( intentState ) )
1986 utilities.assert_equals(
1987 expect=main.TRUE,
1988 actual=sameIntents,
1989 onpass="Intents are consistent with before failure",
1990 onfail="The Intents changed during failure" )
1991 intentCheck = intentCheck and sameIntents
1992
1993 main.step( "Get the OF Table entries and compare to before " +
1994 "component failure" )
1995 FlowTables = main.TRUE
1996 flows2 = []
1997 for i in range( 28 ):
1998 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall9043c902015-07-30 14:23:44 -07001999 tmpFlows = main.Mininet1.getFlowTable( 1.3, "s" + str( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002000 flows2.append( tmpFlows )
Jon Hall9043c902015-07-30 14:23:44 -07002001 tempResult = main.Mininet1.flowComp(
Jon Hall5cf14d52015-07-16 12:15:19 -07002002 flow1=flows[ i ],
2003 flow2=tmpFlows )
2004 FlowTables = FlowTables and tempResult
2005 if FlowTables == main.FALSE:
2006 main.log.info( "Differences in flow table for switch: s" +
2007 str( i + 1 ) )
2008 utilities.assert_equals(
2009 expect=main.TRUE,
2010 actual=FlowTables,
2011 onpass="No changes were found in the flow tables",
2012 onfail="Changes were found in the flow tables" )
2013
2014 main.Mininet2.pingLongKill()
2015 '''
2016 main.step( "Check the continuous pings to ensure that no packets " +
2017 "were dropped during component failure" )
2018 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2019 main.params[ 'TESTONIP' ] )
2020 LossInPings = main.FALSE
2021 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2022 for i in range( 8, 18 ):
2023 main.log.info(
2024 "Checking for a loss in pings along flow from s" +
2025 str( i ) )
2026 LossInPings = main.Mininet2.checkForLoss(
2027 "/tmp/ping.h" +
2028 str( i ) ) or LossInPings
2029 if LossInPings == main.TRUE:
2030 main.log.info( "Loss in ping detected" )
2031 elif LossInPings == main.ERROR:
2032 main.log.info( "There are multiple mininet process running" )
2033 elif LossInPings == main.FALSE:
2034 main.log.info( "No Loss in the pings" )
2035 main.log.info( "No loss of dataplane connectivity" )
2036 utilities.assert_equals(
2037 expect=main.FALSE,
2038 actual=LossInPings,
2039 onpass="No Loss of connectivity",
2040 onfail="Loss of dataplane connectivity detected" )
2041 '''
2042
2043 main.step( "Leadership Election is still functional" )
2044 # Test of LeadershipElection
2045 leaderList = []
2046 # FIXME: make sure this matches nodes that were restarted
Jon Halle1a3b752015-07-22 13:02:46 -07002047 restarted = [ main.nodes[0].ip_address, main.nodes[1].ip_address,
2048 main.nodes[2].ip_address ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002049
2050 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002051 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002052 leaderN = cli.electionTestLeader()
2053 leaderList.append( leaderN )
2054 if leaderN == main.FALSE:
2055 # error in response
2056 main.log.error( "Something is wrong with " +
2057 "electionTestLeader function, check the" +
2058 " error logs" )
2059 leaderResult = main.FALSE
2060 elif leaderN is None:
2061 main.log.error( cli.name +
2062 " shows no leader for the election-app was" +
2063 " elected after the old one died" )
2064 leaderResult = main.FALSE
2065 elif leaderN in restarted:
2066 main.log.error( cli.name + " shows " + str( leaderN ) +
2067 " as leader for the election-app, but it " +
2068 "was restarted" )
2069 leaderResult = main.FALSE
2070 if len( set( leaderList ) ) != 1:
2071 leaderResult = main.FALSE
2072 main.log.error(
2073 "Inconsistent view of leader for the election test app" )
2074 # TODO: print the list
2075 utilities.assert_equals(
2076 expect=main.TRUE,
2077 actual=leaderResult,
2078 onpass="Leadership election passed",
2079 onfail="Something went wrong with Leadership election" )
2080
2081 def CASE8( self, main ):
2082 """
2083 Compare topo
2084 """
2085 import json
2086 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002087 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002088 assert main, "main not defined"
2089 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002090 assert main.CLIs, "main.CLIs not defined"
2091 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002092
2093 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002094 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002095 " and ONOS"
2096
2097 main.step( "Comparing ONOS topology to MN" )
2098 devicesResults = main.TRUE
2099 linksResults = main.TRUE
2100 hostsResults = main.TRUE
2101 hostAttachmentResults = True
2102 topoResult = main.FALSE
2103 elapsed = 0
2104 count = 0
2105 main.step( "Collecting topology information from ONOS" )
2106 startTime = time.time()
2107 # Give time for Gossip to work
2108 while topoResult == main.FALSE and elapsed < 60:
2109 count += 1
2110 cliStart = time.time()
2111 devices = []
2112 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002113 for i in range( main.numCtrls ):
2114 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002115 name="devices-" + str( i ),
2116 args=[ ] )
2117 threads.append( t )
2118 t.start()
2119
2120 for t in threads:
2121 t.join()
2122 devices.append( t.result )
2123 hosts = []
2124 ipResult = main.TRUE
2125 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002126 for i in range( main.numCtrls ):
2127 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002128 name="hosts-" + str( i ),
2129 args=[ ] )
2130 threads.append( t )
2131 t.start()
2132
2133 for t in threads:
2134 t.join()
2135 try:
2136 hosts.append( json.loads( t.result ) )
2137 except ( ValueError, TypeError ):
2138 main.log.exception( "Error parsing hosts results" )
2139 main.log.error( repr( t.result ) )
2140 for controller in range( 0, len( hosts ) ):
2141 controllerStr = str( controller + 1 )
2142 for host in hosts[ controller ]:
2143 if host is None or host.get( 'ipAddresses', [] ) == []:
2144 main.log.error(
2145 "DEBUG:Error with host ipAddresses on controller" +
2146 controllerStr + ": " + str( host ) )
2147 ipResult = main.FALSE
2148 ports = []
2149 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002150 for i in range( main.numCtrls ):
2151 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002152 name="ports-" + str( i ),
2153 args=[ ] )
2154 threads.append( t )
2155 t.start()
2156
2157 for t in threads:
2158 t.join()
2159 ports.append( t.result )
2160 links = []
2161 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002162 for i in range( main.numCtrls ):
2163 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002164 name="links-" + str( i ),
2165 args=[ ] )
2166 threads.append( t )
2167 t.start()
2168
2169 for t in threads:
2170 t.join()
2171 links.append( t.result )
2172 clusters = []
2173 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002174 for i in range( main.numCtrls ):
2175 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002176 name="clusters-" + str( i ),
2177 args=[ ] )
2178 threads.append( t )
2179 t.start()
2180
2181 for t in threads:
2182 t.join()
2183 clusters.append( t.result )
2184
2185 elapsed = time.time() - startTime
2186 cliTime = time.time() - cliStart
2187 print "Elapsed time: " + str( elapsed )
2188 print "CLI time: " + str( cliTime )
2189
2190 mnSwitches = main.Mininet1.getSwitches()
2191 mnLinks = main.Mininet1.getLinks()
2192 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002193 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002194 controllerStr = str( controller + 1 )
2195 if devices[ controller ] and ports[ controller ] and\
2196 "Error" not in devices[ controller ] and\
2197 "Error" not in ports[ controller ]:
2198
2199 currentDevicesResult = main.Mininet1.compareSwitches(
2200 mnSwitches,
2201 json.loads( devices[ controller ] ),
2202 json.loads( ports[ controller ] ) )
2203 else:
2204 currentDevicesResult = main.FALSE
2205 utilities.assert_equals( expect=main.TRUE,
2206 actual=currentDevicesResult,
2207 onpass="ONOS" + controllerStr +
2208 " Switches view is correct",
2209 onfail="ONOS" + controllerStr +
2210 " Switches view is incorrect" )
2211
2212 if links[ controller ] and "Error" not in links[ controller ]:
2213 currentLinksResult = main.Mininet1.compareLinks(
2214 mnSwitches, mnLinks,
2215 json.loads( links[ controller ] ) )
2216 else:
2217 currentLinksResult = main.FALSE
2218 utilities.assert_equals( expect=main.TRUE,
2219 actual=currentLinksResult,
2220 onpass="ONOS" + controllerStr +
2221 " links view is correct",
2222 onfail="ONOS" + controllerStr +
2223 " links view is incorrect" )
2224
2225 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2226 currentHostsResult = main.Mininet1.compareHosts(
2227 mnHosts,
2228 hosts[ controller ] )
2229 else:
2230 currentHostsResult = main.FALSE
2231 utilities.assert_equals( expect=main.TRUE,
2232 actual=currentHostsResult,
2233 onpass="ONOS" + controllerStr +
2234 " hosts exist in Mininet",
2235 onfail="ONOS" + controllerStr +
2236 " hosts don't match Mininet" )
2237 # CHECKING HOST ATTACHMENT POINTS
2238 hostAttachment = True
2239 zeroHosts = False
2240 # FIXME: topo-HA/obelisk specific mappings:
2241 # key is mac and value is dpid
2242 mappings = {}
2243 for i in range( 1, 29 ): # hosts 1 through 28
2244 # set up correct variables:
2245 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2246 if i == 1:
2247 deviceId = "1000".zfill(16)
2248 elif i == 2:
2249 deviceId = "2000".zfill(16)
2250 elif i == 3:
2251 deviceId = "3000".zfill(16)
2252 elif i == 4:
2253 deviceId = "3004".zfill(16)
2254 elif i == 5:
2255 deviceId = "5000".zfill(16)
2256 elif i == 6:
2257 deviceId = "6000".zfill(16)
2258 elif i == 7:
2259 deviceId = "6007".zfill(16)
2260 elif i >= 8 and i <= 17:
2261 dpid = '3' + str( i ).zfill( 3 )
2262 deviceId = dpid.zfill(16)
2263 elif i >= 18 and i <= 27:
2264 dpid = '6' + str( i ).zfill( 3 )
2265 deviceId = dpid.zfill(16)
2266 elif i == 28:
2267 deviceId = "2800".zfill(16)
2268 mappings[ macId ] = deviceId
2269 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2270 if hosts[ controller ] == []:
2271 main.log.warn( "There are no hosts discovered" )
2272 zeroHosts = True
2273 else:
2274 for host in hosts[ controller ]:
2275 mac = None
2276 location = None
2277 device = None
2278 port = None
2279 try:
2280 mac = host.get( 'mac' )
2281 assert mac, "mac field could not be found for this host object"
2282
2283 location = host.get( 'location' )
2284 assert location, "location field could not be found for this host object"
2285
2286 # Trim the protocol identifier off deviceId
2287 device = str( location.get( 'elementId' ) ).split(':')[1]
2288 assert device, "elementId field could not be found for this host location object"
2289
2290 port = location.get( 'port' )
2291 assert port, "port field could not be found for this host location object"
2292
2293 # Now check if this matches where they should be
2294 if mac and device and port:
2295 if str( port ) != "1":
2296 main.log.error( "The attachment port is incorrect for " +
2297 "host " + str( mac ) +
2298 ". Expected: 1 Actual: " + str( port) )
2299 hostAttachment = False
2300 if device != mappings[ str( mac ) ]:
2301 main.log.error( "The attachment device is incorrect for " +
2302 "host " + str( mac ) +
2303 ". Expected: " + mappings[ str( mac ) ] +
2304 " Actual: " + device )
2305 hostAttachment = False
2306 else:
2307 hostAttachment = False
2308 except AssertionError:
2309 main.log.exception( "Json object not as expected" )
2310 main.log.error( repr( host ) )
2311 hostAttachment = False
2312 else:
2313 main.log.error( "No hosts json output or \"Error\"" +
2314 " in output. hosts = " +
2315 repr( hosts[ controller ] ) )
2316 if zeroHosts is False:
2317 hostAttachment = True
2318
2319 # END CHECKING HOST ATTACHMENT POINTS
2320 devicesResults = devicesResults and currentDevicesResult
2321 linksResults = linksResults and currentLinksResult
2322 hostsResults = hostsResults and currentHostsResult
2323 hostAttachmentResults = hostAttachmentResults and\
2324 hostAttachment
2325
2326 # Compare json objects for hosts and dataplane clusters
2327
2328 # hosts
2329 main.step( "Hosts view is consistent across all ONOS nodes" )
2330 consistentHostsResult = main.TRUE
2331 for controller in range( len( hosts ) ):
2332 controllerStr = str( controller + 1 )
2333 if "Error" not in hosts[ controller ]:
2334 if hosts[ controller ] == hosts[ 0 ]:
2335 continue
2336 else: # hosts not consistent
2337 main.log.error( "hosts from ONOS" + controllerStr +
2338 " is inconsistent with ONOS1" )
2339 main.log.warn( repr( hosts[ controller ] ) )
2340 consistentHostsResult = main.FALSE
2341
2342 else:
2343 main.log.error( "Error in getting ONOS hosts from ONOS" +
2344 controllerStr )
2345 consistentHostsResult = main.FALSE
2346 main.log.warn( "ONOS" + controllerStr +
2347 " hosts response: " +
2348 repr( hosts[ controller ] ) )
2349 utilities.assert_equals(
2350 expect=main.TRUE,
2351 actual=consistentHostsResult,
2352 onpass="Hosts view is consistent across all ONOS nodes",
2353 onfail="ONOS nodes have different views of hosts" )
2354
2355 main.step( "Hosts information is correct" )
2356 hostsResults = hostsResults and ipResult
2357 utilities.assert_equals(
2358 expect=main.TRUE,
2359 actual=hostsResults,
2360 onpass="Host information is correct",
2361 onfail="Host information is incorrect" )
2362
2363 main.step( "Host attachment points to the network" )
2364 utilities.assert_equals(
2365 expect=True,
2366 actual=hostAttachmentResults,
2367 onpass="Hosts are correctly attached to the network",
2368 onfail="ONOS did not correctly attach hosts to the network" )
2369
2370 # Strongly connected clusters of devices
2371 main.step( "Clusters view is consistent across all ONOS nodes" )
2372 consistentClustersResult = main.TRUE
2373 for controller in range( len( clusters ) ):
2374 controllerStr = str( controller + 1 )
2375 if "Error" not in clusters[ controller ]:
2376 if clusters[ controller ] == clusters[ 0 ]:
2377 continue
2378 else: # clusters not consistent
2379 main.log.error( "clusters from ONOS" +
2380 controllerStr +
2381 " is inconsistent with ONOS1" )
2382 consistentClustersResult = main.FALSE
2383
2384 else:
2385 main.log.error( "Error in getting dataplane clusters " +
2386 "from ONOS" + controllerStr )
2387 consistentClustersResult = main.FALSE
2388 main.log.warn( "ONOS" + controllerStr +
2389 " clusters response: " +
2390 repr( clusters[ controller ] ) )
2391 utilities.assert_equals(
2392 expect=main.TRUE,
2393 actual=consistentClustersResult,
2394 onpass="Clusters view is consistent across all ONOS nodes",
2395 onfail="ONOS nodes have different views of clusters" )
2396
2397 main.step( "There is only one SCC" )
2398 # there should always only be one cluster
2399 try:
2400 numClusters = len( json.loads( clusters[ 0 ] ) )
2401 except ( ValueError, TypeError ):
2402 main.log.exception( "Error parsing clusters[0]: " +
2403 repr( clusters[0] ) )
2404 clusterResults = main.FALSE
2405 if numClusters == 1:
2406 clusterResults = main.TRUE
2407 utilities.assert_equals(
2408 expect=1,
2409 actual=numClusters,
2410 onpass="ONOS shows 1 SCC",
2411 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2412
2413 topoResult = ( devicesResults and linksResults
2414 and hostsResults and consistentHostsResult
2415 and consistentClustersResult and clusterResults
2416 and ipResult and hostAttachmentResults )
2417
2418 topoResult = topoResult and int( count <= 2 )
2419 note = "note it takes about " + str( int( cliTime ) ) + \
2420 " seconds for the test to make all the cli calls to fetch " +\
2421 "the topology from each ONOS instance"
2422 main.log.info(
2423 "Very crass estimate for topology discovery/convergence( " +
2424 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2425 str( count ) + " tries" )
2426
2427 main.step( "Device information is correct" )
2428 utilities.assert_equals(
2429 expect=main.TRUE,
2430 actual=devicesResults,
2431 onpass="Device information is correct",
2432 onfail="Device information is incorrect" )
2433
2434 main.step( "Links are correct" )
2435 utilities.assert_equals(
2436 expect=main.TRUE,
2437 actual=linksResults,
2438 onpass="Link are correct",
2439 onfail="Links are incorrect" )
2440
2441 # FIXME: move this to an ONOS state case
2442 main.step( "Checking ONOS nodes" )
2443 nodesOutput = []
2444 nodeResults = main.TRUE
2445 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002446 for i in range( main.numCtrls ):
2447 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002448 name="nodes-" + str( i ),
2449 args=[ ] )
2450 threads.append( t )
2451 t.start()
2452
2453 for t in threads:
2454 t.join()
2455 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002456 ips = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002457 for i in nodesOutput:
2458 try:
2459 current = json.loads( i )
2460 for node in current:
2461 currentResult = main.FALSE
2462 if node['ip'] in ips: # node in nodes() output is in cell
2463 if node['state'] == 'ACTIVE':
2464 currentResult = main.TRUE
2465 else:
2466 main.log.error( "Error in ONOS node availability" )
2467 main.log.error(
2468 json.dumps( current,
2469 sort_keys=True,
2470 indent=4,
2471 separators=( ',', ': ' ) ) )
2472 break
2473 nodeResults = nodeResults and currentResult
2474 except ( ValueError, TypeError ):
2475 main.log.error( "Error parsing nodes output" )
2476 main.log.warn( repr( i ) )
2477 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2478 onpass="Nodes check successful",
2479 onfail="Nodes check NOT successful" )
2480
2481 def CASE9( self, main ):
2482 """
2483 Link s3-s28 down
2484 """
2485 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002486 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002487 assert main, "main not defined"
2488 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002489 assert main.CLIs, "main.CLIs not defined"
2490 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002491 # NOTE: You should probably run a topology check after this
2492
2493 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2494
2495 description = "Turn off a link to ensure that Link Discovery " +\
2496 "is working properly"
2497 main.case( description )
2498
2499 main.step( "Kill Link between s3 and s28" )
2500 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2501 main.log.info( "Waiting " + str( linkSleep ) +
2502 " seconds for link down to be discovered" )
2503 time.sleep( linkSleep )
2504 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2505 onpass="Link down successful",
2506 onfail="Failed to bring link down" )
2507 # TODO do some sort of check here
2508
2509 def CASE10( self, main ):
2510 """
2511 Link s3-s28 up
2512 """
2513 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002514 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002515 assert main, "main not defined"
2516 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002517 assert main.CLIs, "main.CLIs not defined"
2518 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002519 # NOTE: You should probably run a topology check after this
2520
2521 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2522
2523 description = "Restore a link to ensure that Link Discovery is " + \
2524 "working properly"
2525 main.case( description )
2526
2527 main.step( "Bring link between s3 and s28 back up" )
2528 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2529 main.log.info( "Waiting " + str( linkSleep ) +
2530 " seconds for link up to be discovered" )
2531 time.sleep( linkSleep )
2532 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2533 onpass="Link up successful",
2534 onfail="Failed to bring link up" )
2535 # TODO do some sort of check here
2536
2537 def CASE11( self, main ):
2538 """
2539 Switch Down
2540 """
2541 # NOTE: You should probably run a topology check after this
2542 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002543 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002544 assert main, "main not defined"
2545 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002546 assert main.CLIs, "main.CLIs not defined"
2547 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002548
2549 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2550
2551 description = "Killing a switch to ensure it is discovered correctly"
2552 main.case( description )
2553 switch = main.params[ 'kill' ][ 'switch' ]
2554 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2555
2556 # TODO: Make this switch parameterizable
2557 main.step( "Kill " + switch )
2558 main.log.info( "Deleting " + switch )
2559 main.Mininet1.delSwitch( switch )
2560 main.log.info( "Waiting " + str( switchSleep ) +
2561 " seconds for switch down to be discovered" )
2562 time.sleep( switchSleep )
2563 device = main.ONOScli1.getDevice( dpid=switchDPID )
2564 # Peek at the deleted switch
2565 main.log.warn( str( device ) )
2566 result = main.FALSE
2567 if device and device[ 'available' ] is False:
2568 result = main.TRUE
2569 utilities.assert_equals( expect=main.TRUE, actual=result,
2570 onpass="Kill switch successful",
2571 onfail="Failed to kill switch?" )
2572
2573 def CASE12( self, main ):
2574 """
2575 Switch Up
2576 """
2577 # NOTE: You should probably run a topology check after this
2578 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002579 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002580 assert main, "main not defined"
2581 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002582 assert main.CLIs, "main.CLIs not defined"
2583 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002584 assert ONOS1Port, "ONOS1Port not defined"
2585 assert ONOS2Port, "ONOS2Port not defined"
2586 assert ONOS3Port, "ONOS3Port not defined"
2587 assert ONOS4Port, "ONOS4Port not defined"
2588 assert ONOS5Port, "ONOS5Port not defined"
2589 assert ONOS6Port, "ONOS6Port not defined"
2590 assert ONOS7Port, "ONOS7Port not defined"
2591
2592 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2593 switch = main.params[ 'kill' ][ 'switch' ]
2594 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2595 links = main.params[ 'kill' ][ 'links' ].split()
2596 description = "Adding a switch to ensure it is discovered correctly"
2597 main.case( description )
2598
2599 main.step( "Add back " + switch )
2600 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2601 for peer in links:
2602 main.Mininet1.addLink( switch, peer )
2603 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002604 for i in range( main.numCtrls ):
2605 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002606 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2607 main.log.info( "Waiting " + str( switchSleep ) +
2608 " seconds for switch up to be discovered" )
2609 time.sleep( switchSleep )
2610 device = main.ONOScli1.getDevice( dpid=switchDPID )
2611 # Peek at the deleted switch
2612 main.log.warn( str( device ) )
2613 result = main.FALSE
2614 if device and device[ 'available' ]:
2615 result = main.TRUE
2616 utilities.assert_equals( expect=main.TRUE, actual=result,
2617 onpass="add switch successful",
2618 onfail="Failed to add switch?" )
2619
2620 def CASE13( self, main ):
2621 """
2622 Clean up
2623 """
2624 import os
2625 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002626 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002627 assert main, "main not defined"
2628 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002629 assert main.CLIs, "main.CLIs not defined"
2630 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002631
2632 # printing colors to terminal
2633 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2634 'blue': '\033[94m', 'green': '\033[92m',
2635 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2636 main.case( "Test Cleanup" )
2637 main.step( "Killing tcpdumps" )
2638 main.Mininet2.stopTcpdump()
2639
2640 testname = main.TEST
2641 if main.params[ 'BACKUP' ] == "True":
2642 main.step( "Copying MN pcap and ONOS log files to test station" )
2643 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2644 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
2645 # NOTE: MN Pcap file is being saved to ~/packet_captures
2646 # scp this file as MN and TestON aren't necessarily the same vm
2647 # FIXME: scp
2648 # mn files
2649 # TODO: Load these from params
2650 # NOTE: must end in /
2651 logFolder = "/opt/onos/log/"
2652 logFiles = [ "karaf.log", "karaf.log.1" ]
2653 # NOTE: must end in /
2654 dstDir = "~/packet_captures/"
2655 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002656 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002657 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2658 ":" + logFolder + f + " " +
2659 teststationUser + "@" +
2660 teststationIP + ":" +
2661 dstDir + str( testname ) +
2662 "-" + node.name + "-" + f )
2663 main.ONOSbench.handle.expect( "\$" )
2664
2665 # std*.log's
2666 # NOTE: must end in /
2667 logFolder = "/opt/onos/var/"
2668 logFiles = [ "stderr.log", "stdout.log" ]
2669 # NOTE: must end in /
2670 dstDir = "~/packet_captures/"
2671 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002672 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002673 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2674 ":" + logFolder + f + " " +
2675 teststationUser + "@" +
2676 teststationIP + ":" +
2677 dstDir + str( testname ) +
2678 "-" + node.name + "-" + f )
2679 main.ONOSbench.handle.expect( "\$" )
2680 # sleep so scp can finish
2681 time.sleep( 10 )
2682 main.step( "Packing and rotating pcap archives" )
2683 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
2684
2685 main.step( "Stopping Mininet" )
2686 mnResult = main.Mininet1.stopNet()
2687 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2688 onpass="Mininet stopped",
2689 onfail="MN cleanup NOT successful" )
2690
2691 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002692 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002693 print colors[ 'purple' ] + "Checking logs for errors on " + \
2694 node.name + ":" + colors[ 'end' ]
2695 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
2696
2697 try:
2698 timerLog = open( main.logdir + "/Timers.csv", 'w')
2699 # Overwrite with empty line and close
2700 labels = "Gossip Intents, Restart"
2701 data = str( gossipTime ) + ", " + str( main.restartTime )
2702 timerLog.write( labels + "\n" + data )
2703 timerLog.close()
2704 except NameError, e:
2705 main.log.exception(e)
2706
2707 def CASE14( self, main ):
2708 """
2709 start election app on all onos nodes
2710 """
Jon Halle1a3b752015-07-22 13:02:46 -07002711 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002712 assert main, "main not defined"
2713 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002714 assert main.CLIs, "main.CLIs not defined"
2715 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002716
2717 main.case("Start Leadership Election app")
2718 main.step( "Install leadership election app" )
2719 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2720 utilities.assert_equals(
2721 expect=main.TRUE,
2722 actual=appResult,
2723 onpass="Election app installed",
2724 onfail="Something went wrong with installing Leadership election" )
2725
2726 main.step( "Run for election on each node" )
2727 leaderResult = main.TRUE
2728 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002729 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002730 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002731 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002732 leader = cli.electionTestLeader()
2733 if leader is None or leader == main.FALSE:
2734 main.log.error( cli.name + ": Leader for the election app " +
2735 "should be an ONOS node, instead got '" +
2736 str( leader ) + "'" )
2737 leaderResult = main.FALSE
2738 leaders.append( leader )
2739 utilities.assert_equals(
2740 expect=main.TRUE,
2741 actual=leaderResult,
2742 onpass="Successfully ran for leadership",
2743 onfail="Failed to run for leadership" )
2744
2745 main.step( "Check that each node shows the same leader" )
2746 sameLeader = main.TRUE
2747 if len( set( leaders ) ) != 1:
2748 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002749 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002750 str( leaders ) )
2751 utilities.assert_equals(
2752 expect=main.TRUE,
2753 actual=sameLeader,
2754 onpass="Leadership is consistent for the election topic",
2755 onfail="Nodes have different leaders" )
2756
2757 def CASE15( self, main ):
2758 """
2759 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002760 15.1 Run election on each node
2761 15.2 Check that each node has the same leaders and candidates
2762 15.3 Find current leader and withdraw
2763 15.4 Check that a new node was elected leader
2764 15.5 Check that that new leader was the candidate of old leader
2765 15.6 Run for election on old leader
2766 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2767 15.8 Make sure that the old leader was added to the candidate list
2768
2769 old and new variable prefixes refer to data from before vs after
2770 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002771 """
2772 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002773 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002774 assert main, "main not defined"
2775 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002776 assert main.CLIs, "main.CLIs not defined"
2777 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002778
Jon Hall5cf14d52015-07-16 12:15:19 -07002779 description = "Check that Leadership Election is still functional"
2780 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002781 # NOTE: Need to re-run since being a canidate is not persistant
2782 # TODO: add check for "Command not found:" in the driver, this
2783 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002784
acsmars71adceb2015-08-31 15:09:26 -07002785 oldLeaders = [] # leaders by node before withdrawl from candidates
2786 newLeaders = [] # leaders by node after withdrawl from candidates
2787 oldAllCandidates = [] # list of lists of each nodes' candidates before
2788 newAllCandidates = [] # list of lists of each nodes' candidates after
2789 oldCandidates = [] # list of candidates from node 0 before withdrawl
2790 newCandidates = [] # list of candidates from node 0 after withdrawl
2791 oldLeader = '' # the old leader from oldLeaders, None if not same
2792 newLeader = '' # the new leaders fron newLoeaders, None if not same
2793 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2794 expectNoLeader = False # True when there is only one leader
2795 if main.numCtrls == 1:
2796 expectNoLeader = True
2797
2798 main.step( "Run for election on each node" )
2799 electionResult = main.TRUE
2800
2801 for cli in main.CLIs: # run test election on each node
2802 if cli.electionTestRun() == main.FALSE:
2803 electionResult = main.FALSE
2804
Jon Hall5cf14d52015-07-16 12:15:19 -07002805 utilities.assert_equals(
2806 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002807 actual=electionResult,
2808 onpass="All nodes successfully ran for leadership",
2809 onfail="At least one node failed to run for leadership" )
2810
2811 main.step( "Check that each node shows the same leader and candidates" )
2812 sameResult = main.TRUE
2813 failMessage = "Nodes have different leaders"
2814 for cli in main.CLIs:
2815 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2816 oldAllCandidates.append( node )
2817 oldLeaders.append( node[ 0 ] )
2818 oldCandidates = oldAllCandidates[ 0 ]
2819
2820 # Check that each node has the same leader. Defines oldLeader
2821 if len( set( oldLeaders ) ) != 1:
2822 sameResult = main.FALSE
2823 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2824 oldLeader = None
2825 else:
2826 oldLeader = oldLeaders[ 0 ]
2827
2828 # Check that each node's candidate list is the same
2829 for candidates in oldAllCandidates:
2830 if set( candidates ) != set( oldCandidates ):
2831 sameResult = main.FALSE
2832 failMessage += "and candidates"
2833
2834 utilities.assert_equals(
2835 expect=main.TRUE,
2836 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002837 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002838 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002839
2840 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002841 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002842 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002843 if oldLeader is None:
2844 main.log.error( "Leadership isn't consistent." )
2845 withdrawResult = main.FALSE
2846 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002847 for i in range( len( main.CLIs ) ):
acsmars71adceb2015-08-31 15:09:26 -07002848 if oldLeader == main.nodes[ i ].ip_address:
2849 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002850 break
2851 else: # FOR/ELSE statement
2852 main.log.error( "Leader election, could not find current leader" )
2853 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002854 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 utilities.assert_equals(
2856 expect=main.TRUE,
2857 actual=withdrawResult,
2858 onpass="Node was withdrawn from election",
2859 onfail="Node was not withdrawn from election" )
2860
acsmars71adceb2015-08-31 15:09:26 -07002861 main.step( "Check that a new node was elected leader" )
2862
Jon Hall5cf14d52015-07-16 12:15:19 -07002863 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002864 newLeaderResult = main.TRUE
2865 failMessage = "Nodes have different leaders"
2866
2867 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002868 for cli in main.CLIs:
acsmars71adceb2015-08-31 15:09:26 -07002869 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2870 # elections might no have finished yet
2871 if node[ 0 ] == 'none' and not expectNoLeader:
2872 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2873 "sure elections are complete." )
2874 time.sleep(5)
2875 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2876 # election still isn't done or there is a problem
2877 if node[ 0 ] == 'none':
2878 main.log.error( "No leader was elected on at least 1 node" )
2879 newLeaderResult = main.FALSE
2880 newAllCandidates.append( node )
2881 newLeaders.append( node[ 0 ] )
2882 newCandidates = newAllCandidates[ 0 ]
2883
2884 # Check that each node has the same leader. Defines newLeader
2885 if len( set( newLeaders ) ) != 1:
2886 newLeaderResult = main.FALSE
2887 main.log.error( "Nodes have different leaders: " +
2888 str( newLeaders ) )
2889 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002890 else:
acsmars71adceb2015-08-31 15:09:26 -07002891 newLeader = newLeaders[ 0 ]
2892
2893 # Check that each node's candidate list is the same
2894 for candidates in newAllCandidates:
2895 if set( candidates ) != set( newCandidates ):
2896 newLeaderResult = main.FALSE
2897 main.error.log( "Discrepancy in candidate lists detected" )
2898
2899 # Check that the new leader is not the older leader, which was withdrawn
2900 if newLeader == oldLeader:
2901 newLeaderResult = main.FALSE
2902 main.log.error( "All nodes still see old leader: " + oldLeader +
2903 " as the current leader" )
2904
Jon Hall5cf14d52015-07-16 12:15:19 -07002905 utilities.assert_equals(
2906 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002907 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002908 onpass="Leadership election passed",
2909 onfail="Something went wrong with Leadership election" )
2910
acsmars71adceb2015-08-31 15:09:26 -07002911 main.step( "Check that that new leader was the candidate of old leader")
2912 # candidates[ 2 ] should be come the top candidate after withdrawl
2913 correctCandidateResult = main.TRUE
2914 if expectNoLeader:
2915 if newLeader == 'none':
2916 main.log.info( "No leader expected. None found. Pass" )
2917 correctCandidateResult = main.TRUE
2918 else:
2919 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2920 correctCandidateResult = main.FALSE
2921 elif newLeader != oldCandidates[ 2 ]:
2922 correctCandidateResult = main.FALSE
2923 main.log.error( "Candidate " + newLeader + " was elected. " +
2924 oldCandidates[ 2 ] + " should have had priority." )
2925
2926 utilities.assert_equals(
2927 expect=main.TRUE,
2928 actual=correctCandidateResult,
2929 onpass="Correct Candidate Elected",
2930 onfail="Incorrect Candidate Elected" )
2931
Jon Hall5cf14d52015-07-16 12:15:19 -07002932 main.step( "Run for election on old leader( just so everyone " +
2933 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002934 if oldLeaderCLI is not None:
2935 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002936 else:
acsmars71adceb2015-08-31 15:09:26 -07002937 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002938 runResult = main.FALSE
2939 utilities.assert_equals(
2940 expect=main.TRUE,
2941 actual=runResult,
2942 onpass="App re-ran for election",
2943 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002944 main.step(
2945 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002946 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07002947 positionResult = main.TRUE
2948 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
2949
2950 # Reset and reuse the new candidate and leaders lists
2951 newAllCandidates = []
2952 newCandidates = []
2953 newLeaders = []
2954 for cli in main.CLIs:
2955 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2956 if oldLeader not in node: # election might no have finished yet
2957 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2958 "be sure elections are complete" )
2959 time.sleep(5)
2960 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2961 if oldLeader not in node: # election still isn't done, errors
2962 main.log.error(
2963 "Old leader was not elected on at least one node" )
2964 positionResult = main.FALSE
2965 newAllCandidates.append( node )
2966 newLeaders.append( node[ 0 ] )
2967 newCandidates = newAllCandidates[ 0 ]
2968
2969 # Check that each node has the same leader. Defines newLeader
2970 if len( set( newLeaders ) ) != 1:
2971 positionResult = main.FALSE
2972 main.log.error( "Nodes have different leaders: " +
2973 str( newLeaders ) )
2974 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002975 else:
acsmars71adceb2015-08-31 15:09:26 -07002976 newLeader = newLeaders[ 0 ]
2977
2978 # Check that each node's candidate list is the same
2979 for candidates in newAllCandidates:
2980 if set( candidates ) != set( newCandidates ):
2981 newLeaderResult = main.FALSE
2982 main.error.log( "Discrepancy in candidate lists detected" )
2983
2984 # Check that the re-elected node is last on the candidate List
2985 if oldLeader != newCandidates[ -1 ]:
2986 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2987 str( newCandidates ) )
2988 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002989
2990 utilities.assert_equals(
2991 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002992 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002993 onpass="Old leader successfully re-ran for election",
2994 onfail="Something went wrong with Leadership election after " +
2995 "the old leader re-ran for election" )
2996
2997 def CASE16( self, main ):
2998 """
2999 Install Distributed Primitives app
3000 """
3001 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003002 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003003 assert main, "main not defined"
3004 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003005 assert main.CLIs, "main.CLIs not defined"
3006 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003007
3008 # Variables for the distributed primitives tests
3009 global pCounterName
3010 global iCounterName
3011 global pCounterValue
3012 global iCounterValue
3013 global onosSet
3014 global onosSetName
3015 pCounterName = "TestON-Partitions"
3016 iCounterName = "TestON-inMemory"
3017 pCounterValue = 0
3018 iCounterValue = 0
3019 onosSet = set([])
3020 onosSetName = "TestON-set"
3021
3022 description = "Install Primitives app"
3023 main.case( description )
3024 main.step( "Install Primitives app" )
3025 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003026 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003027 utilities.assert_equals( expect=main.TRUE,
3028 actual=appResults,
3029 onpass="Primitives app activated",
3030 onfail="Primitives app not activated" )
3031 time.sleep( 5 ) # To allow all nodes to activate
3032
3033 def CASE17( self, main ):
3034 """
3035 Check for basic functionality with distributed primitives
3036 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003037 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003038 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003039 assert main, "main not defined"
3040 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003041 assert main.CLIs, "main.CLIs not defined"
3042 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003043 assert pCounterName, "pCounterName not defined"
3044 assert iCounterName, "iCounterName not defined"
3045 assert onosSetName, "onosSetName not defined"
3046 # NOTE: assert fails if value is 0/None/Empty/False
3047 try:
3048 pCounterValue
3049 except NameError:
3050 main.log.error( "pCounterValue not defined, setting to 0" )
3051 pCounterValue = 0
3052 try:
3053 iCounterValue
3054 except NameError:
3055 main.log.error( "iCounterValue not defined, setting to 0" )
3056 iCounterValue = 0
3057 try:
3058 onosSet
3059 except NameError:
3060 main.log.error( "onosSet not defined, setting to empty Set" )
3061 onosSet = set([])
3062 # Variables for the distributed primitives tests. These are local only
3063 addValue = "a"
3064 addAllValue = "a b c d e f"
3065 retainValue = "c d e f"
3066
3067 description = "Check for basic functionality with distributed " +\
3068 "primitives"
3069 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003070 main.caseExplanation = "Test the methods of the distributed " +\
3071 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003072 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003073 # Partitioned counters
3074 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003075 pCounters = []
3076 threads = []
3077 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003078 for i in range( main.numCtrls ):
3079 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3080 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003081 args=[ pCounterName ] )
3082 pCounterValue += 1
3083 addedPValues.append( pCounterValue )
3084 threads.append( t )
3085 t.start()
3086
3087 for t in threads:
3088 t.join()
3089 pCounters.append( t.result )
3090 # Check that counter incremented numController times
3091 pCounterResults = True
3092 for i in addedPValues:
3093 tmpResult = i in pCounters
3094 pCounterResults = pCounterResults and tmpResult
3095 if not tmpResult:
3096 main.log.error( str( i ) + " is not in partitioned "
3097 "counter incremented results" )
3098 utilities.assert_equals( expect=True,
3099 actual=pCounterResults,
3100 onpass="Default counter incremented",
3101 onfail="Error incrementing default" +
3102 " counter" )
3103
Jon Halle1a3b752015-07-22 13:02:46 -07003104 main.step( "Get then Increment a default counter on each node" )
3105 pCounters = []
3106 threads = []
3107 addedPValues = []
3108 for i in range( main.numCtrls ):
3109 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3110 name="counterGetAndAdd-" + str( i ),
3111 args=[ pCounterName ] )
3112 addedPValues.append( pCounterValue )
3113 pCounterValue += 1
3114 threads.append( t )
3115 t.start()
3116
3117 for t in threads:
3118 t.join()
3119 pCounters.append( t.result )
3120 # Check that counter incremented numController times
3121 pCounterResults = True
3122 for i in addedPValues:
3123 tmpResult = i in pCounters
3124 pCounterResults = pCounterResults and tmpResult
3125 if not tmpResult:
3126 main.log.error( str( i ) + " is not in partitioned "
3127 "counter incremented results" )
3128 utilities.assert_equals( expect=True,
3129 actual=pCounterResults,
3130 onpass="Default counter incremented",
3131 onfail="Error incrementing default" +
3132 " counter" )
3133
3134 main.step( "Counters we added have the correct values" )
3135 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3136 utilities.assert_equals( expect=main.TRUE,
3137 actual=incrementCheck,
3138 onpass="Added counters are correct",
3139 onfail="Added counters are incorrect" )
3140
3141 main.step( "Add -8 to then get a default counter on each node" )
3142 pCounters = []
3143 threads = []
3144 addedPValues = []
3145 for i in range( main.numCtrls ):
3146 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3147 name="counterIncrement-" + str( i ),
3148 args=[ pCounterName ],
3149 kwargs={ "delta": -8 } )
3150 pCounterValue += -8
3151 addedPValues.append( pCounterValue )
3152 threads.append( t )
3153 t.start()
3154
3155 for t in threads:
3156 t.join()
3157 pCounters.append( t.result )
3158 # Check that counter incremented numController times
3159 pCounterResults = True
3160 for i in addedPValues:
3161 tmpResult = i in pCounters
3162 pCounterResults = pCounterResults and tmpResult
3163 if not tmpResult:
3164 main.log.error( str( i ) + " is not in partitioned "
3165 "counter incremented results" )
3166 utilities.assert_equals( expect=True,
3167 actual=pCounterResults,
3168 onpass="Default counter incremented",
3169 onfail="Error incrementing default" +
3170 " counter" )
3171
3172 main.step( "Add 5 to then get a default counter on each node" )
3173 pCounters = []
3174 threads = []
3175 addedPValues = []
3176 for i in range( main.numCtrls ):
3177 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3178 name="counterIncrement-" + str( i ),
3179 args=[ pCounterName ],
3180 kwargs={ "delta": 5 } )
3181 pCounterValue += 5
3182 addedPValues.append( pCounterValue )
3183 threads.append( t )
3184 t.start()
3185
3186 for t in threads:
3187 t.join()
3188 pCounters.append( t.result )
3189 # Check that counter incremented numController times
3190 pCounterResults = True
3191 for i in addedPValues:
3192 tmpResult = i in pCounters
3193 pCounterResults = pCounterResults and tmpResult
3194 if not tmpResult:
3195 main.log.error( str( i ) + " is not in partitioned "
3196 "counter incremented results" )
3197 utilities.assert_equals( expect=True,
3198 actual=pCounterResults,
3199 onpass="Default counter incremented",
3200 onfail="Error incrementing default" +
3201 " counter" )
3202
3203 main.step( "Get then add 5 to a default counter on each node" )
3204 pCounters = []
3205 threads = []
3206 addedPValues = []
3207 for i in range( main.numCtrls ):
3208 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3209 name="counterIncrement-" + str( i ),
3210 args=[ pCounterName ],
3211 kwargs={ "delta": 5 } )
3212 addedPValues.append( pCounterValue )
3213 pCounterValue += 5
3214 threads.append( t )
3215 t.start()
3216
3217 for t in threads:
3218 t.join()
3219 pCounters.append( t.result )
3220 # Check that counter incremented numController times
3221 pCounterResults = True
3222 for i in addedPValues:
3223 tmpResult = i in pCounters
3224 pCounterResults = pCounterResults and tmpResult
3225 if not tmpResult:
3226 main.log.error( str( i ) + " is not in partitioned "
3227 "counter incremented results" )
3228 utilities.assert_equals( expect=True,
3229 actual=pCounterResults,
3230 onpass="Default counter incremented",
3231 onfail="Error incrementing default" +
3232 " counter" )
3233
3234 main.step( "Counters we added have the correct values" )
3235 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3236 utilities.assert_equals( expect=main.TRUE,
3237 actual=incrementCheck,
3238 onpass="Added counters are correct",
3239 onfail="Added counters are incorrect" )
3240
3241 # In-Memory counters
3242 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003243 iCounters = []
3244 addedIValues = []
3245 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003246 for i in range( main.numCtrls ):
3247 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003248 name="icounterIncrement-" + str( i ),
3249 args=[ iCounterName ],
3250 kwargs={ "inMemory": True } )
3251 iCounterValue += 1
3252 addedIValues.append( iCounterValue )
3253 threads.append( t )
3254 t.start()
3255
3256 for t in threads:
3257 t.join()
3258 iCounters.append( t.result )
3259 # Check that counter incremented numController times
3260 iCounterResults = True
3261 for i in addedIValues:
3262 tmpResult = i in iCounters
3263 iCounterResults = iCounterResults and tmpResult
3264 if not tmpResult:
3265 main.log.error( str( i ) + " is not in the in-memory "
3266 "counter incremented results" )
3267 utilities.assert_equals( expect=True,
3268 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003269 onpass="In-memory counter incremented",
3270 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003271 " counter" )
3272
Jon Halle1a3b752015-07-22 13:02:46 -07003273 main.step( "Get then Increment a in-memory counter on each node" )
3274 iCounters = []
3275 threads = []
3276 addedIValues = []
3277 for i in range( main.numCtrls ):
3278 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3279 name="counterGetAndAdd-" + str( i ),
3280 args=[ iCounterName ],
3281 kwargs={ "inMemory": True } )
3282 addedIValues.append( iCounterValue )
3283 iCounterValue += 1
3284 threads.append( t )
3285 t.start()
3286
3287 for t in threads:
3288 t.join()
3289 iCounters.append( t.result )
3290 # Check that counter incremented numController times
3291 iCounterResults = True
3292 for i in addedIValues:
3293 tmpResult = i in iCounters
3294 iCounterResults = iCounterResults and tmpResult
3295 if not tmpResult:
3296 main.log.error( str( i ) + " is not in in-memory "
3297 "counter incremented results" )
3298 utilities.assert_equals( expect=True,
3299 actual=iCounterResults,
3300 onpass="In-memory counter incremented",
3301 onfail="Error incrementing in-memory" +
3302 " counter" )
3303
3304 main.step( "Counters we added have the correct values" )
3305 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3306 utilities.assert_equals( expect=main.TRUE,
3307 actual=incrementCheck,
3308 onpass="Added counters are correct",
3309 onfail="Added counters are incorrect" )
3310
3311 main.step( "Add -8 to then get a in-memory counter on each node" )
3312 iCounters = []
3313 threads = []
3314 addedIValues = []
3315 for i in range( main.numCtrls ):
3316 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3317 name="counterIncrement-" + str( i ),
3318 args=[ iCounterName ],
3319 kwargs={ "delta": -8, "inMemory": True } )
3320 iCounterValue += -8
3321 addedIValues.append( iCounterValue )
3322 threads.append( t )
3323 t.start()
3324
3325 for t in threads:
3326 t.join()
3327 iCounters.append( t.result )
3328 # Check that counter incremented numController times
3329 iCounterResults = True
3330 for i in addedIValues:
3331 tmpResult = i in iCounters
3332 iCounterResults = iCounterResults and tmpResult
3333 if not tmpResult:
3334 main.log.error( str( i ) + " is not in in-memory "
3335 "counter incremented results" )
3336 utilities.assert_equals( expect=True,
3337 actual=pCounterResults,
3338 onpass="In-memory counter incremented",
3339 onfail="Error incrementing in-memory" +
3340 " counter" )
3341
3342 main.step( "Add 5 to then get a in-memory counter on each node" )
3343 iCounters = []
3344 threads = []
3345 addedIValues = []
3346 for i in range( main.numCtrls ):
3347 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3348 name="counterIncrement-" + str( i ),
3349 args=[ iCounterName ],
3350 kwargs={ "delta": 5, "inMemory": True } )
3351 iCounterValue += 5
3352 addedIValues.append( iCounterValue )
3353 threads.append( t )
3354 t.start()
3355
3356 for t in threads:
3357 t.join()
3358 iCounters.append( t.result )
3359 # Check that counter incremented numController times
3360 iCounterResults = True
3361 for i in addedIValues:
3362 tmpResult = i in iCounters
3363 iCounterResults = iCounterResults and tmpResult
3364 if not tmpResult:
3365 main.log.error( str( i ) + " is not in in-memory "
3366 "counter incremented results" )
3367 utilities.assert_equals( expect=True,
3368 actual=pCounterResults,
3369 onpass="In-memory counter incremented",
3370 onfail="Error incrementing in-memory" +
3371 " counter" )
3372
3373 main.step( "Get then add 5 to a in-memory counter on each node" )
3374 iCounters = []
3375 threads = []
3376 addedIValues = []
3377 for i in range( main.numCtrls ):
3378 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3379 name="counterIncrement-" + str( i ),
3380 args=[ iCounterName ],
3381 kwargs={ "delta": 5, "inMemory": True } )
3382 addedIValues.append( iCounterValue )
3383 iCounterValue += 5
3384 threads.append( t )
3385 t.start()
3386
3387 for t in threads:
3388 t.join()
3389 iCounters.append( t.result )
3390 # Check that counter incremented numController times
3391 iCounterResults = True
3392 for i in addedIValues:
3393 tmpResult = i in iCounters
3394 iCounterResults = iCounterResults and tmpResult
3395 if not tmpResult:
3396 main.log.error( str( i ) + " is not in in-memory "
3397 "counter incremented results" )
3398 utilities.assert_equals( expect=True,
3399 actual=iCounterResults,
3400 onpass="In-memory counter incremented",
3401 onfail="Error incrementing in-memory" +
3402 " counter" )
3403
3404 main.step( "Counters we added have the correct values" )
3405 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3406 utilities.assert_equals( expect=main.TRUE,
3407 actual=incrementCheck,
3408 onpass="Added counters are correct",
3409 onfail="Added counters are incorrect" )
3410
Jon Hall5cf14d52015-07-16 12:15:19 -07003411 main.step( "Check counters are consistant across nodes" )
3412 onosCounters = []
3413 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003414 for i in range( main.numCtrls ):
3415 t = main.Thread( target=main.CLIs[i].counters,
Jon Hall5cf14d52015-07-16 12:15:19 -07003416 name="counters-" + str( i ) )
3417 threads.append( t )
3418 t.start()
3419 for t in threads:
3420 t.join()
3421 onosCounters.append( t.result )
3422 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3423 if all( tmp ):
3424 main.log.info( "Counters are consistent across all nodes" )
3425 consistentCounterResults = main.TRUE
3426 else:
3427 main.log.error( "Counters are not consistent across all nodes" )
3428 consistentCounterResults = main.FALSE
3429 utilities.assert_equals( expect=main.TRUE,
3430 actual=consistentCounterResults,
3431 onpass="ONOS counters are consistent " +
3432 "across nodes",
3433 onfail="ONOS Counters are inconsistent " +
3434 "across nodes" )
3435
3436 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003437 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3438 incrementCheck = incrementCheck and \
3439 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003440 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003441 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003442 onpass="Added counters are correct",
3443 onfail="Added counters are incorrect" )
Jon Halle1a3b752015-07-22 13:02:46 -07003444
Jon Hall5cf14d52015-07-16 12:15:19 -07003445 # DISTRIBUTED SETS
3446 main.step( "Distributed Set get" )
3447 size = len( onosSet )
3448 getResponses = []
3449 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003450 for i in range( main.numCtrls ):
3451 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003452 name="setTestGet-" + str( i ),
3453 args=[ onosSetName ] )
3454 threads.append( t )
3455 t.start()
3456 for t in threads:
3457 t.join()
3458 getResponses.append( t.result )
3459
3460 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003461 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003462 if isinstance( getResponses[ i ], list):
3463 current = set( getResponses[ i ] )
3464 if len( current ) == len( getResponses[ i ] ):
3465 # no repeats
3466 if onosSet != current:
3467 main.log.error( "ONOS" + str( i + 1 ) +
3468 " has incorrect view" +
3469 " of set " + onosSetName + ":\n" +
3470 str( getResponses[ i ] ) )
3471 main.log.debug( "Expected: " + str( onosSet ) )
3472 main.log.debug( "Actual: " + str( current ) )
3473 getResults = main.FALSE
3474 else:
3475 # error, set is not a set
3476 main.log.error( "ONOS" + str( i + 1 ) +
3477 " has repeat elements in" +
3478 " set " + onosSetName + ":\n" +
3479 str( getResponses[ i ] ) )
3480 getResults = main.FALSE
3481 elif getResponses[ i ] == main.ERROR:
3482 getResults = main.FALSE
3483 utilities.assert_equals( expect=main.TRUE,
3484 actual=getResults,
3485 onpass="Set elements are correct",
3486 onfail="Set elements are incorrect" )
3487
3488 main.step( "Distributed Set size" )
3489 sizeResponses = []
3490 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003491 for i in range( main.numCtrls ):
3492 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003493 name="setTestSize-" + str( i ),
3494 args=[ onosSetName ] )
3495 threads.append( t )
3496 t.start()
3497 for t in threads:
3498 t.join()
3499 sizeResponses.append( t.result )
3500
3501 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003502 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003503 if size != sizeResponses[ i ]:
3504 sizeResults = main.FALSE
3505 main.log.error( "ONOS" + str( i + 1 ) +
3506 " expected a size of " + str( size ) +
3507 " for set " + onosSetName +
3508 " but got " + str( sizeResponses[ i ] ) )
3509 utilities.assert_equals( expect=main.TRUE,
3510 actual=sizeResults,
3511 onpass="Set sizes are correct",
3512 onfail="Set sizes are incorrect" )
3513
3514 main.step( "Distributed Set add()" )
3515 onosSet.add( addValue )
3516 addResponses = []
3517 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003518 for i in range( main.numCtrls ):
3519 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003520 name="setTestAdd-" + str( i ),
3521 args=[ onosSetName, addValue ] )
3522 threads.append( t )
3523 t.start()
3524 for t in threads:
3525 t.join()
3526 addResponses.append( t.result )
3527
3528 # main.TRUE = successfully changed the set
3529 # main.FALSE = action resulted in no change in set
3530 # main.ERROR - Some error in executing the function
3531 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003532 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003533 if addResponses[ i ] == main.TRUE:
3534 # All is well
3535 pass
3536 elif addResponses[ i ] == main.FALSE:
3537 # Already in set, probably fine
3538 pass
3539 elif addResponses[ i ] == main.ERROR:
3540 # Error in execution
3541 addResults = main.FALSE
3542 else:
3543 # unexpected result
3544 addResults = main.FALSE
3545 if addResults != main.TRUE:
3546 main.log.error( "Error executing set add" )
3547
3548 # Check if set is still correct
3549 size = len( onosSet )
3550 getResponses = []
3551 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003552 for i in range( main.numCtrls ):
3553 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003554 name="setTestGet-" + str( i ),
3555 args=[ onosSetName ] )
3556 threads.append( t )
3557 t.start()
3558 for t in threads:
3559 t.join()
3560 getResponses.append( t.result )
3561 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003562 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003563 if isinstance( getResponses[ i ], list):
3564 current = set( getResponses[ i ] )
3565 if len( current ) == len( getResponses[ i ] ):
3566 # no repeats
3567 if onosSet != current:
3568 main.log.error( "ONOS" + str( i + 1 ) +
3569 " has incorrect view" +
3570 " of set " + onosSetName + ":\n" +
3571 str( getResponses[ i ] ) )
3572 main.log.debug( "Expected: " + str( onosSet ) )
3573 main.log.debug( "Actual: " + str( current ) )
3574 getResults = main.FALSE
3575 else:
3576 # error, set is not a set
3577 main.log.error( "ONOS" + str( i + 1 ) +
3578 " has repeat elements in" +
3579 " set " + onosSetName + ":\n" +
3580 str( getResponses[ i ] ) )
3581 getResults = main.FALSE
3582 elif getResponses[ i ] == main.ERROR:
3583 getResults = main.FALSE
3584 sizeResponses = []
3585 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003586 for i in range( main.numCtrls ):
3587 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003588 name="setTestSize-" + str( i ),
3589 args=[ onosSetName ] )
3590 threads.append( t )
3591 t.start()
3592 for t in threads:
3593 t.join()
3594 sizeResponses.append( t.result )
3595 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003596 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003597 if size != sizeResponses[ i ]:
3598 sizeResults = main.FALSE
3599 main.log.error( "ONOS" + str( i + 1 ) +
3600 " expected a size of " + str( size ) +
3601 " for set " + onosSetName +
3602 " but got " + str( sizeResponses[ i ] ) )
3603 addResults = addResults and getResults and sizeResults
3604 utilities.assert_equals( expect=main.TRUE,
3605 actual=addResults,
3606 onpass="Set add correct",
3607 onfail="Set add was incorrect" )
3608
3609 main.step( "Distributed Set addAll()" )
3610 onosSet.update( addAllValue.split() )
3611 addResponses = []
3612 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003613 for i in range( main.numCtrls ):
3614 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003615 name="setTestAddAll-" + str( i ),
3616 args=[ onosSetName, addAllValue ] )
3617 threads.append( t )
3618 t.start()
3619 for t in threads:
3620 t.join()
3621 addResponses.append( t.result )
3622
3623 # main.TRUE = successfully changed the set
3624 # main.FALSE = action resulted in no change in set
3625 # main.ERROR - Some error in executing the function
3626 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003627 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003628 if addResponses[ i ] == main.TRUE:
3629 # All is well
3630 pass
3631 elif addResponses[ i ] == main.FALSE:
3632 # Already in set, probably fine
3633 pass
3634 elif addResponses[ i ] == main.ERROR:
3635 # Error in execution
3636 addAllResults = main.FALSE
3637 else:
3638 # unexpected result
3639 addAllResults = main.FALSE
3640 if addAllResults != main.TRUE:
3641 main.log.error( "Error executing set addAll" )
3642
3643 # Check if set is still correct
3644 size = len( onosSet )
3645 getResponses = []
3646 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003647 for i in range( main.numCtrls ):
3648 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003649 name="setTestGet-" + str( i ),
3650 args=[ onosSetName ] )
3651 threads.append( t )
3652 t.start()
3653 for t in threads:
3654 t.join()
3655 getResponses.append( t.result )
3656 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003657 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003658 if isinstance( getResponses[ i ], list):
3659 current = set( getResponses[ i ] )
3660 if len( current ) == len( getResponses[ i ] ):
3661 # no repeats
3662 if onosSet != current:
3663 main.log.error( "ONOS" + str( i + 1 ) +
3664 " has incorrect view" +
3665 " of set " + onosSetName + ":\n" +
3666 str( getResponses[ i ] ) )
3667 main.log.debug( "Expected: " + str( onosSet ) )
3668 main.log.debug( "Actual: " + str( current ) )
3669 getResults = main.FALSE
3670 else:
3671 # error, set is not a set
3672 main.log.error( "ONOS" + str( i + 1 ) +
3673 " has repeat elements in" +
3674 " set " + onosSetName + ":\n" +
3675 str( getResponses[ i ] ) )
3676 getResults = main.FALSE
3677 elif getResponses[ i ] == main.ERROR:
3678 getResults = main.FALSE
3679 sizeResponses = []
3680 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003681 for i in range( main.numCtrls ):
3682 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003683 name="setTestSize-" + str( i ),
3684 args=[ onosSetName ] )
3685 threads.append( t )
3686 t.start()
3687 for t in threads:
3688 t.join()
3689 sizeResponses.append( t.result )
3690 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003691 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003692 if size != sizeResponses[ i ]:
3693 sizeResults = main.FALSE
3694 main.log.error( "ONOS" + str( i + 1 ) +
3695 " expected a size of " + str( size ) +
3696 " for set " + onosSetName +
3697 " but got " + str( sizeResponses[ i ] ) )
3698 addAllResults = addAllResults and getResults and sizeResults
3699 utilities.assert_equals( expect=main.TRUE,
3700 actual=addAllResults,
3701 onpass="Set addAll correct",
3702 onfail="Set addAll was incorrect" )
3703
3704 main.step( "Distributed Set contains()" )
3705 containsResponses = []
3706 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003707 for i in range( main.numCtrls ):
3708 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003709 name="setContains-" + str( i ),
3710 args=[ onosSetName ],
3711 kwargs={ "values": addValue } )
3712 threads.append( t )
3713 t.start()
3714 for t in threads:
3715 t.join()
3716 # NOTE: This is the tuple
3717 containsResponses.append( t.result )
3718
3719 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003720 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003721 if containsResponses[ i ] == main.ERROR:
3722 containsResults = main.FALSE
3723 else:
3724 containsResults = containsResults and\
3725 containsResponses[ i ][ 1 ]
3726 utilities.assert_equals( expect=main.TRUE,
3727 actual=containsResults,
3728 onpass="Set contains is functional",
3729 onfail="Set contains failed" )
3730
3731 main.step( "Distributed Set containsAll()" )
3732 containsAllResponses = []
3733 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003734 for i in range( main.numCtrls ):
3735 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003736 name="setContainsAll-" + str( i ),
3737 args=[ onosSetName ],
3738 kwargs={ "values": addAllValue } )
3739 threads.append( t )
3740 t.start()
3741 for t in threads:
3742 t.join()
3743 # NOTE: This is the tuple
3744 containsAllResponses.append( t.result )
3745
3746 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003747 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003748 if containsResponses[ i ] == main.ERROR:
3749 containsResults = main.FALSE
3750 else:
3751 containsResults = containsResults and\
3752 containsResponses[ i ][ 1 ]
3753 utilities.assert_equals( expect=main.TRUE,
3754 actual=containsAllResults,
3755 onpass="Set containsAll is functional",
3756 onfail="Set containsAll failed" )
3757
3758 main.step( "Distributed Set remove()" )
3759 onosSet.remove( addValue )
3760 removeResponses = []
3761 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003762 for i in range( main.numCtrls ):
3763 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003764 name="setTestRemove-" + str( i ),
3765 args=[ onosSetName, addValue ] )
3766 threads.append( t )
3767 t.start()
3768 for t in threads:
3769 t.join()
3770 removeResponses.append( t.result )
3771
3772 # main.TRUE = successfully changed the set
3773 # main.FALSE = action resulted in no change in set
3774 # main.ERROR - Some error in executing the function
3775 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003776 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003777 if removeResponses[ i ] == main.TRUE:
3778 # All is well
3779 pass
3780 elif removeResponses[ i ] == main.FALSE:
3781 # not in set, probably fine
3782 pass
3783 elif removeResponses[ i ] == main.ERROR:
3784 # Error in execution
3785 removeResults = main.FALSE
3786 else:
3787 # unexpected result
3788 removeResults = main.FALSE
3789 if removeResults != main.TRUE:
3790 main.log.error( "Error executing set remove" )
3791
3792 # Check if set is still correct
3793 size = len( onosSet )
3794 getResponses = []
3795 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003796 for i in range( main.numCtrls ):
3797 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003798 name="setTestGet-" + str( i ),
3799 args=[ onosSetName ] )
3800 threads.append( t )
3801 t.start()
3802 for t in threads:
3803 t.join()
3804 getResponses.append( t.result )
3805 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003806 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003807 if isinstance( getResponses[ i ], list):
3808 current = set( getResponses[ i ] )
3809 if len( current ) == len( getResponses[ i ] ):
3810 # no repeats
3811 if onosSet != current:
3812 main.log.error( "ONOS" + str( i + 1 ) +
3813 " has incorrect view" +
3814 " of set " + onosSetName + ":\n" +
3815 str( getResponses[ i ] ) )
3816 main.log.debug( "Expected: " + str( onosSet ) )
3817 main.log.debug( "Actual: " + str( current ) )
3818 getResults = main.FALSE
3819 else:
3820 # error, set is not a set
3821 main.log.error( "ONOS" + str( i + 1 ) +
3822 " has repeat elements in" +
3823 " set " + onosSetName + ":\n" +
3824 str( getResponses[ i ] ) )
3825 getResults = main.FALSE
3826 elif getResponses[ i ] == main.ERROR:
3827 getResults = main.FALSE
3828 sizeResponses = []
3829 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003830 for i in range( main.numCtrls ):
3831 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003832 name="setTestSize-" + str( i ),
3833 args=[ onosSetName ] )
3834 threads.append( t )
3835 t.start()
3836 for t in threads:
3837 t.join()
3838 sizeResponses.append( t.result )
3839 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003840 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003841 if size != sizeResponses[ i ]:
3842 sizeResults = main.FALSE
3843 main.log.error( "ONOS" + str( i + 1 ) +
3844 " expected a size of " + str( size ) +
3845 " for set " + onosSetName +
3846 " but got " + str( sizeResponses[ i ] ) )
3847 removeResults = removeResults and getResults and sizeResults
3848 utilities.assert_equals( expect=main.TRUE,
3849 actual=removeResults,
3850 onpass="Set remove correct",
3851 onfail="Set remove was incorrect" )
3852
3853 main.step( "Distributed Set removeAll()" )
3854 onosSet.difference_update( addAllValue.split() )
3855 removeAllResponses = []
3856 threads = []
3857 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003858 for i in range( main.numCtrls ):
3859 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003860 name="setTestRemoveAll-" + str( i ),
3861 args=[ onosSetName, addAllValue ] )
3862 threads.append( t )
3863 t.start()
3864 for t in threads:
3865 t.join()
3866 removeAllResponses.append( t.result )
3867 except Exception, e:
3868 main.log.exception(e)
3869
3870 # main.TRUE = successfully changed the set
3871 # main.FALSE = action resulted in no change in set
3872 # main.ERROR - Some error in executing the function
3873 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003874 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003875 if removeAllResponses[ i ] == main.TRUE:
3876 # All is well
3877 pass
3878 elif removeAllResponses[ i ] == main.FALSE:
3879 # not in set, probably fine
3880 pass
3881 elif removeAllResponses[ i ] == main.ERROR:
3882 # Error in execution
3883 removeAllResults = main.FALSE
3884 else:
3885 # unexpected result
3886 removeAllResults = main.FALSE
3887 if removeAllResults != main.TRUE:
3888 main.log.error( "Error executing set removeAll" )
3889
3890 # Check if set is still correct
3891 size = len( onosSet )
3892 getResponses = []
3893 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003894 for i in range( main.numCtrls ):
3895 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003896 name="setTestGet-" + str( i ),
3897 args=[ onosSetName ] )
3898 threads.append( t )
3899 t.start()
3900 for t in threads:
3901 t.join()
3902 getResponses.append( t.result )
3903 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003904 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003905 if isinstance( getResponses[ i ], list):
3906 current = set( getResponses[ i ] )
3907 if len( current ) == len( getResponses[ i ] ):
3908 # no repeats
3909 if onosSet != current:
3910 main.log.error( "ONOS" + str( i + 1 ) +
3911 " has incorrect view" +
3912 " of set " + onosSetName + ":\n" +
3913 str( getResponses[ i ] ) )
3914 main.log.debug( "Expected: " + str( onosSet ) )
3915 main.log.debug( "Actual: " + str( current ) )
3916 getResults = main.FALSE
3917 else:
3918 # error, set is not a set
3919 main.log.error( "ONOS" + str( i + 1 ) +
3920 " has repeat elements in" +
3921 " set " + onosSetName + ":\n" +
3922 str( getResponses[ i ] ) )
3923 getResults = main.FALSE
3924 elif getResponses[ i ] == main.ERROR:
3925 getResults = main.FALSE
3926 sizeResponses = []
3927 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003928 for i in range( main.numCtrls ):
3929 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003930 name="setTestSize-" + str( i ),
3931 args=[ onosSetName ] )
3932 threads.append( t )
3933 t.start()
3934 for t in threads:
3935 t.join()
3936 sizeResponses.append( t.result )
3937 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003938 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003939 if size != sizeResponses[ i ]:
3940 sizeResults = main.FALSE
3941 main.log.error( "ONOS" + str( i + 1 ) +
3942 " expected a size of " + str( size ) +
3943 " for set " + onosSetName +
3944 " but got " + str( sizeResponses[ i ] ) )
3945 removeAllResults = removeAllResults and getResults and sizeResults
3946 utilities.assert_equals( expect=main.TRUE,
3947 actual=removeAllResults,
3948 onpass="Set removeAll correct",
3949 onfail="Set removeAll was incorrect" )
3950
3951 main.step( "Distributed Set addAll()" )
3952 onosSet.update( addAllValue.split() )
3953 addResponses = []
3954 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003955 for i in range( main.numCtrls ):
3956 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003957 name="setTestAddAll-" + str( i ),
3958 args=[ onosSetName, addAllValue ] )
3959 threads.append( t )
3960 t.start()
3961 for t in threads:
3962 t.join()
3963 addResponses.append( t.result )
3964
3965 # main.TRUE = successfully changed the set
3966 # main.FALSE = action resulted in no change in set
3967 # main.ERROR - Some error in executing the function
3968 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003969 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003970 if addResponses[ i ] == main.TRUE:
3971 # All is well
3972 pass
3973 elif addResponses[ i ] == main.FALSE:
3974 # Already in set, probably fine
3975 pass
3976 elif addResponses[ i ] == main.ERROR:
3977 # Error in execution
3978 addAllResults = main.FALSE
3979 else:
3980 # unexpected result
3981 addAllResults = main.FALSE
3982 if addAllResults != main.TRUE:
3983 main.log.error( "Error executing set addAll" )
3984
3985 # Check if set is still correct
3986 size = len( onosSet )
3987 getResponses = []
3988 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003989 for i in range( main.numCtrls ):
3990 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003991 name="setTestGet-" + str( i ),
3992 args=[ onosSetName ] )
3993 threads.append( t )
3994 t.start()
3995 for t in threads:
3996 t.join()
3997 getResponses.append( t.result )
3998 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003999 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004000 if isinstance( getResponses[ i ], list):
4001 current = set( getResponses[ i ] )
4002 if len( current ) == len( getResponses[ i ] ):
4003 # no repeats
4004 if onosSet != current:
4005 main.log.error( "ONOS" + str( i + 1 ) +
4006 " has incorrect view" +
4007 " of set " + onosSetName + ":\n" +
4008 str( getResponses[ i ] ) )
4009 main.log.debug( "Expected: " + str( onosSet ) )
4010 main.log.debug( "Actual: " + str( current ) )
4011 getResults = main.FALSE
4012 else:
4013 # error, set is not a set
4014 main.log.error( "ONOS" + str( i + 1 ) +
4015 " has repeat elements in" +
4016 " set " + onosSetName + ":\n" +
4017 str( getResponses[ i ] ) )
4018 getResults = main.FALSE
4019 elif getResponses[ i ] == main.ERROR:
4020 getResults = main.FALSE
4021 sizeResponses = []
4022 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004023 for i in range( main.numCtrls ):
4024 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004025 name="setTestSize-" + str( i ),
4026 args=[ onosSetName ] )
4027 threads.append( t )
4028 t.start()
4029 for t in threads:
4030 t.join()
4031 sizeResponses.append( t.result )
4032 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004033 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004034 if size != sizeResponses[ i ]:
4035 sizeResults = main.FALSE
4036 main.log.error( "ONOS" + str( i + 1 ) +
4037 " expected a size of " + str( size ) +
4038 " for set " + onosSetName +
4039 " but got " + str( sizeResponses[ i ] ) )
4040 addAllResults = addAllResults and getResults and sizeResults
4041 utilities.assert_equals( expect=main.TRUE,
4042 actual=addAllResults,
4043 onpass="Set addAll correct",
4044 onfail="Set addAll was incorrect" )
4045
4046 main.step( "Distributed Set clear()" )
4047 onosSet.clear()
4048 clearResponses = []
4049 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004050 for i in range( main.numCtrls ):
4051 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004052 name="setTestClear-" + str( i ),
4053 args=[ onosSetName, " "], # Values doesn't matter
4054 kwargs={ "clear": True } )
4055 threads.append( t )
4056 t.start()
4057 for t in threads:
4058 t.join()
4059 clearResponses.append( t.result )
4060
4061 # main.TRUE = successfully changed the set
4062 # main.FALSE = action resulted in no change in set
4063 # main.ERROR - Some error in executing the function
4064 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004065 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004066 if clearResponses[ i ] == main.TRUE:
4067 # All is well
4068 pass
4069 elif clearResponses[ i ] == main.FALSE:
4070 # Nothing set, probably fine
4071 pass
4072 elif clearResponses[ i ] == main.ERROR:
4073 # Error in execution
4074 clearResults = main.FALSE
4075 else:
4076 # unexpected result
4077 clearResults = main.FALSE
4078 if clearResults != main.TRUE:
4079 main.log.error( "Error executing set clear" )
4080
4081 # Check if set is still correct
4082 size = len( onosSet )
4083 getResponses = []
4084 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004085 for i in range( main.numCtrls ):
4086 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004087 name="setTestGet-" + str( i ),
4088 args=[ onosSetName ] )
4089 threads.append( t )
4090 t.start()
4091 for t in threads:
4092 t.join()
4093 getResponses.append( t.result )
4094 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004095 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004096 if isinstance( getResponses[ i ], list):
4097 current = set( getResponses[ i ] )
4098 if len( current ) == len( getResponses[ i ] ):
4099 # no repeats
4100 if onosSet != current:
4101 main.log.error( "ONOS" + str( i + 1 ) +
4102 " has incorrect view" +
4103 " of set " + onosSetName + ":\n" +
4104 str( getResponses[ i ] ) )
4105 main.log.debug( "Expected: " + str( onosSet ) )
4106 main.log.debug( "Actual: " + str( current ) )
4107 getResults = main.FALSE
4108 else:
4109 # error, set is not a set
4110 main.log.error( "ONOS" + str( i + 1 ) +
4111 " has repeat elements in" +
4112 " set " + onosSetName + ":\n" +
4113 str( getResponses[ i ] ) )
4114 getResults = main.FALSE
4115 elif getResponses[ i ] == main.ERROR:
4116 getResults = main.FALSE
4117 sizeResponses = []
4118 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004119 for i in range( main.numCtrls ):
4120 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004121 name="setTestSize-" + str( i ),
4122 args=[ onosSetName ] )
4123 threads.append( t )
4124 t.start()
4125 for t in threads:
4126 t.join()
4127 sizeResponses.append( t.result )
4128 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004129 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004130 if size != sizeResponses[ i ]:
4131 sizeResults = main.FALSE
4132 main.log.error( "ONOS" + str( i + 1 ) +
4133 " expected a size of " + str( size ) +
4134 " for set " + onosSetName +
4135 " but got " + str( sizeResponses[ i ] ) )
4136 clearResults = clearResults and getResults and sizeResults
4137 utilities.assert_equals( expect=main.TRUE,
4138 actual=clearResults,
4139 onpass="Set clear correct",
4140 onfail="Set clear was incorrect" )
4141
4142 main.step( "Distributed Set addAll()" )
4143 onosSet.update( addAllValue.split() )
4144 addResponses = []
4145 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004146 for i in range( main.numCtrls ):
4147 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004148 name="setTestAddAll-" + str( i ),
4149 args=[ onosSetName, addAllValue ] )
4150 threads.append( t )
4151 t.start()
4152 for t in threads:
4153 t.join()
4154 addResponses.append( t.result )
4155
4156 # main.TRUE = successfully changed the set
4157 # main.FALSE = action resulted in no change in set
4158 # main.ERROR - Some error in executing the function
4159 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004160 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004161 if addResponses[ i ] == main.TRUE:
4162 # All is well
4163 pass
4164 elif addResponses[ i ] == main.FALSE:
4165 # Already in set, probably fine
4166 pass
4167 elif addResponses[ i ] == main.ERROR:
4168 # Error in execution
4169 addAllResults = main.FALSE
4170 else:
4171 # unexpected result
4172 addAllResults = main.FALSE
4173 if addAllResults != main.TRUE:
4174 main.log.error( "Error executing set addAll" )
4175
4176 # Check if set is still correct
4177 size = len( onosSet )
4178 getResponses = []
4179 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004180 for i in range( main.numCtrls ):
4181 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004182 name="setTestGet-" + str( i ),
4183 args=[ onosSetName ] )
4184 threads.append( t )
4185 t.start()
4186 for t in threads:
4187 t.join()
4188 getResponses.append( t.result )
4189 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004190 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004191 if isinstance( getResponses[ i ], list):
4192 current = set( getResponses[ i ] )
4193 if len( current ) == len( getResponses[ i ] ):
4194 # no repeats
4195 if onosSet != current:
4196 main.log.error( "ONOS" + str( i + 1 ) +
4197 " has incorrect view" +
4198 " of set " + onosSetName + ":\n" +
4199 str( getResponses[ i ] ) )
4200 main.log.debug( "Expected: " + str( onosSet ) )
4201 main.log.debug( "Actual: " + str( current ) )
4202 getResults = main.FALSE
4203 else:
4204 # error, set is not a set
4205 main.log.error( "ONOS" + str( i + 1 ) +
4206 " has repeat elements in" +
4207 " set " + onosSetName + ":\n" +
4208 str( getResponses[ i ] ) )
4209 getResults = main.FALSE
4210 elif getResponses[ i ] == main.ERROR:
4211 getResults = main.FALSE
4212 sizeResponses = []
4213 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004214 for i in range( main.numCtrls ):
4215 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004216 name="setTestSize-" + str( i ),
4217 args=[ onosSetName ] )
4218 threads.append( t )
4219 t.start()
4220 for t in threads:
4221 t.join()
4222 sizeResponses.append( t.result )
4223 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004224 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004225 if size != sizeResponses[ i ]:
4226 sizeResults = main.FALSE
4227 main.log.error( "ONOS" + str( i + 1 ) +
4228 " expected a size of " + str( size ) +
4229 " for set " + onosSetName +
4230 " but got " + str( sizeResponses[ i ] ) )
4231 addAllResults = addAllResults and getResults and sizeResults
4232 utilities.assert_equals( expect=main.TRUE,
4233 actual=addAllResults,
4234 onpass="Set addAll correct",
4235 onfail="Set addAll was incorrect" )
4236
4237 main.step( "Distributed Set retain()" )
4238 onosSet.intersection_update( retainValue.split() )
4239 retainResponses = []
4240 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004241 for i in range( main.numCtrls ):
4242 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004243 name="setTestRetain-" + str( i ),
4244 args=[ onosSetName, retainValue ],
4245 kwargs={ "retain": True } )
4246 threads.append( t )
4247 t.start()
4248 for t in threads:
4249 t.join()
4250 retainResponses.append( t.result )
4251
4252 # main.TRUE = successfully changed the set
4253 # main.FALSE = action resulted in no change in set
4254 # main.ERROR - Some error in executing the function
4255 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004256 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004257 if retainResponses[ i ] == main.TRUE:
4258 # All is well
4259 pass
4260 elif retainResponses[ i ] == main.FALSE:
4261 # Already in set, probably fine
4262 pass
4263 elif retainResponses[ i ] == main.ERROR:
4264 # Error in execution
4265 retainResults = main.FALSE
4266 else:
4267 # unexpected result
4268 retainResults = main.FALSE
4269 if retainResults != main.TRUE:
4270 main.log.error( "Error executing set retain" )
4271
4272 # Check if set is still correct
4273 size = len( onosSet )
4274 getResponses = []
4275 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004276 for i in range( main.numCtrls ):
4277 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004278 name="setTestGet-" + str( i ),
4279 args=[ onosSetName ] )
4280 threads.append( t )
4281 t.start()
4282 for t in threads:
4283 t.join()
4284 getResponses.append( t.result )
4285 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004286 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004287 if isinstance( getResponses[ i ], list):
4288 current = set( getResponses[ i ] )
4289 if len( current ) == len( getResponses[ i ] ):
4290 # no repeats
4291 if onosSet != current:
4292 main.log.error( "ONOS" + str( i + 1 ) +
4293 " has incorrect view" +
4294 " of set " + onosSetName + ":\n" +
4295 str( getResponses[ i ] ) )
4296 main.log.debug( "Expected: " + str( onosSet ) )
4297 main.log.debug( "Actual: " + str( current ) )
4298 getResults = main.FALSE
4299 else:
4300 # error, set is not a set
4301 main.log.error( "ONOS" + str( i + 1 ) +
4302 " has repeat elements in" +
4303 " set " + onosSetName + ":\n" +
4304 str( getResponses[ i ] ) )
4305 getResults = main.FALSE
4306 elif getResponses[ i ] == main.ERROR:
4307 getResults = main.FALSE
4308 sizeResponses = []
4309 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004310 for i in range( main.numCtrls ):
4311 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004312 name="setTestSize-" + str( i ),
4313 args=[ onosSetName ] )
4314 threads.append( t )
4315 t.start()
4316 for t in threads:
4317 t.join()
4318 sizeResponses.append( t.result )
4319 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004320 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004321 if size != sizeResponses[ i ]:
4322 sizeResults = main.FALSE
4323 main.log.error( "ONOS" + str( i + 1 ) +
4324 " expected a size of " +
4325 str( size ) + " for set " + onosSetName +
4326 " but got " + str( sizeResponses[ i ] ) )
4327 retainResults = retainResults and getResults and sizeResults
4328 utilities.assert_equals( expect=main.TRUE,
4329 actual=retainResults,
4330 onpass="Set retain correct",
4331 onfail="Set retain was incorrect" )
4332
Jon Hall2a5002c2015-08-21 16:49:11 -07004333 # Transactional maps
4334 main.step( "Partitioned Transactional maps put" )
4335 tMapValue = "Testing"
4336 numKeys = 100
4337 putResult = True
4338 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4339 if len( putResponses ) == 100:
4340 for i in putResponses:
4341 if putResponses[ i ][ 'value' ] != tMapValue:
4342 putResult = False
4343 else:
4344 putResult = False
4345 if not putResult:
4346 main.log.debug( "Put response values: " + str( putResponses ) )
4347 utilities.assert_equals( expect=True,
4348 actual=putResult,
4349 onpass="Partitioned Transactional Map put successful",
4350 onfail="Partitioned Transactional Map put values are incorrect" )
4351
4352 main.step( "Partitioned Transactional maps get" )
4353 getCheck = True
4354 for n in range( 1, numKeys + 1 ):
4355 getResponses = []
4356 threads = []
4357 valueCheck = True
4358 for i in range( main.numCtrls ):
4359 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4360 name="TMap-get-" + str( i ),
4361 args=[ "Key" + str ( n ) ] )
4362 threads.append( t )
4363 t.start()
4364 for t in threads:
4365 t.join()
4366 getResponses.append( t.result )
4367 for node in getResponses:
4368 if node != tMapValue:
4369 valueCheck = False
4370 if not valueCheck:
4371 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4372 main.log.warn( getResponses )
4373 getCheck = getCheck and valueCheck
4374 utilities.assert_equals( expect=True,
4375 actual=getCheck,
4376 onpass="Partitioned Transactional Map get values were correct",
4377 onfail="Partitioned Transactional Map values incorrect" )
4378
4379 main.step( "In-memory Transactional maps put" )
4380 tMapValue = "Testing"
4381 numKeys = 100
4382 putResult = True
4383 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4384 if len( putResponses ) == 100:
4385 for i in putResponses:
4386 if putResponses[ i ][ 'value' ] != tMapValue:
4387 putResult = False
4388 else:
4389 putResult = False
4390 if not putResult:
4391 main.log.debug( "Put response values: " + str( putResponses ) )
4392 utilities.assert_equals( expect=True,
4393 actual=putResult,
4394 onpass="In-Memory Transactional Map put successful",
4395 onfail="In-Memory Transactional Map put values are incorrect" )
4396
4397 main.step( "In-Memory Transactional maps get" )
4398 getCheck = True
4399 for n in range( 1, numKeys + 1 ):
4400 getResponses = []
4401 threads = []
4402 valueCheck = True
4403 for i in range( main.numCtrls ):
4404 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4405 name="TMap-get-" + str( i ),
4406 args=[ "Key" + str ( n ) ],
4407 kwargs={ "inMemory": True } )
4408 threads.append( t )
4409 t.start()
4410 for t in threads:
4411 t.join()
4412 getResponses.append( t.result )
4413 for node in getResponses:
4414 if node != tMapValue:
4415 valueCheck = False
4416 if not valueCheck:
4417 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4418 main.log.warn( getResponses )
4419 getCheck = getCheck and valueCheck
4420 utilities.assert_equals( expect=True,
4421 actual=getCheck,
4422 onpass="In-Memory Transactional Map get values were correct",
4423 onfail="In-Memory Transactional Map values incorrect" )