blob: 855f3804163364b9c3ba0fd6934f7e8dcd76cfa9 [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
acsmars3a72bde2015-09-02 14:16:22 -07002811 if electionResult == main.FALSE:
2812 main.log.error(
2813 "Skipping Test Case because Election Test App isn't loaded" )
2814 main.skipCase()
2815
acsmars71adceb2015-08-31 15:09:26 -07002816 main.step( "Check that each node shows the same leader and candidates" )
2817 sameResult = main.TRUE
2818 failMessage = "Nodes have different leaders"
2819 for cli in main.CLIs:
2820 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2821 oldAllCandidates.append( node )
2822 oldLeaders.append( node[ 0 ] )
2823 oldCandidates = oldAllCandidates[ 0 ]
2824
2825 # Check that each node has the same leader. Defines oldLeader
2826 if len( set( oldLeaders ) ) != 1:
2827 sameResult = main.FALSE
2828 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2829 oldLeader = None
2830 else:
2831 oldLeader = oldLeaders[ 0 ]
2832
2833 # Check that each node's candidate list is the same
2834 for candidates in oldAllCandidates:
2835 if set( candidates ) != set( oldCandidates ):
2836 sameResult = main.FALSE
2837 failMessage += "and candidates"
2838
2839 utilities.assert_equals(
2840 expect=main.TRUE,
2841 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002842 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002843 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002844
2845 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002846 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002847 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002848 if oldLeader is None:
2849 main.log.error( "Leadership isn't consistent." )
2850 withdrawResult = main.FALSE
2851 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002852 for i in range( len( main.CLIs ) ):
acsmars71adceb2015-08-31 15:09:26 -07002853 if oldLeader == main.nodes[ i ].ip_address:
2854 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 break
2856 else: # FOR/ELSE statement
2857 main.log.error( "Leader election, could not find current leader" )
2858 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002859 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002860 utilities.assert_equals(
2861 expect=main.TRUE,
2862 actual=withdrawResult,
2863 onpass="Node was withdrawn from election",
2864 onfail="Node was not withdrawn from election" )
2865
acsmars71adceb2015-08-31 15:09:26 -07002866 main.step( "Check that a new node was elected leader" )
2867
Jon Hall5cf14d52015-07-16 12:15:19 -07002868 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002869 newLeaderResult = main.TRUE
2870 failMessage = "Nodes have different leaders"
2871
2872 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002873 for cli in main.CLIs:
acsmars71adceb2015-08-31 15:09:26 -07002874 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2875 # elections might no have finished yet
2876 if node[ 0 ] == 'none' and not expectNoLeader:
2877 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2878 "sure elections are complete." )
2879 time.sleep(5)
2880 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2881 # election still isn't done or there is a problem
2882 if node[ 0 ] == 'none':
2883 main.log.error( "No leader was elected on at least 1 node" )
2884 newLeaderResult = main.FALSE
2885 newAllCandidates.append( node )
2886 newLeaders.append( node[ 0 ] )
2887 newCandidates = newAllCandidates[ 0 ]
2888
2889 # Check that each node has the same leader. Defines newLeader
2890 if len( set( newLeaders ) ) != 1:
2891 newLeaderResult = main.FALSE
2892 main.log.error( "Nodes have different leaders: " +
2893 str( newLeaders ) )
2894 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002895 else:
acsmars71adceb2015-08-31 15:09:26 -07002896 newLeader = newLeaders[ 0 ]
2897
2898 # Check that each node's candidate list is the same
2899 for candidates in newAllCandidates:
2900 if set( candidates ) != set( newCandidates ):
2901 newLeaderResult = main.FALSE
2902 main.error.log( "Discrepancy in candidate lists detected" )
2903
2904 # Check that the new leader is not the older leader, which was withdrawn
2905 if newLeader == oldLeader:
2906 newLeaderResult = main.FALSE
2907 main.log.error( "All nodes still see old leader: " + oldLeader +
2908 " as the current leader" )
2909
Jon Hall5cf14d52015-07-16 12:15:19 -07002910 utilities.assert_equals(
2911 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002912 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002913 onpass="Leadership election passed",
2914 onfail="Something went wrong with Leadership election" )
2915
acsmars71adceb2015-08-31 15:09:26 -07002916 main.step( "Check that that new leader was the candidate of old leader")
2917 # candidates[ 2 ] should be come the top candidate after withdrawl
2918 correctCandidateResult = main.TRUE
2919 if expectNoLeader:
2920 if newLeader == 'none':
2921 main.log.info( "No leader expected. None found. Pass" )
2922 correctCandidateResult = main.TRUE
2923 else:
2924 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2925 correctCandidateResult = main.FALSE
2926 elif newLeader != oldCandidates[ 2 ]:
2927 correctCandidateResult = main.FALSE
2928 main.log.error( "Candidate " + newLeader + " was elected. " +
2929 oldCandidates[ 2 ] + " should have had priority." )
2930
2931 utilities.assert_equals(
2932 expect=main.TRUE,
2933 actual=correctCandidateResult,
2934 onpass="Correct Candidate Elected",
2935 onfail="Incorrect Candidate Elected" )
2936
Jon Hall5cf14d52015-07-16 12:15:19 -07002937 main.step( "Run for election on old leader( just so everyone " +
2938 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002939 if oldLeaderCLI is not None:
2940 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002941 else:
acsmars71adceb2015-08-31 15:09:26 -07002942 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002943 runResult = main.FALSE
2944 utilities.assert_equals(
2945 expect=main.TRUE,
2946 actual=runResult,
2947 onpass="App re-ran for election",
2948 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002949 main.step(
2950 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002951 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07002952 positionResult = main.TRUE
2953 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
2954
2955 # Reset and reuse the new candidate and leaders lists
2956 newAllCandidates = []
2957 newCandidates = []
2958 newLeaders = []
2959 for cli in main.CLIs:
2960 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2961 if oldLeader not in node: # election might no have finished yet
2962 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2963 "be sure elections are complete" )
2964 time.sleep(5)
2965 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2966 if oldLeader not in node: # election still isn't done, errors
2967 main.log.error(
2968 "Old leader was not elected on at least one node" )
2969 positionResult = main.FALSE
2970 newAllCandidates.append( node )
2971 newLeaders.append( node[ 0 ] )
2972 newCandidates = newAllCandidates[ 0 ]
2973
2974 # Check that each node has the same leader. Defines newLeader
2975 if len( set( newLeaders ) ) != 1:
2976 positionResult = main.FALSE
2977 main.log.error( "Nodes have different leaders: " +
2978 str( newLeaders ) )
2979 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002980 else:
acsmars71adceb2015-08-31 15:09:26 -07002981 newLeader = newLeaders[ 0 ]
2982
2983 # Check that each node's candidate list is the same
2984 for candidates in newAllCandidates:
2985 if set( candidates ) != set( newCandidates ):
2986 newLeaderResult = main.FALSE
2987 main.error.log( "Discrepancy in candidate lists detected" )
2988
2989 # Check that the re-elected node is last on the candidate List
2990 if oldLeader != newCandidates[ -1 ]:
2991 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2992 str( newCandidates ) )
2993 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002994
2995 utilities.assert_equals(
2996 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002997 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002998 onpass="Old leader successfully re-ran for election",
2999 onfail="Something went wrong with Leadership election after " +
3000 "the old leader re-ran for election" )
3001
3002 def CASE16( self, main ):
3003 """
3004 Install Distributed Primitives app
3005 """
3006 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003007 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003008 assert main, "main not defined"
3009 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003010 assert main.CLIs, "main.CLIs not defined"
3011 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003012
3013 # Variables for the distributed primitives tests
3014 global pCounterName
3015 global iCounterName
3016 global pCounterValue
3017 global iCounterValue
3018 global onosSet
3019 global onosSetName
3020 pCounterName = "TestON-Partitions"
3021 iCounterName = "TestON-inMemory"
3022 pCounterValue = 0
3023 iCounterValue = 0
3024 onosSet = set([])
3025 onosSetName = "TestON-set"
3026
3027 description = "Install Primitives app"
3028 main.case( description )
3029 main.step( "Install Primitives app" )
3030 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003031 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003032 utilities.assert_equals( expect=main.TRUE,
3033 actual=appResults,
3034 onpass="Primitives app activated",
3035 onfail="Primitives app not activated" )
3036 time.sleep( 5 ) # To allow all nodes to activate
3037
3038 def CASE17( self, main ):
3039 """
3040 Check for basic functionality with distributed primitives
3041 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003042 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003043 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003044 assert main, "main not defined"
3045 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003046 assert main.CLIs, "main.CLIs not defined"
3047 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003048 assert pCounterName, "pCounterName not defined"
3049 assert iCounterName, "iCounterName not defined"
3050 assert onosSetName, "onosSetName not defined"
3051 # NOTE: assert fails if value is 0/None/Empty/False
3052 try:
3053 pCounterValue
3054 except NameError:
3055 main.log.error( "pCounterValue not defined, setting to 0" )
3056 pCounterValue = 0
3057 try:
3058 iCounterValue
3059 except NameError:
3060 main.log.error( "iCounterValue not defined, setting to 0" )
3061 iCounterValue = 0
3062 try:
3063 onosSet
3064 except NameError:
3065 main.log.error( "onosSet not defined, setting to empty Set" )
3066 onosSet = set([])
3067 # Variables for the distributed primitives tests. These are local only
3068 addValue = "a"
3069 addAllValue = "a b c d e f"
3070 retainValue = "c d e f"
3071
3072 description = "Check for basic functionality with distributed " +\
3073 "primitives"
3074 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003075 main.caseExplanation = "Test the methods of the distributed " +\
3076 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003077 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003078 # Partitioned counters
3079 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003080 pCounters = []
3081 threads = []
3082 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003083 for i in range( main.numCtrls ):
3084 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3085 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003086 args=[ pCounterName ] )
3087 pCounterValue += 1
3088 addedPValues.append( pCounterValue )
3089 threads.append( t )
3090 t.start()
3091
3092 for t in threads:
3093 t.join()
3094 pCounters.append( t.result )
3095 # Check that counter incremented numController times
3096 pCounterResults = True
3097 for i in addedPValues:
3098 tmpResult = i in pCounters
3099 pCounterResults = pCounterResults and tmpResult
3100 if not tmpResult:
3101 main.log.error( str( i ) + " is not in partitioned "
3102 "counter incremented results" )
3103 utilities.assert_equals( expect=True,
3104 actual=pCounterResults,
3105 onpass="Default counter incremented",
3106 onfail="Error incrementing default" +
3107 " counter" )
3108
Jon Halle1a3b752015-07-22 13:02:46 -07003109 main.step( "Get then Increment a default counter on each node" )
3110 pCounters = []
3111 threads = []
3112 addedPValues = []
3113 for i in range( main.numCtrls ):
3114 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3115 name="counterGetAndAdd-" + str( i ),
3116 args=[ pCounterName ] )
3117 addedPValues.append( pCounterValue )
3118 pCounterValue += 1
3119 threads.append( t )
3120 t.start()
3121
3122 for t in threads:
3123 t.join()
3124 pCounters.append( t.result )
3125 # Check that counter incremented numController times
3126 pCounterResults = True
3127 for i in addedPValues:
3128 tmpResult = i in pCounters
3129 pCounterResults = pCounterResults and tmpResult
3130 if not tmpResult:
3131 main.log.error( str( i ) + " is not in partitioned "
3132 "counter incremented results" )
3133 utilities.assert_equals( expect=True,
3134 actual=pCounterResults,
3135 onpass="Default counter incremented",
3136 onfail="Error incrementing default" +
3137 " counter" )
3138
3139 main.step( "Counters we added have the correct values" )
3140 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3141 utilities.assert_equals( expect=main.TRUE,
3142 actual=incrementCheck,
3143 onpass="Added counters are correct",
3144 onfail="Added counters are incorrect" )
3145
3146 main.step( "Add -8 to then get a default counter on each node" )
3147 pCounters = []
3148 threads = []
3149 addedPValues = []
3150 for i in range( main.numCtrls ):
3151 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3152 name="counterIncrement-" + str( i ),
3153 args=[ pCounterName ],
3154 kwargs={ "delta": -8 } )
3155 pCounterValue += -8
3156 addedPValues.append( pCounterValue )
3157 threads.append( t )
3158 t.start()
3159
3160 for t in threads:
3161 t.join()
3162 pCounters.append( t.result )
3163 # Check that counter incremented numController times
3164 pCounterResults = True
3165 for i in addedPValues:
3166 tmpResult = i in pCounters
3167 pCounterResults = pCounterResults and tmpResult
3168 if not tmpResult:
3169 main.log.error( str( i ) + " is not in partitioned "
3170 "counter incremented results" )
3171 utilities.assert_equals( expect=True,
3172 actual=pCounterResults,
3173 onpass="Default counter incremented",
3174 onfail="Error incrementing default" +
3175 " counter" )
3176
3177 main.step( "Add 5 to then get a default counter on each node" )
3178 pCounters = []
3179 threads = []
3180 addedPValues = []
3181 for i in range( main.numCtrls ):
3182 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3183 name="counterIncrement-" + str( i ),
3184 args=[ pCounterName ],
3185 kwargs={ "delta": 5 } )
3186 pCounterValue += 5
3187 addedPValues.append( pCounterValue )
3188 threads.append( t )
3189 t.start()
3190
3191 for t in threads:
3192 t.join()
3193 pCounters.append( t.result )
3194 # Check that counter incremented numController times
3195 pCounterResults = True
3196 for i in addedPValues:
3197 tmpResult = i in pCounters
3198 pCounterResults = pCounterResults and tmpResult
3199 if not tmpResult:
3200 main.log.error( str( i ) + " is not in partitioned "
3201 "counter incremented results" )
3202 utilities.assert_equals( expect=True,
3203 actual=pCounterResults,
3204 onpass="Default counter incremented",
3205 onfail="Error incrementing default" +
3206 " counter" )
3207
3208 main.step( "Get then add 5 to a default counter on each node" )
3209 pCounters = []
3210 threads = []
3211 addedPValues = []
3212 for i in range( main.numCtrls ):
3213 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3214 name="counterIncrement-" + str( i ),
3215 args=[ pCounterName ],
3216 kwargs={ "delta": 5 } )
3217 addedPValues.append( pCounterValue )
3218 pCounterValue += 5
3219 threads.append( t )
3220 t.start()
3221
3222 for t in threads:
3223 t.join()
3224 pCounters.append( t.result )
3225 # Check that counter incremented numController times
3226 pCounterResults = True
3227 for i in addedPValues:
3228 tmpResult = i in pCounters
3229 pCounterResults = pCounterResults and tmpResult
3230 if not tmpResult:
3231 main.log.error( str( i ) + " is not in partitioned "
3232 "counter incremented results" )
3233 utilities.assert_equals( expect=True,
3234 actual=pCounterResults,
3235 onpass="Default counter incremented",
3236 onfail="Error incrementing default" +
3237 " counter" )
3238
3239 main.step( "Counters we added have the correct values" )
3240 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3241 utilities.assert_equals( expect=main.TRUE,
3242 actual=incrementCheck,
3243 onpass="Added counters are correct",
3244 onfail="Added counters are incorrect" )
3245
3246 # In-Memory counters
3247 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003248 iCounters = []
3249 addedIValues = []
3250 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003251 for i in range( main.numCtrls ):
3252 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003253 name="icounterIncrement-" + str( i ),
3254 args=[ iCounterName ],
3255 kwargs={ "inMemory": True } )
3256 iCounterValue += 1
3257 addedIValues.append( iCounterValue )
3258 threads.append( t )
3259 t.start()
3260
3261 for t in threads:
3262 t.join()
3263 iCounters.append( t.result )
3264 # Check that counter incremented numController times
3265 iCounterResults = True
3266 for i in addedIValues:
3267 tmpResult = i in iCounters
3268 iCounterResults = iCounterResults and tmpResult
3269 if not tmpResult:
3270 main.log.error( str( i ) + " is not in the in-memory "
3271 "counter incremented results" )
3272 utilities.assert_equals( expect=True,
3273 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003274 onpass="In-memory counter incremented",
3275 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003276 " counter" )
3277
Jon Halle1a3b752015-07-22 13:02:46 -07003278 main.step( "Get then Increment a in-memory counter on each node" )
3279 iCounters = []
3280 threads = []
3281 addedIValues = []
3282 for i in range( main.numCtrls ):
3283 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3284 name="counterGetAndAdd-" + str( i ),
3285 args=[ iCounterName ],
3286 kwargs={ "inMemory": True } )
3287 addedIValues.append( iCounterValue )
3288 iCounterValue += 1
3289 threads.append( t )
3290 t.start()
3291
3292 for t in threads:
3293 t.join()
3294 iCounters.append( t.result )
3295 # Check that counter incremented numController times
3296 iCounterResults = True
3297 for i in addedIValues:
3298 tmpResult = i in iCounters
3299 iCounterResults = iCounterResults and tmpResult
3300 if not tmpResult:
3301 main.log.error( str( i ) + " is not in in-memory "
3302 "counter incremented results" )
3303 utilities.assert_equals( expect=True,
3304 actual=iCounterResults,
3305 onpass="In-memory counter incremented",
3306 onfail="Error incrementing in-memory" +
3307 " counter" )
3308
3309 main.step( "Counters we added have the correct values" )
3310 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3311 utilities.assert_equals( expect=main.TRUE,
3312 actual=incrementCheck,
3313 onpass="Added counters are correct",
3314 onfail="Added counters are incorrect" )
3315
3316 main.step( "Add -8 to then get a in-memory counter on each node" )
3317 iCounters = []
3318 threads = []
3319 addedIValues = []
3320 for i in range( main.numCtrls ):
3321 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3322 name="counterIncrement-" + str( i ),
3323 args=[ iCounterName ],
3324 kwargs={ "delta": -8, "inMemory": True } )
3325 iCounterValue += -8
3326 addedIValues.append( iCounterValue )
3327 threads.append( t )
3328 t.start()
3329
3330 for t in threads:
3331 t.join()
3332 iCounters.append( t.result )
3333 # Check that counter incremented numController times
3334 iCounterResults = True
3335 for i in addedIValues:
3336 tmpResult = i in iCounters
3337 iCounterResults = iCounterResults and tmpResult
3338 if not tmpResult:
3339 main.log.error( str( i ) + " is not in in-memory "
3340 "counter incremented results" )
3341 utilities.assert_equals( expect=True,
3342 actual=pCounterResults,
3343 onpass="In-memory counter incremented",
3344 onfail="Error incrementing in-memory" +
3345 " counter" )
3346
3347 main.step( "Add 5 to then get a in-memory counter on each node" )
3348 iCounters = []
3349 threads = []
3350 addedIValues = []
3351 for i in range( main.numCtrls ):
3352 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3353 name="counterIncrement-" + str( i ),
3354 args=[ iCounterName ],
3355 kwargs={ "delta": 5, "inMemory": True } )
3356 iCounterValue += 5
3357 addedIValues.append( iCounterValue )
3358 threads.append( t )
3359 t.start()
3360
3361 for t in threads:
3362 t.join()
3363 iCounters.append( t.result )
3364 # Check that counter incremented numController times
3365 iCounterResults = True
3366 for i in addedIValues:
3367 tmpResult = i in iCounters
3368 iCounterResults = iCounterResults and tmpResult
3369 if not tmpResult:
3370 main.log.error( str( i ) + " is not in in-memory "
3371 "counter incremented results" )
3372 utilities.assert_equals( expect=True,
3373 actual=pCounterResults,
3374 onpass="In-memory counter incremented",
3375 onfail="Error incrementing in-memory" +
3376 " counter" )
3377
3378 main.step( "Get then add 5 to a in-memory counter on each node" )
3379 iCounters = []
3380 threads = []
3381 addedIValues = []
3382 for i in range( main.numCtrls ):
3383 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3384 name="counterIncrement-" + str( i ),
3385 args=[ iCounterName ],
3386 kwargs={ "delta": 5, "inMemory": True } )
3387 addedIValues.append( iCounterValue )
3388 iCounterValue += 5
3389 threads.append( t )
3390 t.start()
3391
3392 for t in threads:
3393 t.join()
3394 iCounters.append( t.result )
3395 # Check that counter incremented numController times
3396 iCounterResults = True
3397 for i in addedIValues:
3398 tmpResult = i in iCounters
3399 iCounterResults = iCounterResults and tmpResult
3400 if not tmpResult:
3401 main.log.error( str( i ) + " is not in in-memory "
3402 "counter incremented results" )
3403 utilities.assert_equals( expect=True,
3404 actual=iCounterResults,
3405 onpass="In-memory counter incremented",
3406 onfail="Error incrementing in-memory" +
3407 " counter" )
3408
3409 main.step( "Counters we added have the correct values" )
3410 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3411 utilities.assert_equals( expect=main.TRUE,
3412 actual=incrementCheck,
3413 onpass="Added counters are correct",
3414 onfail="Added counters are incorrect" )
3415
Jon Hall5cf14d52015-07-16 12:15:19 -07003416 main.step( "Check counters are consistant across nodes" )
3417 onosCounters = []
3418 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003419 for i in range( main.numCtrls ):
3420 t = main.Thread( target=main.CLIs[i].counters,
Jon Hall5cf14d52015-07-16 12:15:19 -07003421 name="counters-" + str( i ) )
3422 threads.append( t )
3423 t.start()
3424 for t in threads:
3425 t.join()
3426 onosCounters.append( t.result )
3427 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3428 if all( tmp ):
3429 main.log.info( "Counters are consistent across all nodes" )
3430 consistentCounterResults = main.TRUE
3431 else:
3432 main.log.error( "Counters are not consistent across all nodes" )
3433 consistentCounterResults = main.FALSE
3434 utilities.assert_equals( expect=main.TRUE,
3435 actual=consistentCounterResults,
3436 onpass="ONOS counters are consistent " +
3437 "across nodes",
3438 onfail="ONOS Counters are inconsistent " +
3439 "across nodes" )
3440
3441 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003442 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3443 incrementCheck = incrementCheck and \
3444 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003445 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003446 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003447 onpass="Added counters are correct",
3448 onfail="Added counters are incorrect" )
Jon Halle1a3b752015-07-22 13:02:46 -07003449
Jon Hall5cf14d52015-07-16 12:15:19 -07003450 # DISTRIBUTED SETS
3451 main.step( "Distributed Set get" )
3452 size = len( onosSet )
3453 getResponses = []
3454 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003455 for i in range( main.numCtrls ):
3456 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003457 name="setTestGet-" + str( i ),
3458 args=[ onosSetName ] )
3459 threads.append( t )
3460 t.start()
3461 for t in threads:
3462 t.join()
3463 getResponses.append( t.result )
3464
3465 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003466 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003467 if isinstance( getResponses[ i ], list):
3468 current = set( getResponses[ i ] )
3469 if len( current ) == len( getResponses[ i ] ):
3470 # no repeats
3471 if onosSet != current:
3472 main.log.error( "ONOS" + str( i + 1 ) +
3473 " has incorrect view" +
3474 " of set " + onosSetName + ":\n" +
3475 str( getResponses[ i ] ) )
3476 main.log.debug( "Expected: " + str( onosSet ) )
3477 main.log.debug( "Actual: " + str( current ) )
3478 getResults = main.FALSE
3479 else:
3480 # error, set is not a set
3481 main.log.error( "ONOS" + str( i + 1 ) +
3482 " has repeat elements in" +
3483 " set " + onosSetName + ":\n" +
3484 str( getResponses[ i ] ) )
3485 getResults = main.FALSE
3486 elif getResponses[ i ] == main.ERROR:
3487 getResults = main.FALSE
3488 utilities.assert_equals( expect=main.TRUE,
3489 actual=getResults,
3490 onpass="Set elements are correct",
3491 onfail="Set elements are incorrect" )
3492
3493 main.step( "Distributed Set size" )
3494 sizeResponses = []
3495 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003496 for i in range( main.numCtrls ):
3497 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003498 name="setTestSize-" + str( i ),
3499 args=[ onosSetName ] )
3500 threads.append( t )
3501 t.start()
3502 for t in threads:
3503 t.join()
3504 sizeResponses.append( t.result )
3505
3506 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003507 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003508 if size != sizeResponses[ i ]:
3509 sizeResults = main.FALSE
3510 main.log.error( "ONOS" + str( i + 1 ) +
3511 " expected a size of " + str( size ) +
3512 " for set " + onosSetName +
3513 " but got " + str( sizeResponses[ i ] ) )
3514 utilities.assert_equals( expect=main.TRUE,
3515 actual=sizeResults,
3516 onpass="Set sizes are correct",
3517 onfail="Set sizes are incorrect" )
3518
3519 main.step( "Distributed Set add()" )
3520 onosSet.add( addValue )
3521 addResponses = []
3522 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003523 for i in range( main.numCtrls ):
3524 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003525 name="setTestAdd-" + str( i ),
3526 args=[ onosSetName, addValue ] )
3527 threads.append( t )
3528 t.start()
3529 for t in threads:
3530 t.join()
3531 addResponses.append( t.result )
3532
3533 # main.TRUE = successfully changed the set
3534 # main.FALSE = action resulted in no change in set
3535 # main.ERROR - Some error in executing the function
3536 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003537 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003538 if addResponses[ i ] == main.TRUE:
3539 # All is well
3540 pass
3541 elif addResponses[ i ] == main.FALSE:
3542 # Already in set, probably fine
3543 pass
3544 elif addResponses[ i ] == main.ERROR:
3545 # Error in execution
3546 addResults = main.FALSE
3547 else:
3548 # unexpected result
3549 addResults = main.FALSE
3550 if addResults != main.TRUE:
3551 main.log.error( "Error executing set add" )
3552
3553 # Check if set is still correct
3554 size = len( onosSet )
3555 getResponses = []
3556 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003557 for i in range( main.numCtrls ):
3558 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003559 name="setTestGet-" + str( i ),
3560 args=[ onosSetName ] )
3561 threads.append( t )
3562 t.start()
3563 for t in threads:
3564 t.join()
3565 getResponses.append( t.result )
3566 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003567 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003568 if isinstance( getResponses[ i ], list):
3569 current = set( getResponses[ i ] )
3570 if len( current ) == len( getResponses[ i ] ):
3571 # no repeats
3572 if onosSet != current:
3573 main.log.error( "ONOS" + str( i + 1 ) +
3574 " has incorrect view" +
3575 " of set " + onosSetName + ":\n" +
3576 str( getResponses[ i ] ) )
3577 main.log.debug( "Expected: " + str( onosSet ) )
3578 main.log.debug( "Actual: " + str( current ) )
3579 getResults = main.FALSE
3580 else:
3581 # error, set is not a set
3582 main.log.error( "ONOS" + str( i + 1 ) +
3583 " has repeat elements in" +
3584 " set " + onosSetName + ":\n" +
3585 str( getResponses[ i ] ) )
3586 getResults = main.FALSE
3587 elif getResponses[ i ] == main.ERROR:
3588 getResults = main.FALSE
3589 sizeResponses = []
3590 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003591 for i in range( main.numCtrls ):
3592 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003593 name="setTestSize-" + str( i ),
3594 args=[ onosSetName ] )
3595 threads.append( t )
3596 t.start()
3597 for t in threads:
3598 t.join()
3599 sizeResponses.append( t.result )
3600 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003601 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003602 if size != sizeResponses[ i ]:
3603 sizeResults = main.FALSE
3604 main.log.error( "ONOS" + str( i + 1 ) +
3605 " expected a size of " + str( size ) +
3606 " for set " + onosSetName +
3607 " but got " + str( sizeResponses[ i ] ) )
3608 addResults = addResults and getResults and sizeResults
3609 utilities.assert_equals( expect=main.TRUE,
3610 actual=addResults,
3611 onpass="Set add correct",
3612 onfail="Set add was incorrect" )
3613
3614 main.step( "Distributed Set addAll()" )
3615 onosSet.update( addAllValue.split() )
3616 addResponses = []
3617 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003618 for i in range( main.numCtrls ):
3619 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003620 name="setTestAddAll-" + str( i ),
3621 args=[ onosSetName, addAllValue ] )
3622 threads.append( t )
3623 t.start()
3624 for t in threads:
3625 t.join()
3626 addResponses.append( t.result )
3627
3628 # main.TRUE = successfully changed the set
3629 # main.FALSE = action resulted in no change in set
3630 # main.ERROR - Some error in executing the function
3631 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003632 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003633 if addResponses[ i ] == main.TRUE:
3634 # All is well
3635 pass
3636 elif addResponses[ i ] == main.FALSE:
3637 # Already in set, probably fine
3638 pass
3639 elif addResponses[ i ] == main.ERROR:
3640 # Error in execution
3641 addAllResults = main.FALSE
3642 else:
3643 # unexpected result
3644 addAllResults = main.FALSE
3645 if addAllResults != main.TRUE:
3646 main.log.error( "Error executing set addAll" )
3647
3648 # Check if set is still correct
3649 size = len( onosSet )
3650 getResponses = []
3651 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003652 for i in range( main.numCtrls ):
3653 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003654 name="setTestGet-" + str( i ),
3655 args=[ onosSetName ] )
3656 threads.append( t )
3657 t.start()
3658 for t in threads:
3659 t.join()
3660 getResponses.append( t.result )
3661 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003662 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003663 if isinstance( getResponses[ i ], list):
3664 current = set( getResponses[ i ] )
3665 if len( current ) == len( getResponses[ i ] ):
3666 # no repeats
3667 if onosSet != current:
3668 main.log.error( "ONOS" + str( i + 1 ) +
3669 " has incorrect view" +
3670 " of set " + onosSetName + ":\n" +
3671 str( getResponses[ i ] ) )
3672 main.log.debug( "Expected: " + str( onosSet ) )
3673 main.log.debug( "Actual: " + str( current ) )
3674 getResults = main.FALSE
3675 else:
3676 # error, set is not a set
3677 main.log.error( "ONOS" + str( i + 1 ) +
3678 " has repeat elements in" +
3679 " set " + onosSetName + ":\n" +
3680 str( getResponses[ i ] ) )
3681 getResults = main.FALSE
3682 elif getResponses[ i ] == main.ERROR:
3683 getResults = main.FALSE
3684 sizeResponses = []
3685 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003686 for i in range( main.numCtrls ):
3687 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003688 name="setTestSize-" + str( i ),
3689 args=[ onosSetName ] )
3690 threads.append( t )
3691 t.start()
3692 for t in threads:
3693 t.join()
3694 sizeResponses.append( t.result )
3695 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003696 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003697 if size != sizeResponses[ i ]:
3698 sizeResults = main.FALSE
3699 main.log.error( "ONOS" + str( i + 1 ) +
3700 " expected a size of " + str( size ) +
3701 " for set " + onosSetName +
3702 " but got " + str( sizeResponses[ i ] ) )
3703 addAllResults = addAllResults and getResults and sizeResults
3704 utilities.assert_equals( expect=main.TRUE,
3705 actual=addAllResults,
3706 onpass="Set addAll correct",
3707 onfail="Set addAll was incorrect" )
3708
3709 main.step( "Distributed Set contains()" )
3710 containsResponses = []
3711 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003712 for i in range( main.numCtrls ):
3713 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003714 name="setContains-" + str( i ),
3715 args=[ onosSetName ],
3716 kwargs={ "values": addValue } )
3717 threads.append( t )
3718 t.start()
3719 for t in threads:
3720 t.join()
3721 # NOTE: This is the tuple
3722 containsResponses.append( t.result )
3723
3724 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003725 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003726 if containsResponses[ i ] == main.ERROR:
3727 containsResults = main.FALSE
3728 else:
3729 containsResults = containsResults and\
3730 containsResponses[ i ][ 1 ]
3731 utilities.assert_equals( expect=main.TRUE,
3732 actual=containsResults,
3733 onpass="Set contains is functional",
3734 onfail="Set contains failed" )
3735
3736 main.step( "Distributed Set containsAll()" )
3737 containsAllResponses = []
3738 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003739 for i in range( main.numCtrls ):
3740 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003741 name="setContainsAll-" + str( i ),
3742 args=[ onosSetName ],
3743 kwargs={ "values": addAllValue } )
3744 threads.append( t )
3745 t.start()
3746 for t in threads:
3747 t.join()
3748 # NOTE: This is the tuple
3749 containsAllResponses.append( t.result )
3750
3751 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003752 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003753 if containsResponses[ i ] == main.ERROR:
3754 containsResults = main.FALSE
3755 else:
3756 containsResults = containsResults and\
3757 containsResponses[ i ][ 1 ]
3758 utilities.assert_equals( expect=main.TRUE,
3759 actual=containsAllResults,
3760 onpass="Set containsAll is functional",
3761 onfail="Set containsAll failed" )
3762
3763 main.step( "Distributed Set remove()" )
3764 onosSet.remove( addValue )
3765 removeResponses = []
3766 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003767 for i in range( main.numCtrls ):
3768 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003769 name="setTestRemove-" + str( i ),
3770 args=[ onosSetName, addValue ] )
3771 threads.append( t )
3772 t.start()
3773 for t in threads:
3774 t.join()
3775 removeResponses.append( t.result )
3776
3777 # main.TRUE = successfully changed the set
3778 # main.FALSE = action resulted in no change in set
3779 # main.ERROR - Some error in executing the function
3780 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003781 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003782 if removeResponses[ i ] == main.TRUE:
3783 # All is well
3784 pass
3785 elif removeResponses[ i ] == main.FALSE:
3786 # not in set, probably fine
3787 pass
3788 elif removeResponses[ i ] == main.ERROR:
3789 # Error in execution
3790 removeResults = main.FALSE
3791 else:
3792 # unexpected result
3793 removeResults = main.FALSE
3794 if removeResults != main.TRUE:
3795 main.log.error( "Error executing set remove" )
3796
3797 # Check if set is still correct
3798 size = len( onosSet )
3799 getResponses = []
3800 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003801 for i in range( main.numCtrls ):
3802 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003803 name="setTestGet-" + str( i ),
3804 args=[ onosSetName ] )
3805 threads.append( t )
3806 t.start()
3807 for t in threads:
3808 t.join()
3809 getResponses.append( t.result )
3810 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003811 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003812 if isinstance( getResponses[ i ], list):
3813 current = set( getResponses[ i ] )
3814 if len( current ) == len( getResponses[ i ] ):
3815 # no repeats
3816 if onosSet != current:
3817 main.log.error( "ONOS" + str( i + 1 ) +
3818 " has incorrect view" +
3819 " of set " + onosSetName + ":\n" +
3820 str( getResponses[ i ] ) )
3821 main.log.debug( "Expected: " + str( onosSet ) )
3822 main.log.debug( "Actual: " + str( current ) )
3823 getResults = main.FALSE
3824 else:
3825 # error, set is not a set
3826 main.log.error( "ONOS" + str( i + 1 ) +
3827 " has repeat elements in" +
3828 " set " + onosSetName + ":\n" +
3829 str( getResponses[ i ] ) )
3830 getResults = main.FALSE
3831 elif getResponses[ i ] == main.ERROR:
3832 getResults = main.FALSE
3833 sizeResponses = []
3834 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003835 for i in range( main.numCtrls ):
3836 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003837 name="setTestSize-" + str( i ),
3838 args=[ onosSetName ] )
3839 threads.append( t )
3840 t.start()
3841 for t in threads:
3842 t.join()
3843 sizeResponses.append( t.result )
3844 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003845 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003846 if size != sizeResponses[ i ]:
3847 sizeResults = main.FALSE
3848 main.log.error( "ONOS" + str( i + 1 ) +
3849 " expected a size of " + str( size ) +
3850 " for set " + onosSetName +
3851 " but got " + str( sizeResponses[ i ] ) )
3852 removeResults = removeResults and getResults and sizeResults
3853 utilities.assert_equals( expect=main.TRUE,
3854 actual=removeResults,
3855 onpass="Set remove correct",
3856 onfail="Set remove was incorrect" )
3857
3858 main.step( "Distributed Set removeAll()" )
3859 onosSet.difference_update( addAllValue.split() )
3860 removeAllResponses = []
3861 threads = []
3862 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003863 for i in range( main.numCtrls ):
3864 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003865 name="setTestRemoveAll-" + str( i ),
3866 args=[ onosSetName, addAllValue ] )
3867 threads.append( t )
3868 t.start()
3869 for t in threads:
3870 t.join()
3871 removeAllResponses.append( t.result )
3872 except Exception, e:
3873 main.log.exception(e)
3874
3875 # main.TRUE = successfully changed the set
3876 # main.FALSE = action resulted in no change in set
3877 # main.ERROR - Some error in executing the function
3878 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003879 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003880 if removeAllResponses[ i ] == main.TRUE:
3881 # All is well
3882 pass
3883 elif removeAllResponses[ i ] == main.FALSE:
3884 # not in set, probably fine
3885 pass
3886 elif removeAllResponses[ i ] == main.ERROR:
3887 # Error in execution
3888 removeAllResults = main.FALSE
3889 else:
3890 # unexpected result
3891 removeAllResults = main.FALSE
3892 if removeAllResults != main.TRUE:
3893 main.log.error( "Error executing set removeAll" )
3894
3895 # Check if set is still correct
3896 size = len( onosSet )
3897 getResponses = []
3898 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003899 for i in range( main.numCtrls ):
3900 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003901 name="setTestGet-" + str( i ),
3902 args=[ onosSetName ] )
3903 threads.append( t )
3904 t.start()
3905 for t in threads:
3906 t.join()
3907 getResponses.append( t.result )
3908 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003909 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003910 if isinstance( getResponses[ i ], list):
3911 current = set( getResponses[ i ] )
3912 if len( current ) == len( getResponses[ i ] ):
3913 # no repeats
3914 if onosSet != current:
3915 main.log.error( "ONOS" + str( i + 1 ) +
3916 " has incorrect view" +
3917 " of set " + onosSetName + ":\n" +
3918 str( getResponses[ i ] ) )
3919 main.log.debug( "Expected: " + str( onosSet ) )
3920 main.log.debug( "Actual: " + str( current ) )
3921 getResults = main.FALSE
3922 else:
3923 # error, set is not a set
3924 main.log.error( "ONOS" + str( i + 1 ) +
3925 " has repeat elements in" +
3926 " set " + onosSetName + ":\n" +
3927 str( getResponses[ i ] ) )
3928 getResults = main.FALSE
3929 elif getResponses[ i ] == main.ERROR:
3930 getResults = main.FALSE
3931 sizeResponses = []
3932 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003933 for i in range( main.numCtrls ):
3934 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003935 name="setTestSize-" + str( i ),
3936 args=[ onosSetName ] )
3937 threads.append( t )
3938 t.start()
3939 for t in threads:
3940 t.join()
3941 sizeResponses.append( t.result )
3942 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003943 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003944 if size != sizeResponses[ i ]:
3945 sizeResults = main.FALSE
3946 main.log.error( "ONOS" + str( i + 1 ) +
3947 " expected a size of " + str( size ) +
3948 " for set " + onosSetName +
3949 " but got " + str( sizeResponses[ i ] ) )
3950 removeAllResults = removeAllResults and getResults and sizeResults
3951 utilities.assert_equals( expect=main.TRUE,
3952 actual=removeAllResults,
3953 onpass="Set removeAll correct",
3954 onfail="Set removeAll was incorrect" )
3955
3956 main.step( "Distributed Set addAll()" )
3957 onosSet.update( addAllValue.split() )
3958 addResponses = []
3959 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003960 for i in range( main.numCtrls ):
3961 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003962 name="setTestAddAll-" + str( i ),
3963 args=[ onosSetName, addAllValue ] )
3964 threads.append( t )
3965 t.start()
3966 for t in threads:
3967 t.join()
3968 addResponses.append( t.result )
3969
3970 # main.TRUE = successfully changed the set
3971 # main.FALSE = action resulted in no change in set
3972 # main.ERROR - Some error in executing the function
3973 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003974 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003975 if addResponses[ i ] == main.TRUE:
3976 # All is well
3977 pass
3978 elif addResponses[ i ] == main.FALSE:
3979 # Already in set, probably fine
3980 pass
3981 elif addResponses[ i ] == main.ERROR:
3982 # Error in execution
3983 addAllResults = main.FALSE
3984 else:
3985 # unexpected result
3986 addAllResults = main.FALSE
3987 if addAllResults != main.TRUE:
3988 main.log.error( "Error executing set addAll" )
3989
3990 # Check if set is still correct
3991 size = len( onosSet )
3992 getResponses = []
3993 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003994 for i in range( main.numCtrls ):
3995 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003996 name="setTestGet-" + str( i ),
3997 args=[ onosSetName ] )
3998 threads.append( t )
3999 t.start()
4000 for t in threads:
4001 t.join()
4002 getResponses.append( t.result )
4003 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004004 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004005 if isinstance( getResponses[ i ], list):
4006 current = set( getResponses[ i ] )
4007 if len( current ) == len( getResponses[ i ] ):
4008 # no repeats
4009 if onosSet != current:
4010 main.log.error( "ONOS" + str( i + 1 ) +
4011 " has incorrect view" +
4012 " of set " + onosSetName + ":\n" +
4013 str( getResponses[ i ] ) )
4014 main.log.debug( "Expected: " + str( onosSet ) )
4015 main.log.debug( "Actual: " + str( current ) )
4016 getResults = main.FALSE
4017 else:
4018 # error, set is not a set
4019 main.log.error( "ONOS" + str( i + 1 ) +
4020 " has repeat elements in" +
4021 " set " + onosSetName + ":\n" +
4022 str( getResponses[ i ] ) )
4023 getResults = main.FALSE
4024 elif getResponses[ i ] == main.ERROR:
4025 getResults = main.FALSE
4026 sizeResponses = []
4027 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004028 for i in range( main.numCtrls ):
4029 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004030 name="setTestSize-" + str( i ),
4031 args=[ onosSetName ] )
4032 threads.append( t )
4033 t.start()
4034 for t in threads:
4035 t.join()
4036 sizeResponses.append( t.result )
4037 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004038 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004039 if size != sizeResponses[ i ]:
4040 sizeResults = main.FALSE
4041 main.log.error( "ONOS" + str( i + 1 ) +
4042 " expected a size of " + str( size ) +
4043 " for set " + onosSetName +
4044 " but got " + str( sizeResponses[ i ] ) )
4045 addAllResults = addAllResults and getResults and sizeResults
4046 utilities.assert_equals( expect=main.TRUE,
4047 actual=addAllResults,
4048 onpass="Set addAll correct",
4049 onfail="Set addAll was incorrect" )
4050
4051 main.step( "Distributed Set clear()" )
4052 onosSet.clear()
4053 clearResponses = []
4054 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004055 for i in range( main.numCtrls ):
4056 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004057 name="setTestClear-" + str( i ),
4058 args=[ onosSetName, " "], # Values doesn't matter
4059 kwargs={ "clear": True } )
4060 threads.append( t )
4061 t.start()
4062 for t in threads:
4063 t.join()
4064 clearResponses.append( t.result )
4065
4066 # main.TRUE = successfully changed the set
4067 # main.FALSE = action resulted in no change in set
4068 # main.ERROR - Some error in executing the function
4069 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004070 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004071 if clearResponses[ i ] == main.TRUE:
4072 # All is well
4073 pass
4074 elif clearResponses[ i ] == main.FALSE:
4075 # Nothing set, probably fine
4076 pass
4077 elif clearResponses[ i ] == main.ERROR:
4078 # Error in execution
4079 clearResults = main.FALSE
4080 else:
4081 # unexpected result
4082 clearResults = main.FALSE
4083 if clearResults != main.TRUE:
4084 main.log.error( "Error executing set clear" )
4085
4086 # Check if set is still correct
4087 size = len( onosSet )
4088 getResponses = []
4089 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004090 for i in range( main.numCtrls ):
4091 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004092 name="setTestGet-" + str( i ),
4093 args=[ onosSetName ] )
4094 threads.append( t )
4095 t.start()
4096 for t in threads:
4097 t.join()
4098 getResponses.append( t.result )
4099 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004100 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004101 if isinstance( getResponses[ i ], list):
4102 current = set( getResponses[ i ] )
4103 if len( current ) == len( getResponses[ i ] ):
4104 # no repeats
4105 if onosSet != current:
4106 main.log.error( "ONOS" + str( i + 1 ) +
4107 " has incorrect view" +
4108 " of set " + onosSetName + ":\n" +
4109 str( getResponses[ i ] ) )
4110 main.log.debug( "Expected: " + str( onosSet ) )
4111 main.log.debug( "Actual: " + str( current ) )
4112 getResults = main.FALSE
4113 else:
4114 # error, set is not a set
4115 main.log.error( "ONOS" + str( i + 1 ) +
4116 " has repeat elements in" +
4117 " set " + onosSetName + ":\n" +
4118 str( getResponses[ i ] ) )
4119 getResults = main.FALSE
4120 elif getResponses[ i ] == main.ERROR:
4121 getResults = main.FALSE
4122 sizeResponses = []
4123 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004124 for i in range( main.numCtrls ):
4125 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004126 name="setTestSize-" + str( i ),
4127 args=[ onosSetName ] )
4128 threads.append( t )
4129 t.start()
4130 for t in threads:
4131 t.join()
4132 sizeResponses.append( t.result )
4133 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004134 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004135 if size != sizeResponses[ i ]:
4136 sizeResults = main.FALSE
4137 main.log.error( "ONOS" + str( i + 1 ) +
4138 " expected a size of " + str( size ) +
4139 " for set " + onosSetName +
4140 " but got " + str( sizeResponses[ i ] ) )
4141 clearResults = clearResults and getResults and sizeResults
4142 utilities.assert_equals( expect=main.TRUE,
4143 actual=clearResults,
4144 onpass="Set clear correct",
4145 onfail="Set clear was incorrect" )
4146
4147 main.step( "Distributed Set addAll()" )
4148 onosSet.update( addAllValue.split() )
4149 addResponses = []
4150 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004151 for i in range( main.numCtrls ):
4152 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004153 name="setTestAddAll-" + str( i ),
4154 args=[ onosSetName, addAllValue ] )
4155 threads.append( t )
4156 t.start()
4157 for t in threads:
4158 t.join()
4159 addResponses.append( t.result )
4160
4161 # main.TRUE = successfully changed the set
4162 # main.FALSE = action resulted in no change in set
4163 # main.ERROR - Some error in executing the function
4164 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004165 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004166 if addResponses[ i ] == main.TRUE:
4167 # All is well
4168 pass
4169 elif addResponses[ i ] == main.FALSE:
4170 # Already in set, probably fine
4171 pass
4172 elif addResponses[ i ] == main.ERROR:
4173 # Error in execution
4174 addAllResults = main.FALSE
4175 else:
4176 # unexpected result
4177 addAllResults = main.FALSE
4178 if addAllResults != main.TRUE:
4179 main.log.error( "Error executing set addAll" )
4180
4181 # Check if set is still correct
4182 size = len( onosSet )
4183 getResponses = []
4184 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004185 for i in range( main.numCtrls ):
4186 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004187 name="setTestGet-" + str( i ),
4188 args=[ onosSetName ] )
4189 threads.append( t )
4190 t.start()
4191 for t in threads:
4192 t.join()
4193 getResponses.append( t.result )
4194 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004195 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004196 if isinstance( getResponses[ i ], list):
4197 current = set( getResponses[ i ] )
4198 if len( current ) == len( getResponses[ i ] ):
4199 # no repeats
4200 if onosSet != current:
4201 main.log.error( "ONOS" + str( i + 1 ) +
4202 " has incorrect view" +
4203 " of set " + onosSetName + ":\n" +
4204 str( getResponses[ i ] ) )
4205 main.log.debug( "Expected: " + str( onosSet ) )
4206 main.log.debug( "Actual: " + str( current ) )
4207 getResults = main.FALSE
4208 else:
4209 # error, set is not a set
4210 main.log.error( "ONOS" + str( i + 1 ) +
4211 " has repeat elements in" +
4212 " set " + onosSetName + ":\n" +
4213 str( getResponses[ i ] ) )
4214 getResults = main.FALSE
4215 elif getResponses[ i ] == main.ERROR:
4216 getResults = main.FALSE
4217 sizeResponses = []
4218 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004219 for i in range( main.numCtrls ):
4220 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004221 name="setTestSize-" + str( i ),
4222 args=[ onosSetName ] )
4223 threads.append( t )
4224 t.start()
4225 for t in threads:
4226 t.join()
4227 sizeResponses.append( t.result )
4228 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004229 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004230 if size != sizeResponses[ i ]:
4231 sizeResults = main.FALSE
4232 main.log.error( "ONOS" + str( i + 1 ) +
4233 " expected a size of " + str( size ) +
4234 " for set " + onosSetName +
4235 " but got " + str( sizeResponses[ i ] ) )
4236 addAllResults = addAllResults and getResults and sizeResults
4237 utilities.assert_equals( expect=main.TRUE,
4238 actual=addAllResults,
4239 onpass="Set addAll correct",
4240 onfail="Set addAll was incorrect" )
4241
4242 main.step( "Distributed Set retain()" )
4243 onosSet.intersection_update( retainValue.split() )
4244 retainResponses = []
4245 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004246 for i in range( main.numCtrls ):
4247 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004248 name="setTestRetain-" + str( i ),
4249 args=[ onosSetName, retainValue ],
4250 kwargs={ "retain": True } )
4251 threads.append( t )
4252 t.start()
4253 for t in threads:
4254 t.join()
4255 retainResponses.append( t.result )
4256
4257 # main.TRUE = successfully changed the set
4258 # main.FALSE = action resulted in no change in set
4259 # main.ERROR - Some error in executing the function
4260 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004261 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004262 if retainResponses[ i ] == main.TRUE:
4263 # All is well
4264 pass
4265 elif retainResponses[ i ] == main.FALSE:
4266 # Already in set, probably fine
4267 pass
4268 elif retainResponses[ i ] == main.ERROR:
4269 # Error in execution
4270 retainResults = main.FALSE
4271 else:
4272 # unexpected result
4273 retainResults = main.FALSE
4274 if retainResults != main.TRUE:
4275 main.log.error( "Error executing set retain" )
4276
4277 # Check if set is still correct
4278 size = len( onosSet )
4279 getResponses = []
4280 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004281 for i in range( main.numCtrls ):
4282 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004283 name="setTestGet-" + str( i ),
4284 args=[ onosSetName ] )
4285 threads.append( t )
4286 t.start()
4287 for t in threads:
4288 t.join()
4289 getResponses.append( t.result )
4290 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004291 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004292 if isinstance( getResponses[ i ], list):
4293 current = set( getResponses[ i ] )
4294 if len( current ) == len( getResponses[ i ] ):
4295 # no repeats
4296 if onosSet != current:
4297 main.log.error( "ONOS" + str( i + 1 ) +
4298 " has incorrect view" +
4299 " of set " + onosSetName + ":\n" +
4300 str( getResponses[ i ] ) )
4301 main.log.debug( "Expected: " + str( onosSet ) )
4302 main.log.debug( "Actual: " + str( current ) )
4303 getResults = main.FALSE
4304 else:
4305 # error, set is not a set
4306 main.log.error( "ONOS" + str( i + 1 ) +
4307 " has repeat elements in" +
4308 " set " + onosSetName + ":\n" +
4309 str( getResponses[ i ] ) )
4310 getResults = main.FALSE
4311 elif getResponses[ i ] == main.ERROR:
4312 getResults = main.FALSE
4313 sizeResponses = []
4314 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004315 for i in range( main.numCtrls ):
4316 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004317 name="setTestSize-" + str( i ),
4318 args=[ onosSetName ] )
4319 threads.append( t )
4320 t.start()
4321 for t in threads:
4322 t.join()
4323 sizeResponses.append( t.result )
4324 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004325 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004326 if size != sizeResponses[ i ]:
4327 sizeResults = main.FALSE
4328 main.log.error( "ONOS" + str( i + 1 ) +
4329 " expected a size of " +
4330 str( size ) + " for set " + onosSetName +
4331 " but got " + str( sizeResponses[ i ] ) )
4332 retainResults = retainResults and getResults and sizeResults
4333 utilities.assert_equals( expect=main.TRUE,
4334 actual=retainResults,
4335 onpass="Set retain correct",
4336 onfail="Set retain was incorrect" )
4337
Jon Hall2a5002c2015-08-21 16:49:11 -07004338 # Transactional maps
4339 main.step( "Partitioned Transactional maps put" )
4340 tMapValue = "Testing"
4341 numKeys = 100
4342 putResult = True
4343 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4344 if len( putResponses ) == 100:
4345 for i in putResponses:
4346 if putResponses[ i ][ 'value' ] != tMapValue:
4347 putResult = False
4348 else:
4349 putResult = False
4350 if not putResult:
4351 main.log.debug( "Put response values: " + str( putResponses ) )
4352 utilities.assert_equals( expect=True,
4353 actual=putResult,
4354 onpass="Partitioned Transactional Map put successful",
4355 onfail="Partitioned Transactional Map put values are incorrect" )
4356
4357 main.step( "Partitioned Transactional maps get" )
4358 getCheck = True
4359 for n in range( 1, numKeys + 1 ):
4360 getResponses = []
4361 threads = []
4362 valueCheck = True
4363 for i in range( main.numCtrls ):
4364 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4365 name="TMap-get-" + str( i ),
4366 args=[ "Key" + str ( n ) ] )
4367 threads.append( t )
4368 t.start()
4369 for t in threads:
4370 t.join()
4371 getResponses.append( t.result )
4372 for node in getResponses:
4373 if node != tMapValue:
4374 valueCheck = False
4375 if not valueCheck:
4376 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4377 main.log.warn( getResponses )
4378 getCheck = getCheck and valueCheck
4379 utilities.assert_equals( expect=True,
4380 actual=getCheck,
4381 onpass="Partitioned Transactional Map get values were correct",
4382 onfail="Partitioned Transactional Map values incorrect" )
4383
4384 main.step( "In-memory Transactional maps put" )
4385 tMapValue = "Testing"
4386 numKeys = 100
4387 putResult = True
4388 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4389 if len( putResponses ) == 100:
4390 for i in putResponses:
4391 if putResponses[ i ][ 'value' ] != tMapValue:
4392 putResult = False
4393 else:
4394 putResult = False
4395 if not putResult:
4396 main.log.debug( "Put response values: " + str( putResponses ) )
4397 utilities.assert_equals( expect=True,
4398 actual=putResult,
4399 onpass="In-Memory Transactional Map put successful",
4400 onfail="In-Memory Transactional Map put values are incorrect" )
4401
4402 main.step( "In-Memory Transactional maps get" )
4403 getCheck = True
4404 for n in range( 1, numKeys + 1 ):
4405 getResponses = []
4406 threads = []
4407 valueCheck = True
4408 for i in range( main.numCtrls ):
4409 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4410 name="TMap-get-" + str( i ),
4411 args=[ "Key" + str ( n ) ],
4412 kwargs={ "inMemory": True } )
4413 threads.append( t )
4414 t.start()
4415 for t in threads:
4416 t.join()
4417 getResponses.append( t.result )
4418 for node in getResponses:
4419 if node != tMapValue:
4420 valueCheck = False
4421 if not valueCheck:
4422 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4423 main.log.warn( getResponses )
4424 getCheck = getCheck and valueCheck
4425 utilities.assert_equals( expect=True,
4426 actual=getCheck,
4427 onpass="In-Memory Transactional Map get values were correct",
4428 onfail="In-Memory Transactional Map values incorrect" )