blob: 859d58216063cc58824d2fe826aa3e36b3d0ba7a [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if the HA test setup is
3 working correctly. There are no failures so this test should
4 have a 100% pass rate
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
8CASE2: Assign devices to controllers
9CASE21: Assign mastership to controllers
10CASE3: Assign intents
11CASE4: Ping across added host intents
12CASE5: Reading state of ONOS
13CASE6: The Failure case. Since this is the Sanity test, we do nothing.
14CASE7: Check state after control plane failure
15CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
21CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
23CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
25"""
26
27
28class HAsanity:
29
30 def __init__( self ):
31 self.default = ''
32
33 def CASE1( self, main ):
34 """
35 CASE1 is to compile ONOS and push it to the test machines
36
37 Startup sequence:
38 cell <name>
39 onos-verify-cell
40 NOTE: temporary - onos-remove-raft-logs
41 onos-uninstall
42 start mininet
43 git pull
44 mvn clean install
45 onos-package
46 onos-install -f
47 onos-wait-for-start
48 start cli sessions
49 start tcpdump
50 """
Jon Halle1a3b752015-07-22 13:02:46 -070051 import imp
Jon Hall5cf14d52015-07-16 12:15:19 -070052 main.log.info( "ONOS HA Sanity test - 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 )
Jon Hall5cf14d52015-07-16 12:15:19 -070070 # TODO: refactor how to get onos port, maybe put into component tag?
Jon Halle1a3b752015-07-22 13:02:46 -070071 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79
80 # FIXME: just get controller port from params?
81 # TODO: do we really need all these?
82 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
83 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
84 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
85 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
86 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
87 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
88 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
89
Jon Halle1a3b752015-07-22 13:02:46 -070090 try:
91 fileName = "Counters"
92 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 = "HAsanity"
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
Jon Hall96091e62015-09-21 17:34:17 -0700497 passMsg = "Reactive Pingall test passed"
498 time1 = time.time()
499 pingResult = main.Mininet1.pingall()
500 time2 = time.time()
501 if not pingResult:
502 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700503 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700504 passMsg += " on the second try"
505 utilities.assert_equals(
506 expect=main.TRUE,
507 actual=pingResult,
508 onpass= passMsg,
509 onfail="Reactive Pingall failed, " +
510 "one or more ping pairs failed" )
511 main.log.info( "Time for pingall: %2f seconds" %
512 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700513 # timeout for fwd flows
514 time.sleep( 11 )
515 # uninstall onos-app-fwd
516 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700517 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700518 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
519 onpass="Uninstall fwd successful",
520 onfail="Uninstall fwd failed" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700521
522 main.step( "Check app ids" )
523 threads = []
524 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700525 for i in range( main.numCtrls ):
526 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700527 name="appToIDCheck-" + str( i ),
528 args=[] )
529 threads.append( t )
530 t.start()
531
532 for t in threads:
533 t.join()
534 appCheck2 = appCheck2 and t.result
535 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700536 main.log.warn( main.CLIs[0].apps() )
537 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700538 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
539 onpass="App Ids seem to be correct",
540 onfail="Something is wrong with app Ids" )
541
542 main.step( "Add host intents via cli" )
543 intentIds = []
544 # TODO: move the host numbers to params
545 # Maybe look at all the paths we ping?
546 intentAddResult = True
547 hostResult = main.TRUE
548 for i in range( 8, 18 ):
549 main.log.info( "Adding host intent between h" + str( i ) +
550 " and h" + str( i + 10 ) )
551 host1 = "00:00:00:00:00:" + \
552 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
553 host2 = "00:00:00:00:00:" + \
554 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
555 # NOTE: getHost can return None
556 host1Dict = main.ONOScli1.getHost( host1 )
557 host2Dict = main.ONOScli1.getHost( host2 )
558 host1Id = None
559 host2Id = None
560 if host1Dict and host2Dict:
561 host1Id = host1Dict.get( 'id', None )
562 host2Id = host2Dict.get( 'id', None )
563 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700564 nodeNum = ( i % main.numCtrls )
565 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700566 if tmpId:
567 main.log.info( "Added intent with id: " + tmpId )
568 intentIds.append( tmpId )
569 else:
570 main.log.error( "addHostIntent returned: " +
571 repr( tmpId ) )
572 else:
573 main.log.error( "Error, getHost() failed for h" + str( i ) +
574 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700575 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700576 main.log.warn( "Hosts output: " )
577 try:
578 main.log.warn( json.dumps( json.loads( hosts ),
579 sort_keys=True,
580 indent=4,
581 separators=( ',', ': ' ) ) )
582 except ( ValueError, TypeError ):
583 main.log.warn( repr( hosts ) )
584 hostResult = main.FALSE
585 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
586 onpass="Found a host id for each host",
587 onfail="Error looking up host ids" )
588
589 intentStart = time.time()
590 onosIds = main.ONOScli1.getAllIntentsId()
591 main.log.info( "Submitted intents: " + str( intentIds ) )
592 main.log.info( "Intents in ONOS: " + str( onosIds ) )
593 for intent in intentIds:
594 if intent in onosIds:
595 pass # intent submitted is in onos
596 else:
597 intentAddResult = False
598 if intentAddResult:
599 intentStop = time.time()
600 else:
601 intentStop = None
602 # Print the intent states
603 intents = main.ONOScli1.intents()
604 intentStates = []
605 installedCheck = True
606 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
607 count = 0
608 try:
609 for intent in json.loads( intents ):
610 state = intent.get( 'state', None )
611 if "INSTALLED" not in state:
612 installedCheck = False
613 intentId = intent.get( 'id', None )
614 intentStates.append( ( intentId, state ) )
615 except ( ValueError, TypeError ):
616 main.log.exception( "Error parsing intents" )
617 # add submitted intents not in the store
618 tmplist = [ i for i, s in intentStates ]
619 missingIntents = False
620 for i in intentIds:
621 if i not in tmplist:
622 intentStates.append( ( i, " - " ) )
623 missingIntents = True
624 intentStates.sort()
625 for i, s in intentStates:
626 count += 1
627 main.log.info( "%-6s%-15s%-15s" %
628 ( str( count ), str( i ), str( s ) ) )
629 leaders = main.ONOScli1.leaders()
630 try:
631 missing = False
632 if leaders:
633 parsedLeaders = json.loads( leaders )
634 main.log.warn( json.dumps( parsedLeaders,
635 sort_keys=True,
636 indent=4,
637 separators=( ',', ': ' ) ) )
638 # check for all intent partitions
639 topics = []
640 for i in range( 14 ):
641 topics.append( "intent-partition-" + str( i ) )
642 main.log.debug( topics )
643 ONOStopics = [ j['topic'] for j in parsedLeaders ]
644 for topic in topics:
645 if topic not in ONOStopics:
646 main.log.error( "Error: " + topic +
647 " not in leaders" )
648 missing = True
649 else:
650 main.log.error( "leaders() returned None" )
651 except ( ValueError, TypeError ):
652 main.log.exception( "Error parsing leaders" )
653 main.log.error( repr( leaders ) )
654 # Check all nodes
655 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700656 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700657 response = node.leaders( jsonFormat=False)
658 main.log.warn( str( node.name ) + " leaders output: \n" +
659 str( response ) )
660
661 partitions = main.ONOScli1.partitions()
662 try:
663 if partitions :
664 parsedPartitions = json.loads( partitions )
665 main.log.warn( json.dumps( parsedPartitions,
666 sort_keys=True,
667 indent=4,
668 separators=( ',', ': ' ) ) )
669 # TODO check for a leader in all paritions
670 # TODO check for consistency among nodes
671 else:
672 main.log.error( "partitions() returned None" )
673 except ( ValueError, TypeError ):
674 main.log.exception( "Error parsing partitions" )
675 main.log.error( repr( partitions ) )
676 pendingMap = main.ONOScli1.pendingMap()
677 try:
678 if pendingMap :
679 parsedPending = json.loads( pendingMap )
680 main.log.warn( json.dumps( parsedPending,
681 sort_keys=True,
682 indent=4,
683 separators=( ',', ': ' ) ) )
684 # TODO check something here?
685 else:
686 main.log.error( "pendingMap() returned None" )
687 except ( ValueError, TypeError ):
688 main.log.exception( "Error parsing pending map" )
689 main.log.error( repr( pendingMap ) )
690
691 intentAddResult = bool( intentAddResult and not missingIntents and
692 installedCheck )
693 if not intentAddResult:
694 main.log.error( "Error in pushing host intents to ONOS" )
695
696 main.step( "Intent Anti-Entropy dispersion" )
697 for i in range(100):
698 correct = True
699 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700700 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700701 onosIds = []
702 ids = cli.getAllIntentsId()
703 onosIds.append( ids )
704 main.log.debug( "Intents in " + cli.name + ": " +
705 str( sorted( onosIds ) ) )
706 if sorted( ids ) != sorted( intentIds ):
707 main.log.warn( "Set of intent IDs doesn't match" )
708 correct = False
709 break
710 else:
711 intents = json.loads( cli.intents() )
712 for intent in intents:
713 if intent[ 'state' ] != "INSTALLED":
714 main.log.warn( "Intent " + intent[ 'id' ] +
715 " is " + intent[ 'state' ] )
716 correct = False
717 break
718 if correct:
719 break
720 else:
721 time.sleep(1)
722 if not intentStop:
723 intentStop = time.time()
724 global gossipTime
725 gossipTime = intentStop - intentStart
726 main.log.info( "It took about " + str( gossipTime ) +
727 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700728 gossipPeriod = int( main.params['timers']['gossip'] )
729 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700730 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700731 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700732 onpass="ECM anti-entropy for intents worked within " +
733 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700734 onfail="Intent ECM anti-entropy took too long. " +
735 "Expected time:{}, Actual time:{}".format( maxGossipTime,
736 gossipTime ) )
737 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700738 intentAddResult = True
739
740 if not intentAddResult or "key" in pendingMap:
741 import time
742 installedCheck = True
743 main.log.info( "Sleeping 60 seconds to see if intents are found" )
744 time.sleep( 60 )
745 onosIds = main.ONOScli1.getAllIntentsId()
746 main.log.info( "Submitted intents: " + str( intentIds ) )
747 main.log.info( "Intents in ONOS: " + str( onosIds ) )
748 # Print the intent states
749 intents = main.ONOScli1.intents()
750 intentStates = []
751 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
752 count = 0
753 try:
754 for intent in json.loads( intents ):
755 # Iter through intents of a node
756 state = intent.get( 'state', None )
757 if "INSTALLED" not in state:
758 installedCheck = False
759 intentId = intent.get( 'id', None )
760 intentStates.append( ( intentId, state ) )
761 except ( ValueError, TypeError ):
762 main.log.exception( "Error parsing intents" )
763 # add submitted intents not in the store
764 tmplist = [ i for i, s in intentStates ]
765 for i in intentIds:
766 if i not in tmplist:
767 intentStates.append( ( i, " - " ) )
768 intentStates.sort()
769 for i, s in intentStates:
770 count += 1
771 main.log.info( "%-6s%-15s%-15s" %
772 ( str( count ), str( i ), str( s ) ) )
773 leaders = main.ONOScli1.leaders()
774 try:
775 missing = False
776 if leaders:
777 parsedLeaders = json.loads( leaders )
778 main.log.warn( json.dumps( parsedLeaders,
779 sort_keys=True,
780 indent=4,
781 separators=( ',', ': ' ) ) )
782 # check for all intent partitions
783 # check for election
784 topics = []
785 for i in range( 14 ):
786 topics.append( "intent-partition-" + str( i ) )
787 # FIXME: this should only be after we start the app
788 topics.append( "org.onosproject.election" )
789 main.log.debug( topics )
790 ONOStopics = [ j['topic'] for j in parsedLeaders ]
791 for topic in topics:
792 if topic not in ONOStopics:
793 main.log.error( "Error: " + topic +
794 " not in leaders" )
795 missing = True
796 else:
797 main.log.error( "leaders() returned None" )
798 except ( ValueError, TypeError ):
799 main.log.exception( "Error parsing leaders" )
800 main.log.error( repr( leaders ) )
801 # Check all nodes
802 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700803 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700804 response = node.leaders( jsonFormat=False)
805 main.log.warn( str( node.name ) + " leaders output: \n" +
806 str( response ) )
807
808 partitions = main.ONOScli1.partitions()
809 try:
810 if partitions :
811 parsedPartitions = json.loads( partitions )
812 main.log.warn( json.dumps( parsedPartitions,
813 sort_keys=True,
814 indent=4,
815 separators=( ',', ': ' ) ) )
816 # TODO check for a leader in all paritions
817 # TODO check for consistency among nodes
818 else:
819 main.log.error( "partitions() returned None" )
820 except ( ValueError, TypeError ):
821 main.log.exception( "Error parsing partitions" )
822 main.log.error( repr( partitions ) )
823 pendingMap = main.ONOScli1.pendingMap()
824 try:
825 if pendingMap :
826 parsedPending = json.loads( pendingMap )
827 main.log.warn( json.dumps( parsedPending,
828 sort_keys=True,
829 indent=4,
830 separators=( ',', ': ' ) ) )
831 # TODO check something here?
832 else:
833 main.log.error( "pendingMap() returned None" )
834 except ( ValueError, TypeError ):
835 main.log.exception( "Error parsing pending map" )
836 main.log.error( repr( pendingMap ) )
837
838 def CASE4( self, main ):
839 """
840 Ping across added host intents
841 """
842 import json
843 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700844 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700845 assert main, "main not defined"
846 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700847 assert main.CLIs, "main.CLIs not defined"
848 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700849 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700850 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700851 "functionality and check the state of " +\
852 "the intent"
853 main.step( "Ping across added host intents" )
854 PingResult = main.TRUE
855 for i in range( 8, 18 ):
856 ping = main.Mininet1.pingHost( src="h" + str( i ),
857 target="h" + str( i + 10 ) )
858 PingResult = PingResult and ping
859 if ping == main.FALSE:
860 main.log.warn( "Ping failed between h" + str( i ) +
861 " and h" + str( i + 10 ) )
862 elif ping == main.TRUE:
863 main.log.info( "Ping test passed!" )
864 # Don't set PingResult or you'd override failures
865 if PingResult == main.FALSE:
866 main.log.error(
867 "Intents have not been installed correctly, pings failed." )
868 # TODO: pretty print
869 main.log.warn( "ONOS1 intents: " )
870 try:
871 tmpIntents = main.ONOScli1.intents()
872 main.log.warn( json.dumps( json.loads( tmpIntents ),
873 sort_keys=True,
874 indent=4,
875 separators=( ',', ': ' ) ) )
876 except ( ValueError, TypeError ):
877 main.log.warn( repr( tmpIntents ) )
878 utilities.assert_equals(
879 expect=main.TRUE,
880 actual=PingResult,
881 onpass="Intents have been installed correctly and pings work",
882 onfail="Intents have not been installed correctly, pings failed." )
883
884 main.step( "Check Intent state" )
885 installedCheck = False
886 loopCount = 0
887 while not installedCheck and loopCount < 40:
888 installedCheck = True
889 # Print the intent states
890 intents = main.ONOScli1.intents()
891 intentStates = []
892 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
893 count = 0
894 # Iter through intents of a node
895 try:
896 for intent in json.loads( intents ):
897 state = intent.get( 'state', None )
898 if "INSTALLED" not in state:
899 installedCheck = False
900 intentId = intent.get( 'id', None )
901 intentStates.append( ( intentId, state ) )
902 except ( ValueError, TypeError ):
903 main.log.exception( "Error parsing intents." )
904 # Print states
905 intentStates.sort()
906 for i, s in intentStates:
907 count += 1
908 main.log.info( "%-6s%-15s%-15s" %
909 ( str( count ), str( i ), str( s ) ) )
910 if not installedCheck:
911 time.sleep( 1 )
912 loopCount += 1
913 utilities.assert_equals( expect=True, actual=installedCheck,
914 onpass="Intents are all INSTALLED",
915 onfail="Intents are not all in " +
916 "INSTALLED state" )
917
918 main.step( "Check leadership of topics" )
919 leaders = main.ONOScli1.leaders()
920 topicCheck = main.TRUE
921 try:
922 if leaders:
923 parsedLeaders = json.loads( leaders )
924 main.log.warn( json.dumps( parsedLeaders,
925 sort_keys=True,
926 indent=4,
927 separators=( ',', ': ' ) ) )
928 # check for all intent partitions
929 # check for election
930 # TODO: Look at Devices as topics now that it uses this system
931 topics = []
932 for i in range( 14 ):
933 topics.append( "intent-partition-" + str( i ) )
934 # FIXME: this should only be after we start the app
935 # FIXME: topics.append( "org.onosproject.election" )
936 # Print leaders output
937 main.log.debug( topics )
938 ONOStopics = [ j['topic'] for j in parsedLeaders ]
939 for topic in topics:
940 if topic not in ONOStopics:
941 main.log.error( "Error: " + topic +
942 " not in leaders" )
943 topicCheck = main.FALSE
944 else:
945 main.log.error( "leaders() returned None" )
946 topicCheck = main.FALSE
947 except ( ValueError, TypeError ):
948 topicCheck = main.FALSE
949 main.log.exception( "Error parsing leaders" )
950 main.log.error( repr( leaders ) )
951 # TODO: Check for a leader of these topics
952 # Check all nodes
953 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700954 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700955 response = node.leaders( jsonFormat=False)
956 main.log.warn( str( node.name ) + " leaders output: \n" +
957 str( response ) )
958
959 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
960 onpass="intent Partitions is in leaders",
961 onfail="Some topics were lost " )
962 # Print partitions
963 partitions = main.ONOScli1.partitions()
964 try:
965 if partitions :
966 parsedPartitions = json.loads( partitions )
967 main.log.warn( json.dumps( parsedPartitions,
968 sort_keys=True,
969 indent=4,
970 separators=( ',', ': ' ) ) )
971 # TODO check for a leader in all paritions
972 # TODO check for consistency among nodes
973 else:
974 main.log.error( "partitions() returned None" )
975 except ( ValueError, TypeError ):
976 main.log.exception( "Error parsing partitions" )
977 main.log.error( repr( partitions ) )
978 # Print Pending Map
979 pendingMap = main.ONOScli1.pendingMap()
980 try:
981 if pendingMap :
982 parsedPending = json.loads( pendingMap )
983 main.log.warn( json.dumps( parsedPending,
984 sort_keys=True,
985 indent=4,
986 separators=( ',', ': ' ) ) )
987 # TODO check something here?
988 else:
989 main.log.error( "pendingMap() returned None" )
990 except ( ValueError, TypeError ):
991 main.log.exception( "Error parsing pending map" )
992 main.log.error( repr( pendingMap ) )
993
994 if not installedCheck:
995 main.log.info( "Waiting 60 seconds to see if the state of " +
996 "intents change" )
997 time.sleep( 60 )
998 # Print the intent states
999 intents = main.ONOScli1.intents()
1000 intentStates = []
1001 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1002 count = 0
1003 # Iter through intents of a node
1004 try:
1005 for intent in json.loads( intents ):
1006 state = intent.get( 'state', None )
1007 if "INSTALLED" not in state:
1008 installedCheck = False
1009 intentId = intent.get( 'id', None )
1010 intentStates.append( ( intentId, state ) )
1011 except ( ValueError, TypeError ):
1012 main.log.exception( "Error parsing intents." )
1013 intentStates.sort()
1014 for i, s in intentStates:
1015 count += 1
1016 main.log.info( "%-6s%-15s%-15s" %
1017 ( str( count ), str( i ), str( s ) ) )
1018 leaders = main.ONOScli1.leaders()
1019 try:
1020 missing = False
1021 if leaders:
1022 parsedLeaders = json.loads( leaders )
1023 main.log.warn( json.dumps( parsedLeaders,
1024 sort_keys=True,
1025 indent=4,
1026 separators=( ',', ': ' ) ) )
1027 # check for all intent partitions
1028 # check for election
1029 topics = []
1030 for i in range( 14 ):
1031 topics.append( "intent-partition-" + str( i ) )
1032 # FIXME: this should only be after we start the app
1033 topics.append( "org.onosproject.election" )
1034 main.log.debug( topics )
1035 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1036 for topic in topics:
1037 if topic not in ONOStopics:
1038 main.log.error( "Error: " + topic +
1039 " not in leaders" )
1040 missing = True
1041 else:
1042 main.log.error( "leaders() returned None" )
1043 except ( ValueError, TypeError ):
1044 main.log.exception( "Error parsing leaders" )
1045 main.log.error( repr( leaders ) )
1046 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001047 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001048 response = node.leaders( jsonFormat=False)
1049 main.log.warn( str( node.name ) + " leaders output: \n" +
1050 str( response ) )
1051
1052 partitions = main.ONOScli1.partitions()
1053 try:
1054 if partitions :
1055 parsedPartitions = json.loads( partitions )
1056 main.log.warn( json.dumps( parsedPartitions,
1057 sort_keys=True,
1058 indent=4,
1059 separators=( ',', ': ' ) ) )
1060 # TODO check for a leader in all paritions
1061 # TODO check for consistency among nodes
1062 else:
1063 main.log.error( "partitions() returned None" )
1064 except ( ValueError, TypeError ):
1065 main.log.exception( "Error parsing partitions" )
1066 main.log.error( repr( partitions ) )
1067 pendingMap = main.ONOScli1.pendingMap()
1068 try:
1069 if pendingMap :
1070 parsedPending = json.loads( pendingMap )
1071 main.log.warn( json.dumps( parsedPending,
1072 sort_keys=True,
1073 indent=4,
1074 separators=( ',', ': ' ) ) )
1075 # TODO check something here?
1076 else:
1077 main.log.error( "pendingMap() returned None" )
1078 except ( ValueError, TypeError ):
1079 main.log.exception( "Error parsing pending map" )
1080 main.log.error( repr( pendingMap ) )
1081 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001082 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001083 main.step( "Wait a minute then ping again" )
1084 # the wait is above
1085 PingResult = main.TRUE
1086 for i in range( 8, 18 ):
1087 ping = main.Mininet1.pingHost( src="h" + str( i ),
1088 target="h" + str( i + 10 ) )
1089 PingResult = PingResult and ping
1090 if ping == main.FALSE:
1091 main.log.warn( "Ping failed between h" + str( i ) +
1092 " and h" + str( i + 10 ) )
1093 elif ping == main.TRUE:
1094 main.log.info( "Ping test passed!" )
1095 # Don't set PingResult or you'd override failures
1096 if PingResult == main.FALSE:
1097 main.log.error(
1098 "Intents have not been installed correctly, pings failed." )
1099 # TODO: pretty print
1100 main.log.warn( "ONOS1 intents: " )
1101 try:
1102 tmpIntents = main.ONOScli1.intents()
1103 main.log.warn( json.dumps( json.loads( tmpIntents ),
1104 sort_keys=True,
1105 indent=4,
1106 separators=( ',', ': ' ) ) )
1107 except ( ValueError, TypeError ):
1108 main.log.warn( repr( tmpIntents ) )
1109 utilities.assert_equals(
1110 expect=main.TRUE,
1111 actual=PingResult,
1112 onpass="Intents have been installed correctly and pings work",
1113 onfail="Intents have not been installed correctly, pings failed." )
1114
1115 def CASE5( self, main ):
1116 """
1117 Reading state of ONOS
1118 """
1119 import json
1120 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001121 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001122 assert main, "main not defined"
1123 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001124 assert main.CLIs, "main.CLIs not defined"
1125 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001126
1127 main.case( "Setting up and gathering data for current state" )
1128 # The general idea for this test case is to pull the state of
1129 # ( intents,flows, topology,... ) from each ONOS node
1130 # We can then compare them with each other and also with past states
1131
1132 main.step( "Check that each switch has a master" )
1133 global mastershipState
1134 mastershipState = '[]'
1135
1136 # Assert that each device has a master
1137 rolesNotNull = main.TRUE
1138 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001139 for i in range( main.numCtrls ):
1140 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001141 name="rolesNotNull-" + str( i ),
1142 args=[] )
1143 threads.append( t )
1144 t.start()
1145
1146 for t in threads:
1147 t.join()
1148 rolesNotNull = rolesNotNull and t.result
1149 utilities.assert_equals(
1150 expect=main.TRUE,
1151 actual=rolesNotNull,
1152 onpass="Each device has a master",
1153 onfail="Some devices don't have a master assigned" )
1154
1155 main.step( "Get the Mastership of each switch from each controller" )
1156 ONOSMastership = []
1157 mastershipCheck = main.FALSE
1158 consistentMastership = True
1159 rolesResults = True
1160 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001161 for i in range( main.numCtrls ):
1162 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001163 name="roles-" + str( i ),
1164 args=[] )
1165 threads.append( t )
1166 t.start()
1167
1168 for t in threads:
1169 t.join()
1170 ONOSMastership.append( t.result )
1171
Jon Halle1a3b752015-07-22 13:02:46 -07001172 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001173 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1174 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1175 " roles" )
1176 main.log.warn(
1177 "ONOS" + str( i + 1 ) + " mastership response: " +
1178 repr( ONOSMastership[i] ) )
1179 rolesResults = False
1180 utilities.assert_equals(
1181 expect=True,
1182 actual=rolesResults,
1183 onpass="No error in reading roles output",
1184 onfail="Error in reading roles from ONOS" )
1185
1186 main.step( "Check for consistency in roles from each controller" )
1187 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1188 main.log.info(
1189 "Switch roles are consistent across all ONOS nodes" )
1190 else:
1191 consistentMastership = False
1192 utilities.assert_equals(
1193 expect=True,
1194 actual=consistentMastership,
1195 onpass="Switch roles are consistent across all ONOS nodes",
1196 onfail="ONOS nodes have different views of switch roles" )
1197
1198 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001199 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001200 try:
1201 main.log.warn(
1202 "ONOS" + str( i + 1 ) + " roles: ",
1203 json.dumps(
1204 json.loads( ONOSMastership[ i ] ),
1205 sort_keys=True,
1206 indent=4,
1207 separators=( ',', ': ' ) ) )
1208 except ( ValueError, TypeError ):
1209 main.log.warn( repr( ONOSMastership[ i ] ) )
1210 elif rolesResults and consistentMastership:
1211 mastershipCheck = main.TRUE
1212 mastershipState = ONOSMastership[ 0 ]
1213
1214 main.step( "Get the intents from each controller" )
1215 global intentState
1216 intentState = []
1217 ONOSIntents = []
1218 intentCheck = main.FALSE
1219 consistentIntents = True
1220 intentsResults = True
1221 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001222 for i in range( main.numCtrls ):
1223 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001224 name="intents-" + str( i ),
1225 args=[],
1226 kwargs={ 'jsonFormat': True } )
1227 threads.append( t )
1228 t.start()
1229
1230 for t in threads:
1231 t.join()
1232 ONOSIntents.append( t.result )
1233
Jon Halle1a3b752015-07-22 13:02:46 -07001234 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001235 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1236 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1237 " intents" )
1238 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1239 repr( ONOSIntents[ i ] ) )
1240 intentsResults = False
1241 utilities.assert_equals(
1242 expect=True,
1243 actual=intentsResults,
1244 onpass="No error in reading intents output",
1245 onfail="Error in reading intents from ONOS" )
1246
1247 main.step( "Check for consistency in Intents from each controller" )
1248 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1249 main.log.info( "Intents are consistent across all ONOS " +
1250 "nodes" )
1251 else:
1252 consistentIntents = False
1253 main.log.error( "Intents not consistent" )
1254 utilities.assert_equals(
1255 expect=True,
1256 actual=consistentIntents,
1257 onpass="Intents are consistent across all ONOS nodes",
1258 onfail="ONOS nodes have different views of intents" )
1259
1260 if intentsResults:
1261 # Try to make it easy to figure out what is happening
1262 #
1263 # Intent ONOS1 ONOS2 ...
1264 # 0x01 INSTALLED INSTALLING
1265 # ... ... ...
1266 # ... ... ...
1267 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001268 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001269 title += " " * 10 + "ONOS" + str( n + 1 )
1270 main.log.warn( title )
Jon Halle1a3b752015-07-22 13:02:46 -07001271 # get all intent keys in the cluster
Jon Hall5cf14d52015-07-16 12:15:19 -07001272 keys = []
1273 try:
1274 # Get the set of all intent keys
1275 for nodeStr in ONOSIntents:
1276 node = json.loads( nodeStr )
1277 for intent in node:
1278 keys.append( intent.get( 'id' ) )
1279 keys = set( keys )
1280 # For each intent key, print the state on each node
1281 for key in keys:
1282 row = "%-13s" % key
1283 for nodeStr in ONOSIntents:
1284 node = json.loads( nodeStr )
1285 for intent in node:
1286 if intent.get( 'id', "Error" ) == key:
1287 row += "%-15s" % intent.get( 'state' )
1288 main.log.warn( row )
1289 # End of intent state table
1290 except ValueError as e:
1291 main.log.exception( e )
1292 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
1293
1294 if intentsResults and not consistentIntents:
1295 # print the json objects
1296 n = len(ONOSIntents)
1297 main.log.debug( "ONOS" + str( n ) + " intents: " )
1298 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1299 sort_keys=True,
1300 indent=4,
1301 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001302 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001303 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1304 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1305 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1306 sort_keys=True,
1307 indent=4,
1308 separators=( ',', ': ' ) ) )
1309 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001310 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001311 str( n ) + " intents" )
1312 elif intentsResults and consistentIntents:
1313 intentCheck = main.TRUE
1314 intentState = ONOSIntents[ 0 ]
1315
1316 main.step( "Get the flows from each controller" )
1317 global flowState
1318 flowState = []
1319 ONOSFlows = []
1320 ONOSFlowsJson = []
1321 flowCheck = main.FALSE
1322 consistentFlows = True
1323 flowsResults = True
1324 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001325 for i in range( main.numCtrls ):
1326 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001327 name="flows-" + str( i ),
1328 args=[],
1329 kwargs={ 'jsonFormat': True } )
1330 threads.append( t )
1331 t.start()
1332
1333 # NOTE: Flows command can take some time to run
1334 time.sleep(30)
1335 for t in threads:
1336 t.join()
1337 result = t.result
1338 ONOSFlows.append( result )
1339
Jon Halle1a3b752015-07-22 13:02:46 -07001340 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001341 num = str( i + 1 )
1342 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1343 main.log.error( "Error in getting ONOS" + num + " flows" )
1344 main.log.warn( "ONOS" + num + " flows response: " +
1345 repr( ONOSFlows[ i ] ) )
1346 flowsResults = False
1347 ONOSFlowsJson.append( None )
1348 else:
1349 try:
1350 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1351 except ( ValueError, TypeError ):
1352 # FIXME: change this to log.error?
1353 main.log.exception( "Error in parsing ONOS" + num +
1354 " response as json." )
1355 main.log.error( repr( ONOSFlows[ i ] ) )
1356 ONOSFlowsJson.append( None )
1357 flowsResults = False
1358 utilities.assert_equals(
1359 expect=True,
1360 actual=flowsResults,
1361 onpass="No error in reading flows output",
1362 onfail="Error in reading flows from ONOS" )
1363
1364 main.step( "Check for consistency in Flows from each controller" )
1365 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1366 if all( tmp ):
1367 main.log.info( "Flow count is consistent across all ONOS nodes" )
1368 else:
1369 consistentFlows = False
1370 utilities.assert_equals(
1371 expect=True,
1372 actual=consistentFlows,
1373 onpass="The flow count is consistent across all ONOS nodes",
1374 onfail="ONOS nodes have different flow counts" )
1375
1376 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001377 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001378 try:
1379 main.log.warn(
1380 "ONOS" + str( i + 1 ) + " flows: " +
1381 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1382 indent=4, separators=( ',', ': ' ) ) )
1383 except ( ValueError, TypeError ):
1384 main.log.warn(
1385 "ONOS" + str( i + 1 ) + " flows: " +
1386 repr( ONOSFlows[ i ] ) )
1387 elif flowsResults and consistentFlows:
1388 flowCheck = main.TRUE
1389 flowState = ONOSFlows[ 0 ]
1390
1391 main.step( "Get the OF Table entries" )
1392 global flows
1393 flows = []
1394 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001395 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001396 if flowCheck == main.FALSE:
1397 for table in flows:
1398 main.log.warn( table )
GlennRC68467eb2015-11-16 18:01:01 -08001399
Jon Hall5cf14d52015-07-16 12:15:19 -07001400 # TODO: Compare switch flow tables with ONOS flow tables
1401
1402 main.step( "Start continuous pings" )
1403 main.Mininet2.pingLong(
1404 src=main.params[ 'PING' ][ 'source1' ],
1405 target=main.params[ 'PING' ][ 'target1' ],
1406 pingTime=500 )
1407 main.Mininet2.pingLong(
1408 src=main.params[ 'PING' ][ 'source2' ],
1409 target=main.params[ 'PING' ][ 'target2' ],
1410 pingTime=500 )
1411 main.Mininet2.pingLong(
1412 src=main.params[ 'PING' ][ 'source3' ],
1413 target=main.params[ 'PING' ][ 'target3' ],
1414 pingTime=500 )
1415 main.Mininet2.pingLong(
1416 src=main.params[ 'PING' ][ 'source4' ],
1417 target=main.params[ 'PING' ][ 'target4' ],
1418 pingTime=500 )
1419 main.Mininet2.pingLong(
1420 src=main.params[ 'PING' ][ 'source5' ],
1421 target=main.params[ 'PING' ][ 'target5' ],
1422 pingTime=500 )
1423 main.Mininet2.pingLong(
1424 src=main.params[ 'PING' ][ 'source6' ],
1425 target=main.params[ 'PING' ][ 'target6' ],
1426 pingTime=500 )
1427 main.Mininet2.pingLong(
1428 src=main.params[ 'PING' ][ 'source7' ],
1429 target=main.params[ 'PING' ][ 'target7' ],
1430 pingTime=500 )
1431 main.Mininet2.pingLong(
1432 src=main.params[ 'PING' ][ 'source8' ],
1433 target=main.params[ 'PING' ][ 'target8' ],
1434 pingTime=500 )
1435 main.Mininet2.pingLong(
1436 src=main.params[ 'PING' ][ 'source9' ],
1437 target=main.params[ 'PING' ][ 'target9' ],
1438 pingTime=500 )
1439 main.Mininet2.pingLong(
1440 src=main.params[ 'PING' ][ 'source10' ],
1441 target=main.params[ 'PING' ][ 'target10' ],
1442 pingTime=500 )
1443
1444 main.step( "Collecting topology information from ONOS" )
1445 devices = []
1446 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001447 for i in range( main.numCtrls ):
1448 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001449 name="devices-" + str( i ),
1450 args=[ ] )
1451 threads.append( t )
1452 t.start()
1453
1454 for t in threads:
1455 t.join()
1456 devices.append( t.result )
1457 hosts = []
1458 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001459 for i in range( main.numCtrls ):
1460 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001461 name="hosts-" + str( i ),
1462 args=[ ] )
1463 threads.append( t )
1464 t.start()
1465
1466 for t in threads:
1467 t.join()
1468 try:
1469 hosts.append( json.loads( t.result ) )
1470 except ( ValueError, TypeError ):
1471 # FIXME: better handling of this, print which node
1472 # Maybe use thread name?
1473 main.log.exception( "Error parsing json output of hosts" )
1474 # FIXME: should this be an empty json object instead?
1475 hosts.append( None )
1476
1477 ports = []
1478 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001479 for i in range( main.numCtrls ):
1480 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001481 name="ports-" + str( i ),
1482 args=[ ] )
1483 threads.append( t )
1484 t.start()
1485
1486 for t in threads:
1487 t.join()
1488 ports.append( t.result )
1489 links = []
1490 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001491 for i in range( main.numCtrls ):
1492 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001493 name="links-" + str( i ),
1494 args=[ ] )
1495 threads.append( t )
1496 t.start()
1497
1498 for t in threads:
1499 t.join()
1500 links.append( t.result )
1501 clusters = []
1502 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001503 for i in range( main.numCtrls ):
1504 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001505 name="clusters-" + str( i ),
1506 args=[ ] )
1507 threads.append( t )
1508 t.start()
1509
1510 for t in threads:
1511 t.join()
1512 clusters.append( t.result )
1513 # Compare json objects for hosts and dataplane clusters
1514
1515 # hosts
1516 main.step( "Host view is consistent across ONOS nodes" )
1517 consistentHostsResult = main.TRUE
1518 for controller in range( len( hosts ) ):
1519 controllerStr = str( controller + 1 )
1520 if "Error" not in hosts[ controller ]:
1521 if hosts[ controller ] == hosts[ 0 ]:
1522 continue
1523 else: # hosts not consistent
1524 main.log.error( "hosts from ONOS" +
1525 controllerStr +
1526 " is inconsistent with ONOS1" )
1527 main.log.warn( repr( hosts[ controller ] ) )
1528 consistentHostsResult = main.FALSE
1529
1530 else:
1531 main.log.error( "Error in getting ONOS hosts from ONOS" +
1532 controllerStr )
1533 consistentHostsResult = main.FALSE
1534 main.log.warn( "ONOS" + controllerStr +
1535 " hosts response: " +
1536 repr( hosts[ controller ] ) )
1537 utilities.assert_equals(
1538 expect=main.TRUE,
1539 actual=consistentHostsResult,
1540 onpass="Hosts view is consistent across all ONOS nodes",
1541 onfail="ONOS nodes have different views of hosts" )
1542
1543 main.step( "Each host has an IP address" )
1544 ipResult = main.TRUE
1545 for controller in range( 0, len( hosts ) ):
1546 controllerStr = str( controller + 1 )
1547 for host in hosts[ controller ]:
1548 if not host.get( 'ipAddresses', [ ] ):
1549 main.log.error( "DEBUG:Error with host ips on controller" +
1550 controllerStr + ": " + str( host ) )
1551 ipResult = main.FALSE
1552 utilities.assert_equals(
1553 expect=main.TRUE,
1554 actual=ipResult,
1555 onpass="The ips of the hosts aren't empty",
1556 onfail="The ip of at least one host is missing" )
1557
1558 # Strongly connected clusters of devices
1559 main.step( "Cluster view is consistent across ONOS nodes" )
1560 consistentClustersResult = main.TRUE
1561 for controller in range( len( clusters ) ):
1562 controllerStr = str( controller + 1 )
1563 if "Error" not in clusters[ controller ]:
1564 if clusters[ controller ] == clusters[ 0 ]:
1565 continue
1566 else: # clusters not consistent
1567 main.log.error( "clusters from ONOS" + controllerStr +
1568 " is inconsistent with ONOS1" )
1569 consistentClustersResult = main.FALSE
1570
1571 else:
1572 main.log.error( "Error in getting dataplane clusters " +
1573 "from ONOS" + controllerStr )
1574 consistentClustersResult = main.FALSE
1575 main.log.warn( "ONOS" + controllerStr +
1576 " clusters response: " +
1577 repr( clusters[ controller ] ) )
1578 utilities.assert_equals(
1579 expect=main.TRUE,
1580 actual=consistentClustersResult,
1581 onpass="Clusters view is consistent across all ONOS nodes",
1582 onfail="ONOS nodes have different views of clusters" )
1583 # there should always only be one cluster
1584 main.step( "Cluster view correct across ONOS nodes" )
1585 try:
1586 numClusters = len( json.loads( clusters[ 0 ] ) )
1587 except ( ValueError, TypeError ):
1588 main.log.exception( "Error parsing clusters[0]: " +
1589 repr( clusters[ 0 ] ) )
1590 clusterResults = main.FALSE
1591 if numClusters == 1:
1592 clusterResults = main.TRUE
1593 utilities.assert_equals(
1594 expect=1,
1595 actual=numClusters,
1596 onpass="ONOS shows 1 SCC",
1597 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1598
1599 main.step( "Comparing ONOS topology to MN" )
1600 devicesResults = main.TRUE
1601 linksResults = main.TRUE
1602 hostsResults = main.TRUE
1603 mnSwitches = main.Mininet1.getSwitches()
1604 mnLinks = main.Mininet1.getLinks()
1605 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001606 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001607 controllerStr = str( controller + 1 )
1608 if devices[ controller ] and ports[ controller ] and\
1609 "Error" not in devices[ controller ] and\
1610 "Error" not in ports[ controller ]:
1611
1612 currentDevicesResult = main.Mininet1.compareSwitches(
1613 mnSwitches,
1614 json.loads( devices[ controller ] ),
1615 json.loads( ports[ controller ] ) )
1616 else:
1617 currentDevicesResult = main.FALSE
1618 utilities.assert_equals( expect=main.TRUE,
1619 actual=currentDevicesResult,
1620 onpass="ONOS" + controllerStr +
1621 " Switches view is correct",
1622 onfail="ONOS" + controllerStr +
1623 " Switches view is incorrect" )
1624 if links[ controller ] and "Error" not in links[ controller ]:
1625 currentLinksResult = main.Mininet1.compareLinks(
1626 mnSwitches, mnLinks,
1627 json.loads( links[ controller ] ) )
1628 else:
1629 currentLinksResult = main.FALSE
1630 utilities.assert_equals( expect=main.TRUE,
1631 actual=currentLinksResult,
1632 onpass="ONOS" + controllerStr +
1633 " links view is correct",
1634 onfail="ONOS" + controllerStr +
1635 " links view is incorrect" )
1636
1637 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1638 currentHostsResult = main.Mininet1.compareHosts(
1639 mnHosts,
1640 hosts[ controller ] )
1641 else:
1642 currentHostsResult = main.FALSE
1643 utilities.assert_equals( expect=main.TRUE,
1644 actual=currentHostsResult,
1645 onpass="ONOS" + controllerStr +
1646 " hosts exist in Mininet",
1647 onfail="ONOS" + controllerStr +
1648 " hosts don't match Mininet" )
1649
1650 devicesResults = devicesResults and currentDevicesResult
1651 linksResults = linksResults and currentLinksResult
1652 hostsResults = hostsResults and currentHostsResult
1653
1654 main.step( "Device information is correct" )
1655 utilities.assert_equals(
1656 expect=main.TRUE,
1657 actual=devicesResults,
1658 onpass="Device information is correct",
1659 onfail="Device information is incorrect" )
1660
1661 main.step( "Links are correct" )
1662 utilities.assert_equals(
1663 expect=main.TRUE,
1664 actual=linksResults,
1665 onpass="Link are correct",
1666 onfail="Links are incorrect" )
1667
1668 main.step( "Hosts are correct" )
1669 utilities.assert_equals(
1670 expect=main.TRUE,
1671 actual=hostsResults,
1672 onpass="Hosts are correct",
1673 onfail="Hosts are incorrect" )
1674
1675 def CASE6( self, main ):
1676 """
1677 The Failure case. Since this is the Sanity test, we do nothing.
1678 """
1679 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001680 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001681 assert main, "main not defined"
1682 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001683 assert main.CLIs, "main.CLIs not defined"
1684 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001685 main.case( "Wait 60 seconds instead of inducing a failure" )
1686 time.sleep( 60 )
1687 utilities.assert_equals(
1688 expect=main.TRUE,
1689 actual=main.TRUE,
1690 onpass="Sleeping 60 seconds",
1691 onfail="Something is terribly wrong with my math" )
1692
1693 def CASE7( self, main ):
1694 """
1695 Check state after ONOS failure
1696 """
1697 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001698 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001699 assert main, "main not defined"
1700 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001701 assert main.CLIs, "main.CLIs not defined"
1702 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001703 main.case( "Running ONOS Constant State Tests" )
1704
1705 main.step( "Check that each switch has a master" )
1706 # Assert that each device has a master
1707 rolesNotNull = main.TRUE
1708 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001709 for i in range( main.numCtrls ):
1710 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001711 name="rolesNotNull-" + str( i ),
1712 args=[ ] )
1713 threads.append( t )
1714 t.start()
1715
1716 for t in threads:
1717 t.join()
1718 rolesNotNull = rolesNotNull and t.result
1719 utilities.assert_equals(
1720 expect=main.TRUE,
1721 actual=rolesNotNull,
1722 onpass="Each device has a master",
1723 onfail="Some devices don't have a master assigned" )
1724
1725 main.step( "Read device roles from ONOS" )
1726 ONOSMastership = []
1727 mastershipCheck = main.FALSE
1728 consistentMastership = True
1729 rolesResults = True
1730 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001731 for i in range( main.numCtrls ):
1732 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001733 name="roles-" + str( i ),
1734 args=[] )
1735 threads.append( t )
1736 t.start()
1737
1738 for t in threads:
1739 t.join()
1740 ONOSMastership.append( t.result )
1741
Jon Halle1a3b752015-07-22 13:02:46 -07001742 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001743 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1744 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1745 " roles" )
1746 main.log.warn(
1747 "ONOS" + str( i + 1 ) + " mastership response: " +
1748 repr( ONOSMastership[i] ) )
1749 rolesResults = False
1750 utilities.assert_equals(
1751 expect=True,
1752 actual=rolesResults,
1753 onpass="No error in reading roles output",
1754 onfail="Error in reading roles from ONOS" )
1755
1756 main.step( "Check for consistency in roles from each controller" )
1757 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1758 main.log.info(
1759 "Switch roles are consistent across all ONOS nodes" )
1760 else:
1761 consistentMastership = False
1762 utilities.assert_equals(
1763 expect=True,
1764 actual=consistentMastership,
1765 onpass="Switch roles are consistent across all ONOS nodes",
1766 onfail="ONOS nodes have different views of switch roles" )
1767
1768 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001769 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001770 main.log.warn(
1771 "ONOS" + str( i + 1 ) + " roles: ",
1772 json.dumps(
1773 json.loads( ONOSMastership[ i ] ),
1774 sort_keys=True,
1775 indent=4,
1776 separators=( ',', ': ' ) ) )
1777 elif rolesResults and not consistentMastership:
1778 mastershipCheck = main.TRUE
1779
1780 description2 = "Compare switch roles from before failure"
1781 main.step( description2 )
1782 try:
1783 currentJson = json.loads( ONOSMastership[0] )
1784 oldJson = json.loads( mastershipState )
1785 except ( ValueError, TypeError ):
1786 main.log.exception( "Something is wrong with parsing " +
1787 "ONOSMastership[0] or mastershipState" )
1788 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1789 main.log.error( "mastershipState" + repr( mastershipState ) )
1790 main.cleanup()
1791 main.exit()
1792 mastershipCheck = main.TRUE
1793 for i in range( 1, 29 ):
1794 switchDPID = str(
1795 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1796 current = [ switch[ 'master' ] for switch in currentJson
1797 if switchDPID in switch[ 'id' ] ]
1798 old = [ switch[ 'master' ] for switch in oldJson
1799 if switchDPID in switch[ 'id' ] ]
1800 if current == old:
1801 mastershipCheck = mastershipCheck and main.TRUE
1802 else:
1803 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1804 mastershipCheck = main.FALSE
1805 utilities.assert_equals(
1806 expect=main.TRUE,
1807 actual=mastershipCheck,
1808 onpass="Mastership of Switches was not changed",
1809 onfail="Mastership of some switches changed" )
1810 mastershipCheck = mastershipCheck and consistentMastership
1811
1812 main.step( "Get the intents and compare across all nodes" )
1813 ONOSIntents = []
1814 intentCheck = main.FALSE
1815 consistentIntents = True
1816 intentsResults = True
1817 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001818 for i in range( main.numCtrls ):
1819 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001820 name="intents-" + str( i ),
1821 args=[],
1822 kwargs={ 'jsonFormat': True } )
1823 threads.append( t )
1824 t.start()
1825
1826 for t in threads:
1827 t.join()
1828 ONOSIntents.append( t.result )
1829
Jon Halle1a3b752015-07-22 13:02:46 -07001830 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001831 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1832 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1833 " intents" )
1834 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1835 repr( ONOSIntents[ i ] ) )
1836 intentsResults = False
1837 utilities.assert_equals(
1838 expect=True,
1839 actual=intentsResults,
1840 onpass="No error in reading intents output",
1841 onfail="Error in reading intents from ONOS" )
1842
1843 main.step( "Check for consistency in Intents from each controller" )
1844 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1845 main.log.info( "Intents are consistent across all ONOS " +
1846 "nodes" )
1847 else:
1848 consistentIntents = False
1849
1850 # Try to make it easy to figure out what is happening
1851 #
1852 # Intent ONOS1 ONOS2 ...
1853 # 0x01 INSTALLED INSTALLING
1854 # ... ... ...
1855 # ... ... ...
1856 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001857 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001858 title += " " * 10 + "ONOS" + str( n + 1 )
1859 main.log.warn( title )
1860 # get all intent keys in the cluster
1861 keys = []
1862 for nodeStr in ONOSIntents:
1863 node = json.loads( nodeStr )
1864 for intent in node:
1865 keys.append( intent.get( 'id' ) )
1866 keys = set( keys )
1867 for key in keys:
1868 row = "%-13s" % key
1869 for nodeStr in ONOSIntents:
1870 node = json.loads( nodeStr )
1871 for intent in node:
1872 if intent.get( 'id' ) == key:
1873 row += "%-15s" % intent.get( 'state' )
1874 main.log.warn( row )
1875 # End table view
1876
1877 utilities.assert_equals(
1878 expect=True,
1879 actual=consistentIntents,
1880 onpass="Intents are consistent across all ONOS nodes",
1881 onfail="ONOS nodes have different views of intents" )
1882 intentStates = []
1883 for node in ONOSIntents: # Iter through ONOS nodes
1884 nodeStates = []
1885 # Iter through intents of a node
1886 try:
1887 for intent in json.loads( node ):
1888 nodeStates.append( intent[ 'state' ] )
1889 except ( ValueError, TypeError ):
1890 main.log.exception( "Error in parsing intents" )
1891 main.log.error( repr( node ) )
1892 intentStates.append( nodeStates )
1893 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1894 main.log.info( dict( out ) )
1895
1896 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07001897 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001898 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1899 main.log.warn( json.dumps(
1900 json.loads( ONOSIntents[ i ] ),
1901 sort_keys=True,
1902 indent=4,
1903 separators=( ',', ': ' ) ) )
1904 elif intentsResults and consistentIntents:
1905 intentCheck = main.TRUE
1906
1907 # NOTE: Store has no durability, so intents are lost across system
1908 # restarts
1909 main.step( "Compare current intents with intents before the failure" )
1910 # NOTE: this requires case 5 to pass for intentState to be set.
1911 # maybe we should stop the test if that fails?
1912 sameIntents = main.FALSE
1913 if intentState and intentState == ONOSIntents[ 0 ]:
1914 sameIntents = main.TRUE
1915 main.log.info( "Intents are consistent with before failure" )
1916 # TODO: possibly the states have changed? we may need to figure out
1917 # what the acceptable states are
1918 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1919 sameIntents = main.TRUE
1920 try:
1921 before = json.loads( intentState )
1922 after = json.loads( ONOSIntents[ 0 ] )
1923 for intent in before:
1924 if intent not in after:
1925 sameIntents = main.FALSE
1926 main.log.debug( "Intent is not currently in ONOS " +
1927 "(at least in the same form):" )
1928 main.log.debug( json.dumps( intent ) )
1929 except ( ValueError, TypeError ):
1930 main.log.exception( "Exception printing intents" )
1931 main.log.debug( repr( ONOSIntents[0] ) )
1932 main.log.debug( repr( intentState ) )
1933 if sameIntents == main.FALSE:
1934 try:
1935 main.log.debug( "ONOS intents before: " )
1936 main.log.debug( json.dumps( json.loads( intentState ),
1937 sort_keys=True, indent=4,
1938 separators=( ',', ': ' ) ) )
1939 main.log.debug( "Current ONOS intents: " )
1940 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1941 sort_keys=True, indent=4,
1942 separators=( ',', ': ' ) ) )
1943 except ( ValueError, TypeError ):
1944 main.log.exception( "Exception printing intents" )
1945 main.log.debug( repr( ONOSIntents[0] ) )
1946 main.log.debug( repr( intentState ) )
1947 utilities.assert_equals(
1948 expect=main.TRUE,
1949 actual=sameIntents,
1950 onpass="Intents are consistent with before failure",
1951 onfail="The Intents changed during failure" )
1952 intentCheck = intentCheck and sameIntents
1953
1954 main.step( "Get the OF Table entries and compare to before " +
1955 "component failure" )
1956 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07001957 for i in range( 28 ):
1958 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001959 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1960 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07001961 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001962 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
1963
Jon Hall5cf14d52015-07-16 12:15:19 -07001964 utilities.assert_equals(
1965 expect=main.TRUE,
1966 actual=FlowTables,
1967 onpass="No changes were found in the flow tables",
1968 onfail="Changes were found in the flow tables" )
1969
1970 main.Mininet2.pingLongKill()
1971 '''
1972 main.step( "Check the continuous pings to ensure that no packets " +
1973 "were dropped during component failure" )
1974 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1975 main.params[ 'TESTONIP' ] )
1976 LossInPings = main.FALSE
1977 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1978 for i in range( 8, 18 ):
1979 main.log.info(
1980 "Checking for a loss in pings along flow from s" +
1981 str( i ) )
1982 LossInPings = main.Mininet2.checkForLoss(
1983 "/tmp/ping.h" +
1984 str( i ) ) or LossInPings
1985 if LossInPings == main.TRUE:
1986 main.log.info( "Loss in ping detected" )
1987 elif LossInPings == main.ERROR:
1988 main.log.info( "There are multiple mininet process running" )
1989 elif LossInPings == main.FALSE:
1990 main.log.info( "No Loss in the pings" )
1991 main.log.info( "No loss of dataplane connectivity" )
1992 utilities.assert_equals(
1993 expect=main.FALSE,
1994 actual=LossInPings,
1995 onpass="No Loss of connectivity",
1996 onfail="Loss of dataplane connectivity detected" )
1997 '''
1998
1999 main.step( "Leadership Election is still functional" )
2000 # Test of LeadershipElection
2001 # NOTE: this only works for the sanity test. In case of failures,
2002 # leader will likely change
Jon Halle1a3b752015-07-22 13:02:46 -07002003 leader = main.nodes[ 0 ].ip_address
Jon Hall5cf14d52015-07-16 12:15:19 -07002004 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002005 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002006 leaderN = cli.electionTestLeader()
2007 # verify leader is ONOS1
2008 if leaderN == leader:
2009 # all is well
2010 # NOTE: In failure scenario, this could be a new node, maybe
2011 # check != ONOS1
2012 pass
2013 elif leaderN == main.FALSE:
2014 # error in response
2015 main.log.error( "Something is wrong with " +
2016 "electionTestLeader function, check the" +
2017 " error logs" )
2018 leaderResult = main.FALSE
2019 elif leader != leaderN:
2020 leaderResult = main.FALSE
2021 main.log.error( cli.name + " sees " + str( leaderN ) +
2022 " as the leader of the election app. " +
2023 "Leader should be " + str( leader ) )
2024 utilities.assert_equals(
2025 expect=main.TRUE,
2026 actual=leaderResult,
2027 onpass="Leadership election passed",
2028 onfail="Something went wrong with Leadership election" )
2029
2030 def CASE8( self, main ):
2031 """
2032 Compare topo
2033 """
2034 import json
2035 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002036 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002037 assert main, "main not defined"
2038 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002039 assert main.CLIs, "main.CLIs not defined"
2040 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002041
2042 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002043 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002044 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002045 topoResult = main.FALSE
2046 elapsed = 0
2047 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002048 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002049 startTime = time.time()
2050 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002051 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002052 devicesResults = main.TRUE
2053 linksResults = main.TRUE
2054 hostsResults = main.TRUE
2055 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002056 count += 1
2057 cliStart = time.time()
2058 devices = []
2059 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002060 for i in range( main.numCtrls ):
2061 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002062 name="devices-" + str( i ),
2063 args=[ ] )
2064 threads.append( t )
2065 t.start()
2066
2067 for t in threads:
2068 t.join()
2069 devices.append( t.result )
2070 hosts = []
2071 ipResult = main.TRUE
2072 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002073 for i in range( main.numCtrls ):
2074 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002075 name="hosts-" + str( i ),
2076 args=[ ] )
2077 threads.append( t )
2078 t.start()
2079
2080 for t in threads:
2081 t.join()
2082 try:
2083 hosts.append( json.loads( t.result ) )
2084 except ( ValueError, TypeError ):
2085 main.log.exception( "Error parsing hosts results" )
2086 main.log.error( repr( t.result ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002087 hosts.append( [] )
Jon Hall5cf14d52015-07-16 12:15:19 -07002088 for controller in range( 0, len( hosts ) ):
2089 controllerStr = str( controller + 1 )
2090 for host in hosts[ controller ]:
2091 if host is None or host.get( 'ipAddresses', [] ) == []:
2092 main.log.error(
2093 "DEBUG:Error with host ipAddresses on controller" +
2094 controllerStr + ": " + str( host ) )
2095 ipResult = main.FALSE
2096 ports = []
2097 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002098 for i in range( main.numCtrls ):
2099 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002100 name="ports-" + str( i ),
2101 args=[ ] )
2102 threads.append( t )
2103 t.start()
2104
2105 for t in threads:
2106 t.join()
2107 ports.append( t.result )
2108 links = []
2109 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002110 for i in range( main.numCtrls ):
2111 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002112 name="links-" + str( i ),
2113 args=[ ] )
2114 threads.append( t )
2115 t.start()
2116
2117 for t in threads:
2118 t.join()
2119 links.append( t.result )
2120 clusters = []
2121 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002122 for i in range( main.numCtrls ):
2123 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002124 name="clusters-" + str( i ),
2125 args=[ ] )
2126 threads.append( t )
2127 t.start()
2128
2129 for t in threads:
2130 t.join()
2131 clusters.append( t.result )
2132
2133 elapsed = time.time() - startTime
2134 cliTime = time.time() - cliStart
2135 print "Elapsed time: " + str( elapsed )
2136 print "CLI time: " + str( cliTime )
2137
2138 mnSwitches = main.Mininet1.getSwitches()
2139 mnLinks = main.Mininet1.getLinks()
2140 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002141 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002142 controllerStr = str( controller + 1 )
2143 if devices[ controller ] and ports[ controller ] and\
2144 "Error" not in devices[ controller ] and\
2145 "Error" not in ports[ controller ]:
2146
2147 currentDevicesResult = main.Mininet1.compareSwitches(
2148 mnSwitches,
2149 json.loads( devices[ controller ] ),
2150 json.loads( ports[ controller ] ) )
2151 else:
2152 currentDevicesResult = main.FALSE
2153 utilities.assert_equals( expect=main.TRUE,
2154 actual=currentDevicesResult,
2155 onpass="ONOS" + controllerStr +
2156 " Switches view is correct",
2157 onfail="ONOS" + controllerStr +
2158 " Switches view is incorrect" )
2159
2160 if links[ controller ] and "Error" not in links[ controller ]:
2161 currentLinksResult = main.Mininet1.compareLinks(
2162 mnSwitches, mnLinks,
2163 json.loads( links[ controller ] ) )
2164 else:
2165 currentLinksResult = main.FALSE
2166 utilities.assert_equals( expect=main.TRUE,
2167 actual=currentLinksResult,
2168 onpass="ONOS" + controllerStr +
2169 " links view is correct",
2170 onfail="ONOS" + controllerStr +
2171 " links view is incorrect" )
2172
2173 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2174 currentHostsResult = main.Mininet1.compareHosts(
2175 mnHosts,
2176 hosts[ controller ] )
2177 else:
2178 currentHostsResult = main.FALSE
2179 utilities.assert_equals( expect=main.TRUE,
2180 actual=currentHostsResult,
2181 onpass="ONOS" + controllerStr +
2182 " hosts exist in Mininet",
2183 onfail="ONOS" + controllerStr +
2184 " hosts don't match Mininet" )
2185 # CHECKING HOST ATTACHMENT POINTS
2186 hostAttachment = True
2187 zeroHosts = False
2188 # FIXME: topo-HA/obelisk specific mappings:
2189 # key is mac and value is dpid
2190 mappings = {}
2191 for i in range( 1, 29 ): # hosts 1 through 28
2192 # set up correct variables:
2193 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2194 if i == 1:
2195 deviceId = "1000".zfill(16)
2196 elif i == 2:
2197 deviceId = "2000".zfill(16)
2198 elif i == 3:
2199 deviceId = "3000".zfill(16)
2200 elif i == 4:
2201 deviceId = "3004".zfill(16)
2202 elif i == 5:
2203 deviceId = "5000".zfill(16)
2204 elif i == 6:
2205 deviceId = "6000".zfill(16)
2206 elif i == 7:
2207 deviceId = "6007".zfill(16)
2208 elif i >= 8 and i <= 17:
2209 dpid = '3' + str( i ).zfill( 3 )
2210 deviceId = dpid.zfill(16)
2211 elif i >= 18 and i <= 27:
2212 dpid = '6' + str( i ).zfill( 3 )
2213 deviceId = dpid.zfill(16)
2214 elif i == 28:
2215 deviceId = "2800".zfill(16)
2216 mappings[ macId ] = deviceId
2217 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2218 if hosts[ controller ] == []:
2219 main.log.warn( "There are no hosts discovered" )
2220 zeroHosts = True
2221 else:
2222 for host in hosts[ controller ]:
2223 mac = None
2224 location = None
2225 device = None
2226 port = None
2227 try:
2228 mac = host.get( 'mac' )
2229 assert mac, "mac field could not be found for this host object"
2230
2231 location = host.get( 'location' )
2232 assert location, "location field could not be found for this host object"
2233
2234 # Trim the protocol identifier off deviceId
2235 device = str( location.get( 'elementId' ) ).split(':')[1]
2236 assert device, "elementId field could not be found for this host location object"
2237
2238 port = location.get( 'port' )
2239 assert port, "port field could not be found for this host location object"
2240
2241 # Now check if this matches where they should be
2242 if mac and device and port:
2243 if str( port ) != "1":
2244 main.log.error( "The attachment port is incorrect for " +
2245 "host " + str( mac ) +
2246 ". Expected: 1 Actual: " + str( port) )
2247 hostAttachment = False
2248 if device != mappings[ str( mac ) ]:
2249 main.log.error( "The attachment device is incorrect for " +
2250 "host " + str( mac ) +
2251 ". Expected: " + mappings[ str( mac ) ] +
2252 " Actual: " + device )
2253 hostAttachment = False
2254 else:
2255 hostAttachment = False
2256 except AssertionError:
2257 main.log.exception( "Json object not as expected" )
2258 main.log.error( repr( host ) )
2259 hostAttachment = False
2260 else:
2261 main.log.error( "No hosts json output or \"Error\"" +
2262 " in output. hosts = " +
2263 repr( hosts[ controller ] ) )
2264 if zeroHosts is False:
2265 hostAttachment = True
2266
2267 # END CHECKING HOST ATTACHMENT POINTS
2268 devicesResults = devicesResults and currentDevicesResult
2269 linksResults = linksResults and currentLinksResult
2270 hostsResults = hostsResults and currentHostsResult
2271 hostAttachmentResults = hostAttachmentResults and\
2272 hostAttachment
2273 topoResult = ( devicesResults and linksResults
2274 and hostsResults and ipResult and
2275 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002276 utilities.assert_equals( expect=True,
2277 actual=topoResult,
2278 onpass="ONOS topology matches Mininet",
2279 onfail="ONOS topology don't match Mininet" )
2280 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002281
2282 # Compare json objects for hosts and dataplane clusters
2283
2284 # hosts
2285 main.step( "Hosts view is consistent across all ONOS nodes" )
2286 consistentHostsResult = main.TRUE
2287 for controller in range( len( hosts ) ):
2288 controllerStr = str( controller + 1 )
2289 if "Error" not in hosts[ controller ]:
2290 if hosts[ controller ] == hosts[ 0 ]:
2291 continue
2292 else: # hosts not consistent
2293 main.log.error( "hosts from ONOS" + controllerStr +
2294 " is inconsistent with ONOS1" )
2295 main.log.warn( repr( hosts[ controller ] ) )
2296 consistentHostsResult = main.FALSE
2297
2298 else:
2299 main.log.error( "Error in getting ONOS hosts from ONOS" +
2300 controllerStr )
2301 consistentHostsResult = main.FALSE
2302 main.log.warn( "ONOS" + controllerStr +
2303 " hosts response: " +
2304 repr( hosts[ controller ] ) )
2305 utilities.assert_equals(
2306 expect=main.TRUE,
2307 actual=consistentHostsResult,
2308 onpass="Hosts view is consistent across all ONOS nodes",
2309 onfail="ONOS nodes have different views of hosts" )
2310
2311 main.step( "Hosts information is correct" )
2312 hostsResults = hostsResults and ipResult
2313 utilities.assert_equals(
2314 expect=main.TRUE,
2315 actual=hostsResults,
2316 onpass="Host information is correct",
2317 onfail="Host information is incorrect" )
2318
2319 main.step( "Host attachment points to the network" )
2320 utilities.assert_equals(
2321 expect=True,
2322 actual=hostAttachmentResults,
2323 onpass="Hosts are correctly attached to the network",
2324 onfail="ONOS did not correctly attach hosts to the network" )
2325
2326 # Strongly connected clusters of devices
2327 main.step( "Clusters view is consistent across all ONOS nodes" )
2328 consistentClustersResult = main.TRUE
2329 for controller in range( len( clusters ) ):
2330 controllerStr = str( controller + 1 )
2331 if "Error" not in clusters[ controller ]:
2332 if clusters[ controller ] == clusters[ 0 ]:
2333 continue
2334 else: # clusters not consistent
2335 main.log.error( "clusters from ONOS" +
2336 controllerStr +
2337 " is inconsistent with ONOS1" )
2338 consistentClustersResult = main.FALSE
2339
2340 else:
2341 main.log.error( "Error in getting dataplane clusters " +
2342 "from ONOS" + controllerStr )
2343 consistentClustersResult = main.FALSE
2344 main.log.warn( "ONOS" + controllerStr +
2345 " clusters response: " +
2346 repr( clusters[ controller ] ) )
2347 utilities.assert_equals(
2348 expect=main.TRUE,
2349 actual=consistentClustersResult,
2350 onpass="Clusters view is consistent across all ONOS nodes",
2351 onfail="ONOS nodes have different views of clusters" )
2352
2353 main.step( "There is only one SCC" )
2354 # there should always only be one cluster
2355 try:
2356 numClusters = len( json.loads( clusters[ 0 ] ) )
2357 except ( ValueError, TypeError ):
2358 main.log.exception( "Error parsing clusters[0]: " +
2359 repr( clusters[0] ) )
2360 clusterResults = main.FALSE
2361 if numClusters == 1:
2362 clusterResults = main.TRUE
2363 utilities.assert_equals(
2364 expect=1,
2365 actual=numClusters,
2366 onpass="ONOS shows 1 SCC",
2367 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2368
2369 topoResult = ( devicesResults and linksResults
2370 and hostsResults and consistentHostsResult
2371 and consistentClustersResult and clusterResults
2372 and ipResult and hostAttachmentResults )
2373
2374 topoResult = topoResult and int( count <= 2 )
2375 note = "note it takes about " + str( int( cliTime ) ) + \
2376 " seconds for the test to make all the cli calls to fetch " +\
2377 "the topology from each ONOS instance"
2378 main.log.info(
2379 "Very crass estimate for topology discovery/convergence( " +
2380 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2381 str( count ) + " tries" )
2382
2383 main.step( "Device information is correct" )
2384 utilities.assert_equals(
2385 expect=main.TRUE,
2386 actual=devicesResults,
2387 onpass="Device information is correct",
2388 onfail="Device information is incorrect" )
2389
2390 main.step( "Links are correct" )
2391 utilities.assert_equals(
2392 expect=main.TRUE,
2393 actual=linksResults,
2394 onpass="Link are correct",
2395 onfail="Links are incorrect" )
2396
2397 main.step( "Hosts are correct" )
2398 utilities.assert_equals(
2399 expect=main.TRUE,
2400 actual=hostsResults,
2401 onpass="Hosts are correct",
2402 onfail="Hosts are incorrect" )
2403
2404 # FIXME: move this to an ONOS state case
2405 main.step( "Checking ONOS nodes" )
2406 nodesOutput = []
2407 nodeResults = main.TRUE
2408 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002409 for i in range( main.numCtrls ):
2410 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002411 name="nodes-" + str( i ),
2412 args=[ ] )
2413 threads.append( t )
2414 t.start()
2415
2416 for t in threads:
2417 t.join()
2418 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002419 ips = [ node.ip_address for node in main.nodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002420 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002421 for i in nodesOutput:
2422 try:
2423 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002424 activeIps = []
2425 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002426 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002427 if node['state'] == 'ACTIVE':
2428 activeIps.append( node['ip'] )
2429 activeIps.sort()
2430 if ips == activeIps:
2431 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002432 except ( ValueError, TypeError ):
2433 main.log.error( "Error parsing nodes output" )
2434 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002435 currentResult = main.FALSE
2436 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002437 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2438 onpass="Nodes check successful",
2439 onfail="Nodes check NOT successful" )
2440
2441 def CASE9( self, main ):
2442 """
2443 Link s3-s28 down
2444 """
2445 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002446 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002447 assert main, "main not defined"
2448 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002449 assert main.CLIs, "main.CLIs not defined"
2450 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002451 # NOTE: You should probably run a topology check after this
2452
2453 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2454
2455 description = "Turn off a link to ensure that Link Discovery " +\
2456 "is working properly"
2457 main.case( description )
2458
2459 main.step( "Kill Link between s3 and s28" )
2460 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2461 main.log.info( "Waiting " + str( linkSleep ) +
2462 " seconds for link down to be discovered" )
2463 time.sleep( linkSleep )
2464 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2465 onpass="Link down successful",
2466 onfail="Failed to bring link down" )
2467 # TODO do some sort of check here
2468
2469 def CASE10( self, main ):
2470 """
2471 Link s3-s28 up
2472 """
2473 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002474 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002475 assert main, "main not defined"
2476 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002477 assert main.CLIs, "main.CLIs not defined"
2478 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002479 # NOTE: You should probably run a topology check after this
2480
2481 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2482
2483 description = "Restore a link to ensure that Link Discovery is " + \
2484 "working properly"
2485 main.case( description )
2486
2487 main.step( "Bring link between s3 and s28 back up" )
2488 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2489 main.log.info( "Waiting " + str( linkSleep ) +
2490 " seconds for link up to be discovered" )
2491 time.sleep( linkSleep )
2492 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2493 onpass="Link up successful",
2494 onfail="Failed to bring link up" )
2495 # TODO do some sort of check here
2496
2497 def CASE11( self, main ):
2498 """
2499 Switch Down
2500 """
2501 # NOTE: You should probably run a topology check after this
2502 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002503 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002504 assert main, "main not defined"
2505 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002506 assert main.CLIs, "main.CLIs not defined"
2507 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002508
2509 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2510
2511 description = "Killing a switch to ensure it is discovered correctly"
2512 main.case( description )
2513 switch = main.params[ 'kill' ][ 'switch' ]
2514 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2515
2516 # TODO: Make this switch parameterizable
2517 main.step( "Kill " + switch )
2518 main.log.info( "Deleting " + switch )
2519 main.Mininet1.delSwitch( switch )
2520 main.log.info( "Waiting " + str( switchSleep ) +
2521 " seconds for switch down to be discovered" )
2522 time.sleep( switchSleep )
2523 device = main.ONOScli1.getDevice( dpid=switchDPID )
2524 # Peek at the deleted switch
2525 main.log.warn( str( device ) )
2526 result = main.FALSE
2527 if device and device[ 'available' ] is False:
2528 result = main.TRUE
2529 utilities.assert_equals( expect=main.TRUE, actual=result,
2530 onpass="Kill switch successful",
2531 onfail="Failed to kill switch?" )
2532
2533 def CASE12( self, main ):
2534 """
2535 Switch Up
2536 """
2537 # NOTE: You should probably run a topology check after this
2538 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002539 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002540 assert main, "main not defined"
2541 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002542 assert main.CLIs, "main.CLIs not defined"
2543 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002544 assert ONOS1Port, "ONOS1Port not defined"
2545 assert ONOS2Port, "ONOS2Port not defined"
2546 assert ONOS3Port, "ONOS3Port not defined"
2547 assert ONOS4Port, "ONOS4Port not defined"
2548 assert ONOS5Port, "ONOS5Port not defined"
2549 assert ONOS6Port, "ONOS6Port not defined"
2550 assert ONOS7Port, "ONOS7Port not defined"
2551
2552 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2553 switch = main.params[ 'kill' ][ 'switch' ]
2554 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2555 links = main.params[ 'kill' ][ 'links' ].split()
2556 description = "Adding a switch to ensure it is discovered correctly"
2557 main.case( description )
2558
2559 main.step( "Add back " + switch )
2560 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2561 for peer in links:
2562 main.Mininet1.addLink( switch, peer )
2563 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002564 for i in range( main.numCtrls ):
2565 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002566 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2567 main.log.info( "Waiting " + str( switchSleep ) +
2568 " seconds for switch up to be discovered" )
2569 time.sleep( switchSleep )
2570 device = main.ONOScli1.getDevice( dpid=switchDPID )
2571 # Peek at the deleted switch
2572 main.log.warn( str( device ) )
2573 result = main.FALSE
2574 if device and device[ 'available' ]:
2575 result = main.TRUE
2576 utilities.assert_equals( expect=main.TRUE, actual=result,
2577 onpass="add switch successful",
2578 onfail="Failed to add switch?" )
2579
2580 def CASE13( self, main ):
2581 """
2582 Clean up
2583 """
2584 import os
2585 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002586 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002587 assert main, "main not defined"
2588 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002589 assert main.CLIs, "main.CLIs not defined"
2590 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002591
2592 # printing colors to terminal
2593 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2594 'blue': '\033[94m', 'green': '\033[92m',
2595 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2596 main.case( "Test Cleanup" )
2597 main.step( "Killing tcpdumps" )
2598 main.Mininet2.stopTcpdump()
2599
2600 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002601 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002602 main.step( "Copying MN pcap and ONOS log files to test station" )
2603 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2604 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002605 # NOTE: MN Pcap file is being saved to logdir.
2606 # We scp this file as MN and TestON aren't necessarily the same vm
2607
2608 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002609 # TODO: Load these from params
2610 # NOTE: must end in /
2611 logFolder = "/opt/onos/log/"
2612 logFiles = [ "karaf.log", "karaf.log.1" ]
2613 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002614 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002615 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002616 dstName = main.logdir + "/" + node.name + "-" + f
2617 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2618 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002619 # std*.log's
2620 # NOTE: must end in /
2621 logFolder = "/opt/onos/var/"
2622 logFiles = [ "stderr.log", "stdout.log" ]
2623 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002624 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002625 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002626 dstName = main.logdir + "/" + node.name + "-" + f
2627 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2628 logFolder + f, dstName )
2629 else:
2630 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002631
2632 main.step( "Stopping Mininet" )
2633 mnResult = main.Mininet1.stopNet()
2634 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2635 onpass="Mininet stopped",
2636 onfail="MN cleanup NOT successful" )
2637
2638 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002639 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002640 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2641 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002642
2643 try:
2644 timerLog = open( main.logdir + "/Timers.csv", 'w')
2645 # Overwrite with empty line and close
2646 labels = "Gossip Intents"
2647 data = str( gossipTime )
2648 timerLog.write( labels + "\n" + data )
2649 timerLog.close()
2650 except NameError, e:
2651 main.log.exception(e)
2652
2653 def CASE14( self, main ):
2654 """
2655 start election app on all onos nodes
2656 """
Jon Halle1a3b752015-07-22 13:02:46 -07002657 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002658 assert main, "main not defined"
2659 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002660 assert main.CLIs, "main.CLIs not defined"
2661 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002662
2663 main.case("Start Leadership Election app")
2664 main.step( "Install leadership election app" )
2665 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2666 utilities.assert_equals(
2667 expect=main.TRUE,
2668 actual=appResult,
2669 onpass="Election app installed",
2670 onfail="Something went wrong with installing Leadership election" )
2671
2672 main.step( "Run for election on each node" )
2673 leaderResult = main.TRUE
2674 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002675 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002676 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002677 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002678 leader = cli.electionTestLeader()
2679 if leader is None or leader == main.FALSE:
2680 main.log.error( cli.name + ": Leader for the election app " +
2681 "should be an ONOS node, instead got '" +
2682 str( leader ) + "'" )
2683 leaderResult = main.FALSE
2684 leaders.append( leader )
2685 utilities.assert_equals(
2686 expect=main.TRUE,
2687 actual=leaderResult,
2688 onpass="Successfully ran for leadership",
2689 onfail="Failed to run for leadership" )
2690
2691 main.step( "Check that each node shows the same leader" )
2692 sameLeader = main.TRUE
2693 if len( set( leaders ) ) != 1:
2694 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002695 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002696 str( leaders ) )
2697 utilities.assert_equals(
2698 expect=main.TRUE,
2699 actual=sameLeader,
2700 onpass="Leadership is consistent for the election topic",
2701 onfail="Nodes have different leaders" )
2702
2703 def CASE15( self, main ):
2704 """
2705 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002706 15.1 Run election on each node
2707 15.2 Check that each node has the same leaders and candidates
2708 15.3 Find current leader and withdraw
2709 15.4 Check that a new node was elected leader
2710 15.5 Check that that new leader was the candidate of old leader
2711 15.6 Run for election on old leader
2712 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2713 15.8 Make sure that the old leader was added to the candidate list
2714
2715 old and new variable prefixes refer to data from before vs after
2716 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002717 """
2718 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002719 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002720 assert main, "main not defined"
2721 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002722 assert main.CLIs, "main.CLIs not defined"
2723 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002724
acsmars3a72bde2015-09-02 14:16:22 -07002725 description = "Check that Leadership Election App is still functional"
Jon Hall5cf14d52015-07-16 12:15:19 -07002726 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002727 # NOTE: Need to re-run since being a canidate is not persistant
2728 # TODO: add check for "Command not found:" in the driver, this
2729 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002730
acsmars71adceb2015-08-31 15:09:26 -07002731 oldLeaders = [] # leaders by node before withdrawl from candidates
2732 newLeaders = [] # leaders by node after withdrawl from candidates
2733 oldAllCandidates = [] # list of lists of each nodes' candidates before
2734 newAllCandidates = [] # list of lists of each nodes' candidates after
2735 oldCandidates = [] # list of candidates from node 0 before withdrawl
2736 newCandidates = [] # list of candidates from node 0 after withdrawl
2737 oldLeader = '' # the old leader from oldLeaders, None if not same
2738 newLeader = '' # the new leaders fron newLoeaders, None if not same
2739 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2740 expectNoLeader = False # True when there is only one leader
2741 if main.numCtrls == 1:
2742 expectNoLeader = True
2743
2744 main.step( "Run for election on each node" )
2745 electionResult = main.TRUE
2746
2747 for cli in main.CLIs: # run test election on each node
2748 if cli.electionTestRun() == main.FALSE:
2749 electionResult = main.FALSE
2750
Jon Hall5cf14d52015-07-16 12:15:19 -07002751 utilities.assert_equals(
2752 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002753 actual=electionResult,
2754 onpass="All nodes successfully ran for leadership",
2755 onfail="At least one node failed to run for leadership" )
2756
acsmars3a72bde2015-09-02 14:16:22 -07002757 if electionResult == main.FALSE:
2758 main.log.error(
2759 "Skipping Test Case because Election Test isn't loaded" )
2760 main.skipCase()
2761
acsmars71adceb2015-08-31 15:09:26 -07002762 main.step( "Check that each node shows the same leader and candidates" )
2763 sameResult = main.TRUE
2764 failMessage = "Nodes have different leaders"
2765 for cli in main.CLIs:
2766 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2767 oldAllCandidates.append( node )
2768 oldLeaders.append( node[ 0 ] )
2769 oldCandidates = oldAllCandidates[ 0 ]
2770
2771 # Check that each node has the same leader. Defines oldLeader
2772 if len( set( oldLeaders ) ) != 1:
2773 sameResult = main.FALSE
2774 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2775 oldLeader = None
2776 else:
2777 oldLeader = oldLeaders[ 0 ]
2778
2779 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002780 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07002781 for candidates in oldAllCandidates:
2782 if set( candidates ) != set( oldCandidates ):
2783 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002784 candidateDiscrepancy = True
2785
2786 if candidateDiscrepancy:
2787 failMessage += " and candidates"
acsmars71adceb2015-08-31 15:09:26 -07002788
2789 utilities.assert_equals(
2790 expect=main.TRUE,
2791 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002792 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002793 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002794
2795 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002796 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002797 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002798 if oldLeader is None:
2799 main.log.error( "Leadership isn't consistent." )
2800 withdrawResult = main.FALSE
2801 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002802 for i in range( len( main.CLIs ) ):
acsmars71adceb2015-08-31 15:09:26 -07002803 if oldLeader == main.nodes[ i ].ip_address:
2804 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002805 break
2806 else: # FOR/ELSE statement
2807 main.log.error( "Leader election, could not find current leader" )
2808 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002809 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002810 utilities.assert_equals(
2811 expect=main.TRUE,
2812 actual=withdrawResult,
2813 onpass="Node was withdrawn from election",
2814 onfail="Node was not withdrawn from election" )
2815
acsmars71adceb2015-08-31 15:09:26 -07002816 main.step( "Check that a new node was elected leader" )
2817
Jon Hall5cf14d52015-07-16 12:15:19 -07002818 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002819 newLeaderResult = main.TRUE
2820 failMessage = "Nodes have different leaders"
2821
2822 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002823 for cli in main.CLIs:
acsmars71adceb2015-08-31 15:09:26 -07002824 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2825 # elections might no have finished yet
2826 if node[ 0 ] == 'none' and not expectNoLeader:
2827 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2828 "sure elections are complete." )
2829 time.sleep(5)
2830 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2831 # election still isn't done or there is a problem
2832 if node[ 0 ] == 'none':
2833 main.log.error( "No leader was elected on at least 1 node" )
2834 newLeaderResult = main.FALSE
2835 newAllCandidates.append( node )
2836 newLeaders.append( node[ 0 ] )
2837 newCandidates = newAllCandidates[ 0 ]
2838
2839 # Check that each node has the same leader. Defines newLeader
2840 if len( set( newLeaders ) ) != 1:
2841 newLeaderResult = main.FALSE
2842 main.log.error( "Nodes have different leaders: " +
2843 str( newLeaders ) )
2844 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002845 else:
acsmars71adceb2015-08-31 15:09:26 -07002846 newLeader = newLeaders[ 0 ]
2847
2848 # Check that each node's candidate list is the same
2849 for candidates in newAllCandidates:
2850 if set( candidates ) != set( newCandidates ):
2851 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002852 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002853
2854 # Check that the new leader is not the older leader, which was withdrawn
2855 if newLeader == oldLeader:
2856 newLeaderResult = main.FALSE
2857 main.log.error( "All nodes still see old leader: " + oldLeader +
2858 " as the current leader" )
2859
Jon Hall5cf14d52015-07-16 12:15:19 -07002860 utilities.assert_equals(
2861 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002862 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002863 onpass="Leadership election passed",
2864 onfail="Something went wrong with Leadership election" )
2865
acsmars71adceb2015-08-31 15:09:26 -07002866 main.step( "Check that that new leader was the candidate of old leader")
2867 # candidates[ 2 ] should be come the top candidate after withdrawl
2868 correctCandidateResult = main.TRUE
2869 if expectNoLeader:
2870 if newLeader == 'none':
2871 main.log.info( "No leader expected. None found. Pass" )
2872 correctCandidateResult = main.TRUE
2873 else:
2874 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2875 correctCandidateResult = main.FALSE
2876 elif newLeader != oldCandidates[ 2 ]:
2877 correctCandidateResult = main.FALSE
2878 main.log.error( "Candidate " + newLeader + " was elected. " +
2879 oldCandidates[ 2 ] + " should have had priority." )
2880
2881 utilities.assert_equals(
2882 expect=main.TRUE,
2883 actual=correctCandidateResult,
2884 onpass="Correct Candidate Elected",
2885 onfail="Incorrect Candidate Elected" )
2886
Jon Hall5cf14d52015-07-16 12:15:19 -07002887 main.step( "Run for election on old leader( just so everyone " +
2888 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002889 if oldLeaderCLI is not None:
2890 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002891 else:
acsmars71adceb2015-08-31 15:09:26 -07002892 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002893 runResult = main.FALSE
2894 utilities.assert_equals(
2895 expect=main.TRUE,
2896 actual=runResult,
2897 onpass="App re-ran for election",
2898 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002899 main.step(
2900 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07002902 positionResult = main.TRUE
2903 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
2904
2905 # Reset and reuse the new candidate and leaders lists
2906 newAllCandidates = []
2907 newCandidates = []
2908 newLeaders = []
2909 for cli in main.CLIs:
2910 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2911 if oldLeader not in node: # election might no have finished yet
2912 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2913 "be sure elections are complete" )
2914 time.sleep(5)
2915 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2916 if oldLeader not in node: # election still isn't done, errors
2917 main.log.error(
2918 "Old leader was not elected on at least one node" )
2919 positionResult = main.FALSE
2920 newAllCandidates.append( node )
2921 newLeaders.append( node[ 0 ] )
2922 newCandidates = newAllCandidates[ 0 ]
2923
2924 # Check that each node has the same leader. Defines newLeader
2925 if len( set( newLeaders ) ) != 1:
2926 positionResult = main.FALSE
2927 main.log.error( "Nodes have different leaders: " +
2928 str( newLeaders ) )
2929 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002930 else:
acsmars71adceb2015-08-31 15:09:26 -07002931 newLeader = newLeaders[ 0 ]
2932
2933 # Check that each node's candidate list is the same
2934 for candidates in newAllCandidates:
2935 if set( candidates ) != set( newCandidates ):
2936 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002937 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002938
2939 # Check that the re-elected node is last on the candidate List
2940 if oldLeader != newCandidates[ -1 ]:
2941 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2942 str( newCandidates ) )
2943 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002944
2945 utilities.assert_equals(
2946 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002947 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002948 onpass="Old leader successfully re-ran for election",
2949 onfail="Something went wrong with Leadership election after " +
2950 "the old leader re-ran for election" )
2951
2952 def CASE16( self, main ):
2953 """
2954 Install Distributed Primitives app
2955 """
2956 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002957 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002958 assert main, "main not defined"
2959 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002960 assert main.CLIs, "main.CLIs not defined"
2961 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002962
2963 # Variables for the distributed primitives tests
2964 global pCounterName
2965 global iCounterName
2966 global pCounterValue
2967 global iCounterValue
2968 global onosSet
2969 global onosSetName
2970 pCounterName = "TestON-Partitions"
2971 iCounterName = "TestON-inMemory"
2972 pCounterValue = 0
2973 iCounterValue = 0
2974 onosSet = set([])
2975 onosSetName = "TestON-set"
2976
2977 description = "Install Primitives app"
2978 main.case( description )
2979 main.step( "Install Primitives app" )
2980 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07002981 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002982 utilities.assert_equals( expect=main.TRUE,
2983 actual=appResults,
2984 onpass="Primitives app activated",
2985 onfail="Primitives app not activated" )
2986 time.sleep( 5 ) # To allow all nodes to activate
2987
2988 def CASE17( self, main ):
2989 """
2990 Check for basic functionality with distributed primitives
2991 """
Jon Hall5cf14d52015-07-16 12:15:19 -07002992 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002993 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002994 assert main, "main not defined"
2995 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002996 assert main.CLIs, "main.CLIs not defined"
2997 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002998 assert pCounterName, "pCounterName not defined"
2999 assert iCounterName, "iCounterName not defined"
3000 assert onosSetName, "onosSetName not defined"
3001 # NOTE: assert fails if value is 0/None/Empty/False
3002 try:
3003 pCounterValue
3004 except NameError:
3005 main.log.error( "pCounterValue not defined, setting to 0" )
3006 pCounterValue = 0
3007 try:
3008 iCounterValue
3009 except NameError:
3010 main.log.error( "iCounterValue not defined, setting to 0" )
3011 iCounterValue = 0
3012 try:
3013 onosSet
3014 except NameError:
3015 main.log.error( "onosSet not defined, setting to empty Set" )
3016 onosSet = set([])
3017 # Variables for the distributed primitives tests. These are local only
3018 addValue = "a"
3019 addAllValue = "a b c d e f"
3020 retainValue = "c d e f"
3021
3022 description = "Check for basic functionality with distributed " +\
3023 "primitives"
3024 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003025 main.caseExplanation = "Test the methods of the distributed " +\
3026 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003027 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003028 # Partitioned counters
3029 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003030 pCounters = []
3031 threads = []
3032 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003033 for i in range( main.numCtrls ):
3034 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3035 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003036 args=[ pCounterName ] )
3037 pCounterValue += 1
3038 addedPValues.append( pCounterValue )
3039 threads.append( t )
3040 t.start()
3041
3042 for t in threads:
3043 t.join()
3044 pCounters.append( t.result )
3045 # Check that counter incremented numController times
3046 pCounterResults = True
3047 for i in addedPValues:
3048 tmpResult = i in pCounters
3049 pCounterResults = pCounterResults and tmpResult
3050 if not tmpResult:
3051 main.log.error( str( i ) + " is not in partitioned "
3052 "counter incremented results" )
3053 utilities.assert_equals( expect=True,
3054 actual=pCounterResults,
3055 onpass="Default counter incremented",
3056 onfail="Error incrementing default" +
3057 " counter" )
3058
Jon Halle1a3b752015-07-22 13:02:46 -07003059 main.step( "Get then Increment a default counter on each node" )
3060 pCounters = []
3061 threads = []
3062 addedPValues = []
3063 for i in range( main.numCtrls ):
3064 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3065 name="counterGetAndAdd-" + str( i ),
3066 args=[ pCounterName ] )
3067 addedPValues.append( pCounterValue )
3068 pCounterValue += 1
3069 threads.append( t )
3070 t.start()
3071
3072 for t in threads:
3073 t.join()
3074 pCounters.append( t.result )
3075 # Check that counter incremented numController times
3076 pCounterResults = True
3077 for i in addedPValues:
3078 tmpResult = i in pCounters
3079 pCounterResults = pCounterResults and tmpResult
3080 if not tmpResult:
3081 main.log.error( str( i ) + " is not in partitioned "
3082 "counter incremented results" )
3083 utilities.assert_equals( expect=True,
3084 actual=pCounterResults,
3085 onpass="Default counter incremented",
3086 onfail="Error incrementing default" +
3087 " counter" )
3088
3089 main.step( "Counters we added have the correct values" )
3090 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3091 utilities.assert_equals( expect=main.TRUE,
3092 actual=incrementCheck,
3093 onpass="Added counters are correct",
3094 onfail="Added counters are incorrect" )
3095
3096 main.step( "Add -8 to then get a default counter on each node" )
3097 pCounters = []
3098 threads = []
3099 addedPValues = []
3100 for i in range( main.numCtrls ):
3101 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3102 name="counterIncrement-" + str( i ),
3103 args=[ pCounterName ],
3104 kwargs={ "delta": -8 } )
3105 pCounterValue += -8
3106 addedPValues.append( pCounterValue )
3107 threads.append( t )
3108 t.start()
3109
3110 for t in threads:
3111 t.join()
3112 pCounters.append( t.result )
3113 # Check that counter incremented numController times
3114 pCounterResults = True
3115 for i in addedPValues:
3116 tmpResult = i in pCounters
3117 pCounterResults = pCounterResults and tmpResult
3118 if not tmpResult:
3119 main.log.error( str( i ) + " is not in partitioned "
3120 "counter incremented results" )
3121 utilities.assert_equals( expect=True,
3122 actual=pCounterResults,
3123 onpass="Default counter incremented",
3124 onfail="Error incrementing default" +
3125 " counter" )
3126
3127 main.step( "Add 5 to then get a default counter on each node" )
3128 pCounters = []
3129 threads = []
3130 addedPValues = []
3131 for i in range( main.numCtrls ):
3132 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3133 name="counterIncrement-" + str( i ),
3134 args=[ pCounterName ],
3135 kwargs={ "delta": 5 } )
3136 pCounterValue += 5
3137 addedPValues.append( pCounterValue )
3138 threads.append( t )
3139 t.start()
3140
3141 for t in threads:
3142 t.join()
3143 pCounters.append( t.result )
3144 # Check that counter incremented numController times
3145 pCounterResults = True
3146 for i in addedPValues:
3147 tmpResult = i in pCounters
3148 pCounterResults = pCounterResults and tmpResult
3149 if not tmpResult:
3150 main.log.error( str( i ) + " is not in partitioned "
3151 "counter incremented results" )
3152 utilities.assert_equals( expect=True,
3153 actual=pCounterResults,
3154 onpass="Default counter incremented",
3155 onfail="Error incrementing default" +
3156 " counter" )
3157
3158 main.step( "Get then add 5 to a default counter on each node" )
3159 pCounters = []
3160 threads = []
3161 addedPValues = []
3162 for i in range( main.numCtrls ):
3163 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3164 name="counterIncrement-" + str( i ),
3165 args=[ pCounterName ],
3166 kwargs={ "delta": 5 } )
3167 addedPValues.append( pCounterValue )
3168 pCounterValue += 5
3169 threads.append( t )
3170 t.start()
3171
3172 for t in threads:
3173 t.join()
3174 pCounters.append( t.result )
3175 # Check that counter incremented numController times
3176 pCounterResults = True
3177 for i in addedPValues:
3178 tmpResult = i in pCounters
3179 pCounterResults = pCounterResults and tmpResult
3180 if not tmpResult:
3181 main.log.error( str( i ) + " is not in partitioned "
3182 "counter incremented results" )
3183 utilities.assert_equals( expect=True,
3184 actual=pCounterResults,
3185 onpass="Default counter incremented",
3186 onfail="Error incrementing default" +
3187 " counter" )
3188
3189 main.step( "Counters we added have the correct values" )
3190 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3191 utilities.assert_equals( expect=main.TRUE,
3192 actual=incrementCheck,
3193 onpass="Added counters are correct",
3194 onfail="Added counters are incorrect" )
3195
3196 # In-Memory counters
3197 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003198 iCounters = []
3199 addedIValues = []
3200 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003201 for i in range( main.numCtrls ):
3202 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003203 name="icounterIncrement-" + str( i ),
3204 args=[ iCounterName ],
3205 kwargs={ "inMemory": True } )
3206 iCounterValue += 1
3207 addedIValues.append( iCounterValue )
3208 threads.append( t )
3209 t.start()
3210
3211 for t in threads:
3212 t.join()
3213 iCounters.append( t.result )
3214 # Check that counter incremented numController times
3215 iCounterResults = True
3216 for i in addedIValues:
3217 tmpResult = i in iCounters
3218 iCounterResults = iCounterResults and tmpResult
3219 if not tmpResult:
3220 main.log.error( str( i ) + " is not in the in-memory "
3221 "counter incremented results" )
3222 utilities.assert_equals( expect=True,
3223 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003224 onpass="In-memory counter incremented",
3225 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003226 " counter" )
3227
Jon Halle1a3b752015-07-22 13:02:46 -07003228 main.step( "Get then Increment a in-memory counter on each node" )
3229 iCounters = []
3230 threads = []
3231 addedIValues = []
3232 for i in range( main.numCtrls ):
3233 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3234 name="counterGetAndAdd-" + str( i ),
3235 args=[ iCounterName ],
3236 kwargs={ "inMemory": True } )
3237 addedIValues.append( iCounterValue )
3238 iCounterValue += 1
3239 threads.append( t )
3240 t.start()
3241
3242 for t in threads:
3243 t.join()
3244 iCounters.append( t.result )
3245 # Check that counter incremented numController times
3246 iCounterResults = True
3247 for i in addedIValues:
3248 tmpResult = i in iCounters
3249 iCounterResults = iCounterResults and tmpResult
3250 if not tmpResult:
3251 main.log.error( str( i ) + " is not in in-memory "
3252 "counter incremented results" )
3253 utilities.assert_equals( expect=True,
3254 actual=iCounterResults,
3255 onpass="In-memory counter incremented",
3256 onfail="Error incrementing in-memory" +
3257 " counter" )
3258
3259 main.step( "Counters we added have the correct values" )
3260 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3261 utilities.assert_equals( expect=main.TRUE,
3262 actual=incrementCheck,
3263 onpass="Added counters are correct",
3264 onfail="Added counters are incorrect" )
3265
3266 main.step( "Add -8 to then get a in-memory counter on each node" )
3267 iCounters = []
3268 threads = []
3269 addedIValues = []
3270 for i in range( main.numCtrls ):
3271 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3272 name="counterIncrement-" + str( i ),
3273 args=[ iCounterName ],
3274 kwargs={ "delta": -8, "inMemory": True } )
3275 iCounterValue += -8
3276 addedIValues.append( iCounterValue )
3277 threads.append( t )
3278 t.start()
3279
3280 for t in threads:
3281 t.join()
3282 iCounters.append( t.result )
3283 # Check that counter incremented numController times
3284 iCounterResults = True
3285 for i in addedIValues:
3286 tmpResult = i in iCounters
3287 iCounterResults = iCounterResults and tmpResult
3288 if not tmpResult:
3289 main.log.error( str( i ) + " is not in in-memory "
3290 "counter incremented results" )
3291 utilities.assert_equals( expect=True,
3292 actual=pCounterResults,
3293 onpass="In-memory counter incremented",
3294 onfail="Error incrementing in-memory" +
3295 " counter" )
3296
3297 main.step( "Add 5 to then get a in-memory counter on each node" )
3298 iCounters = []
3299 threads = []
3300 addedIValues = []
3301 for i in range( main.numCtrls ):
3302 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3303 name="counterIncrement-" + str( i ),
3304 args=[ iCounterName ],
3305 kwargs={ "delta": 5, "inMemory": True } )
3306 iCounterValue += 5
3307 addedIValues.append( iCounterValue )
3308 threads.append( t )
3309 t.start()
3310
3311 for t in threads:
3312 t.join()
3313 iCounters.append( t.result )
3314 # Check that counter incremented numController times
3315 iCounterResults = True
3316 for i in addedIValues:
3317 tmpResult = i in iCounters
3318 iCounterResults = iCounterResults and tmpResult
3319 if not tmpResult:
3320 main.log.error( str( i ) + " is not in in-memory "
3321 "counter incremented results" )
3322 utilities.assert_equals( expect=True,
3323 actual=pCounterResults,
3324 onpass="In-memory counter incremented",
3325 onfail="Error incrementing in-memory" +
3326 " counter" )
3327
3328 main.step( "Get then add 5 to a in-memory counter on each node" )
3329 iCounters = []
3330 threads = []
3331 addedIValues = []
3332 for i in range( main.numCtrls ):
3333 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3334 name="counterIncrement-" + str( i ),
3335 args=[ iCounterName ],
3336 kwargs={ "delta": 5, "inMemory": True } )
3337 addedIValues.append( iCounterValue )
3338 iCounterValue += 5
3339 threads.append( t )
3340 t.start()
3341
3342 for t in threads:
3343 t.join()
3344 iCounters.append( t.result )
3345 # Check that counter incremented numController times
3346 iCounterResults = True
3347 for i in addedIValues:
3348 tmpResult = i in iCounters
3349 iCounterResults = iCounterResults and tmpResult
3350 if not tmpResult:
3351 main.log.error( str( i ) + " is not in in-memory "
3352 "counter incremented results" )
3353 utilities.assert_equals( expect=True,
3354 actual=iCounterResults,
3355 onpass="In-memory counter incremented",
3356 onfail="Error incrementing in-memory" +
3357 " counter" )
3358
3359 main.step( "Counters we added have the correct values" )
3360 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3361 utilities.assert_equals( expect=main.TRUE,
3362 actual=incrementCheck,
3363 onpass="Added counters are correct",
3364 onfail="Added counters are incorrect" )
3365
Jon Hall5cf14d52015-07-16 12:15:19 -07003366 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003367 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003368 utilities.assert_equals( expect=main.TRUE,
3369 actual=consistentCounterResults,
3370 onpass="ONOS counters are consistent " +
3371 "across nodes",
3372 onfail="ONOS Counters are inconsistent " +
3373 "across nodes" )
3374
3375 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003376 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3377 incrementCheck = incrementCheck and \
3378 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003379 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003380 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003381 onpass="Added counters are correct",
3382 onfail="Added counters are incorrect" )
3383 # DISTRIBUTED SETS
3384 main.step( "Distributed Set get" )
3385 size = len( onosSet )
3386 getResponses = []
3387 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003388 for i in range( main.numCtrls ):
3389 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003390 name="setTestGet-" + str( i ),
3391 args=[ onosSetName ] )
3392 threads.append( t )
3393 t.start()
3394 for t in threads:
3395 t.join()
3396 getResponses.append( t.result )
3397
3398 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003399 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003400 if isinstance( getResponses[ i ], list):
3401 current = set( getResponses[ i ] )
3402 if len( current ) == len( getResponses[ i ] ):
3403 # no repeats
3404 if onosSet != current:
3405 main.log.error( "ONOS" + str( i + 1 ) +
3406 " has incorrect view" +
3407 " of set " + onosSetName + ":\n" +
3408 str( getResponses[ i ] ) )
3409 main.log.debug( "Expected: " + str( onosSet ) )
3410 main.log.debug( "Actual: " + str( current ) )
3411 getResults = main.FALSE
3412 else:
3413 # error, set is not a set
3414 main.log.error( "ONOS" + str( i + 1 ) +
3415 " has repeat elements in" +
3416 " set " + onosSetName + ":\n" +
3417 str( getResponses[ i ] ) )
3418 getResults = main.FALSE
3419 elif getResponses[ i ] == main.ERROR:
3420 getResults = main.FALSE
3421 utilities.assert_equals( expect=main.TRUE,
3422 actual=getResults,
3423 onpass="Set elements are correct",
3424 onfail="Set elements are incorrect" )
3425
3426 main.step( "Distributed Set size" )
3427 sizeResponses = []
3428 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003429 for i in range( main.numCtrls ):
3430 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003431 name="setTestSize-" + str( i ),
3432 args=[ onosSetName ] )
3433 threads.append( t )
3434 t.start()
3435 for t in threads:
3436 t.join()
3437 sizeResponses.append( t.result )
3438
3439 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003440 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003441 if size != sizeResponses[ i ]:
3442 sizeResults = main.FALSE
3443 main.log.error( "ONOS" + str( i + 1 ) +
3444 " expected a size of " + str( size ) +
3445 " for set " + onosSetName +
3446 " but got " + str( sizeResponses[ i ] ) )
3447 utilities.assert_equals( expect=main.TRUE,
3448 actual=sizeResults,
3449 onpass="Set sizes are correct",
3450 onfail="Set sizes are incorrect" )
3451
3452 main.step( "Distributed Set add()" )
3453 onosSet.add( addValue )
3454 addResponses = []
3455 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003456 for i in range( main.numCtrls ):
3457 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003458 name="setTestAdd-" + str( i ),
3459 args=[ onosSetName, addValue ] )
3460 threads.append( t )
3461 t.start()
3462 for t in threads:
3463 t.join()
3464 addResponses.append( t.result )
3465
3466 # main.TRUE = successfully changed the set
3467 # main.FALSE = action resulted in no change in set
3468 # main.ERROR - Some error in executing the function
3469 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003470 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003471 if addResponses[ i ] == main.TRUE:
3472 # All is well
3473 pass
3474 elif addResponses[ i ] == main.FALSE:
3475 # Already in set, probably fine
3476 pass
3477 elif addResponses[ i ] == main.ERROR:
3478 # Error in execution
3479 addResults = main.FALSE
3480 else:
3481 # unexpected result
3482 addResults = main.FALSE
3483 if addResults != main.TRUE:
3484 main.log.error( "Error executing set add" )
3485
3486 # Check if set is still correct
3487 size = len( onosSet )
3488 getResponses = []
3489 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003490 for i in range( main.numCtrls ):
3491 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003492 name="setTestGet-" + str( i ),
3493 args=[ onosSetName ] )
3494 threads.append( t )
3495 t.start()
3496 for t in threads:
3497 t.join()
3498 getResponses.append( t.result )
3499 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003500 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003501 if isinstance( getResponses[ i ], list):
3502 current = set( getResponses[ i ] )
3503 if len( current ) == len( getResponses[ i ] ):
3504 # no repeats
3505 if onosSet != current:
3506 main.log.error( "ONOS" + str( i + 1 ) +
3507 " has incorrect view" +
3508 " of set " + onosSetName + ":\n" +
3509 str( getResponses[ i ] ) )
3510 main.log.debug( "Expected: " + str( onosSet ) )
3511 main.log.debug( "Actual: " + str( current ) )
3512 getResults = main.FALSE
3513 else:
3514 # error, set is not a set
3515 main.log.error( "ONOS" + str( i + 1 ) +
3516 " has repeat elements in" +
3517 " set " + onosSetName + ":\n" +
3518 str( getResponses[ i ] ) )
3519 getResults = main.FALSE
3520 elif getResponses[ i ] == main.ERROR:
3521 getResults = main.FALSE
3522 sizeResponses = []
3523 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003524 for i in range( main.numCtrls ):
3525 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003526 name="setTestSize-" + str( i ),
3527 args=[ onosSetName ] )
3528 threads.append( t )
3529 t.start()
3530 for t in threads:
3531 t.join()
3532 sizeResponses.append( t.result )
3533 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003534 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003535 if size != sizeResponses[ i ]:
3536 sizeResults = main.FALSE
3537 main.log.error( "ONOS" + str( i + 1 ) +
3538 " expected a size of " + str( size ) +
3539 " for set " + onosSetName +
3540 " but got " + str( sizeResponses[ i ] ) )
3541 addResults = addResults and getResults and sizeResults
3542 utilities.assert_equals( expect=main.TRUE,
3543 actual=addResults,
3544 onpass="Set add correct",
3545 onfail="Set add was incorrect" )
3546
3547 main.step( "Distributed Set addAll()" )
3548 onosSet.update( addAllValue.split() )
3549 addResponses = []
3550 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003551 for i in range( main.numCtrls ):
3552 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003553 name="setTestAddAll-" + str( i ),
3554 args=[ onosSetName, addAllValue ] )
3555 threads.append( t )
3556 t.start()
3557 for t in threads:
3558 t.join()
3559 addResponses.append( t.result )
3560
3561 # main.TRUE = successfully changed the set
3562 # main.FALSE = action resulted in no change in set
3563 # main.ERROR - Some error in executing the function
3564 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003565 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003566 if addResponses[ i ] == main.TRUE:
3567 # All is well
3568 pass
3569 elif addResponses[ i ] == main.FALSE:
3570 # Already in set, probably fine
3571 pass
3572 elif addResponses[ i ] == main.ERROR:
3573 # Error in execution
3574 addAllResults = main.FALSE
3575 else:
3576 # unexpected result
3577 addAllResults = main.FALSE
3578 if addAllResults != main.TRUE:
3579 main.log.error( "Error executing set addAll" )
3580
3581 # Check if set is still correct
3582 size = len( onosSet )
3583 getResponses = []
3584 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003585 for i in range( main.numCtrls ):
3586 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003587 name="setTestGet-" + str( i ),
3588 args=[ onosSetName ] )
3589 threads.append( t )
3590 t.start()
3591 for t in threads:
3592 t.join()
3593 getResponses.append( t.result )
3594 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003595 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003596 if isinstance( getResponses[ i ], list):
3597 current = set( getResponses[ i ] )
3598 if len( current ) == len( getResponses[ i ] ):
3599 # no repeats
3600 if onosSet != current:
3601 main.log.error( "ONOS" + str( i + 1 ) +
3602 " has incorrect view" +
3603 " of set " + onosSetName + ":\n" +
3604 str( getResponses[ i ] ) )
3605 main.log.debug( "Expected: " + str( onosSet ) )
3606 main.log.debug( "Actual: " + str( current ) )
3607 getResults = main.FALSE
3608 else:
3609 # error, set is not a set
3610 main.log.error( "ONOS" + str( i + 1 ) +
3611 " has repeat elements in" +
3612 " set " + onosSetName + ":\n" +
3613 str( getResponses[ i ] ) )
3614 getResults = main.FALSE
3615 elif getResponses[ i ] == main.ERROR:
3616 getResults = main.FALSE
3617 sizeResponses = []
3618 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003619 for i in range( main.numCtrls ):
3620 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003621 name="setTestSize-" + str( i ),
3622 args=[ onosSetName ] )
3623 threads.append( t )
3624 t.start()
3625 for t in threads:
3626 t.join()
3627 sizeResponses.append( t.result )
3628 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003629 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003630 if size != sizeResponses[ i ]:
3631 sizeResults = main.FALSE
3632 main.log.error( "ONOS" + str( i + 1 ) +
3633 " expected a size of " + str( size ) +
3634 " for set " + onosSetName +
3635 " but got " + str( sizeResponses[ i ] ) )
3636 addAllResults = addAllResults and getResults and sizeResults
3637 utilities.assert_equals( expect=main.TRUE,
3638 actual=addAllResults,
3639 onpass="Set addAll correct",
3640 onfail="Set addAll was incorrect" )
3641
3642 main.step( "Distributed Set contains()" )
3643 containsResponses = []
3644 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003645 for i in range( main.numCtrls ):
3646 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003647 name="setContains-" + str( i ),
3648 args=[ onosSetName ],
3649 kwargs={ "values": addValue } )
3650 threads.append( t )
3651 t.start()
3652 for t in threads:
3653 t.join()
3654 # NOTE: This is the tuple
3655 containsResponses.append( t.result )
3656
3657 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003658 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003659 if containsResponses[ i ] == main.ERROR:
3660 containsResults = main.FALSE
3661 else:
3662 containsResults = containsResults and\
3663 containsResponses[ i ][ 1 ]
3664 utilities.assert_equals( expect=main.TRUE,
3665 actual=containsResults,
3666 onpass="Set contains is functional",
3667 onfail="Set contains failed" )
3668
3669 main.step( "Distributed Set containsAll()" )
3670 containsAllResponses = []
3671 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003672 for i in range( main.numCtrls ):
3673 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003674 name="setContainsAll-" + str( i ),
3675 args=[ onosSetName ],
3676 kwargs={ "values": addAllValue } )
3677 threads.append( t )
3678 t.start()
3679 for t in threads:
3680 t.join()
3681 # NOTE: This is the tuple
3682 containsAllResponses.append( t.result )
3683
3684 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003685 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003686 if containsResponses[ i ] == main.ERROR:
3687 containsResults = main.FALSE
3688 else:
3689 containsResults = containsResults and\
3690 containsResponses[ i ][ 1 ]
3691 utilities.assert_equals( expect=main.TRUE,
3692 actual=containsAllResults,
3693 onpass="Set containsAll is functional",
3694 onfail="Set containsAll failed" )
3695
3696 main.step( "Distributed Set remove()" )
3697 onosSet.remove( addValue )
3698 removeResponses = []
3699 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003700 for i in range( main.numCtrls ):
3701 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003702 name="setTestRemove-" + str( i ),
3703 args=[ onosSetName, addValue ] )
3704 threads.append( t )
3705 t.start()
3706 for t in threads:
3707 t.join()
3708 removeResponses.append( t.result )
3709
3710 # main.TRUE = successfully changed the set
3711 # main.FALSE = action resulted in no change in set
3712 # main.ERROR - Some error in executing the function
3713 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003714 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003715 if removeResponses[ i ] == main.TRUE:
3716 # All is well
3717 pass
3718 elif removeResponses[ i ] == main.FALSE:
3719 # not in set, probably fine
3720 pass
3721 elif removeResponses[ i ] == main.ERROR:
3722 # Error in execution
3723 removeResults = main.FALSE
3724 else:
3725 # unexpected result
3726 removeResults = main.FALSE
3727 if removeResults != main.TRUE:
3728 main.log.error( "Error executing set remove" )
3729
3730 # Check if set is still correct
3731 size = len( onosSet )
3732 getResponses = []
3733 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003734 for i in range( main.numCtrls ):
3735 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003736 name="setTestGet-" + str( i ),
3737 args=[ onosSetName ] )
3738 threads.append( t )
3739 t.start()
3740 for t in threads:
3741 t.join()
3742 getResponses.append( t.result )
3743 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003744 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003745 if isinstance( getResponses[ i ], list):
3746 current = set( getResponses[ i ] )
3747 if len( current ) == len( getResponses[ i ] ):
3748 # no repeats
3749 if onosSet != current:
3750 main.log.error( "ONOS" + str( i + 1 ) +
3751 " has incorrect view" +
3752 " of set " + onosSetName + ":\n" +
3753 str( getResponses[ i ] ) )
3754 main.log.debug( "Expected: " + str( onosSet ) )
3755 main.log.debug( "Actual: " + str( current ) )
3756 getResults = main.FALSE
3757 else:
3758 # error, set is not a set
3759 main.log.error( "ONOS" + str( i + 1 ) +
3760 " has repeat elements in" +
3761 " set " + onosSetName + ":\n" +
3762 str( getResponses[ i ] ) )
3763 getResults = main.FALSE
3764 elif getResponses[ i ] == main.ERROR:
3765 getResults = main.FALSE
3766 sizeResponses = []
3767 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003768 for i in range( main.numCtrls ):
3769 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003770 name="setTestSize-" + str( i ),
3771 args=[ onosSetName ] )
3772 threads.append( t )
3773 t.start()
3774 for t in threads:
3775 t.join()
3776 sizeResponses.append( t.result )
3777 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003778 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003779 if size != sizeResponses[ i ]:
3780 sizeResults = main.FALSE
3781 main.log.error( "ONOS" + str( i + 1 ) +
3782 " expected a size of " + str( size ) +
3783 " for set " + onosSetName +
3784 " but got " + str( sizeResponses[ i ] ) )
3785 removeResults = removeResults and getResults and sizeResults
3786 utilities.assert_equals( expect=main.TRUE,
3787 actual=removeResults,
3788 onpass="Set remove correct",
3789 onfail="Set remove was incorrect" )
3790
3791 main.step( "Distributed Set removeAll()" )
3792 onosSet.difference_update( addAllValue.split() )
3793 removeAllResponses = []
3794 threads = []
3795 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003796 for i in range( main.numCtrls ):
3797 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003798 name="setTestRemoveAll-" + str( i ),
3799 args=[ onosSetName, addAllValue ] )
3800 threads.append( t )
3801 t.start()
3802 for t in threads:
3803 t.join()
3804 removeAllResponses.append( t.result )
3805 except Exception, e:
3806 main.log.exception(e)
3807
3808 # main.TRUE = successfully changed the set
3809 # main.FALSE = action resulted in no change in set
3810 # main.ERROR - Some error in executing the function
3811 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003812 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003813 if removeAllResponses[ i ] == main.TRUE:
3814 # All is well
3815 pass
3816 elif removeAllResponses[ i ] == main.FALSE:
3817 # not in set, probably fine
3818 pass
3819 elif removeAllResponses[ i ] == main.ERROR:
3820 # Error in execution
3821 removeAllResults = main.FALSE
3822 else:
3823 # unexpected result
3824 removeAllResults = main.FALSE
3825 if removeAllResults != main.TRUE:
3826 main.log.error( "Error executing set removeAll" )
3827
3828 # Check if set is still correct
3829 size = len( onosSet )
3830 getResponses = []
3831 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003832 for i in range( main.numCtrls ):
3833 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003834 name="setTestGet-" + str( i ),
3835 args=[ onosSetName ] )
3836 threads.append( t )
3837 t.start()
3838 for t in threads:
3839 t.join()
3840 getResponses.append( t.result )
3841 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003842 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003843 if isinstance( getResponses[ i ], list):
3844 current = set( getResponses[ i ] )
3845 if len( current ) == len( getResponses[ i ] ):
3846 # no repeats
3847 if onosSet != current:
3848 main.log.error( "ONOS" + str( i + 1 ) +
3849 " has incorrect view" +
3850 " of set " + onosSetName + ":\n" +
3851 str( getResponses[ i ] ) )
3852 main.log.debug( "Expected: " + str( onosSet ) )
3853 main.log.debug( "Actual: " + str( current ) )
3854 getResults = main.FALSE
3855 else:
3856 # error, set is not a set
3857 main.log.error( "ONOS" + str( i + 1 ) +
3858 " has repeat elements in" +
3859 " set " + onosSetName + ":\n" +
3860 str( getResponses[ i ] ) )
3861 getResults = main.FALSE
3862 elif getResponses[ i ] == main.ERROR:
3863 getResults = main.FALSE
3864 sizeResponses = []
3865 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003866 for i in range( main.numCtrls ):
3867 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003868 name="setTestSize-" + str( i ),
3869 args=[ onosSetName ] )
3870 threads.append( t )
3871 t.start()
3872 for t in threads:
3873 t.join()
3874 sizeResponses.append( t.result )
3875 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003876 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003877 if size != sizeResponses[ i ]:
3878 sizeResults = main.FALSE
3879 main.log.error( "ONOS" + str( i + 1 ) +
3880 " expected a size of " + str( size ) +
3881 " for set " + onosSetName +
3882 " but got " + str( sizeResponses[ i ] ) )
3883 removeAllResults = removeAllResults and getResults and sizeResults
3884 utilities.assert_equals( expect=main.TRUE,
3885 actual=removeAllResults,
3886 onpass="Set removeAll correct",
3887 onfail="Set removeAll was incorrect" )
3888
3889 main.step( "Distributed Set addAll()" )
3890 onosSet.update( addAllValue.split() )
3891 addResponses = []
3892 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003893 for i in range( main.numCtrls ):
3894 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003895 name="setTestAddAll-" + str( i ),
3896 args=[ onosSetName, addAllValue ] )
3897 threads.append( t )
3898 t.start()
3899 for t in threads:
3900 t.join()
3901 addResponses.append( t.result )
3902
3903 # main.TRUE = successfully changed the set
3904 # main.FALSE = action resulted in no change in set
3905 # main.ERROR - Some error in executing the function
3906 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003907 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003908 if addResponses[ i ] == main.TRUE:
3909 # All is well
3910 pass
3911 elif addResponses[ i ] == main.FALSE:
3912 # Already in set, probably fine
3913 pass
3914 elif addResponses[ i ] == main.ERROR:
3915 # Error in execution
3916 addAllResults = main.FALSE
3917 else:
3918 # unexpected result
3919 addAllResults = main.FALSE
3920 if addAllResults != main.TRUE:
3921 main.log.error( "Error executing set addAll" )
3922
3923 # Check if set is still correct
3924 size = len( onosSet )
3925 getResponses = []
3926 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003927 for i in range( main.numCtrls ):
3928 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003929 name="setTestGet-" + str( i ),
3930 args=[ onosSetName ] )
3931 threads.append( t )
3932 t.start()
3933 for t in threads:
3934 t.join()
3935 getResponses.append( t.result )
3936 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003937 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003938 if isinstance( getResponses[ i ], list):
3939 current = set( getResponses[ i ] )
3940 if len( current ) == len( getResponses[ i ] ):
3941 # no repeats
3942 if onosSet != current:
3943 main.log.error( "ONOS" + str( i + 1 ) +
3944 " has incorrect view" +
3945 " of set " + onosSetName + ":\n" +
3946 str( getResponses[ i ] ) )
3947 main.log.debug( "Expected: " + str( onosSet ) )
3948 main.log.debug( "Actual: " + str( current ) )
3949 getResults = main.FALSE
3950 else:
3951 # error, set is not a set
3952 main.log.error( "ONOS" + str( i + 1 ) +
3953 " has repeat elements in" +
3954 " set " + onosSetName + ":\n" +
3955 str( getResponses[ i ] ) )
3956 getResults = main.FALSE
3957 elif getResponses[ i ] == main.ERROR:
3958 getResults = main.FALSE
3959 sizeResponses = []
3960 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003961 for i in range( main.numCtrls ):
3962 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003963 name="setTestSize-" + str( i ),
3964 args=[ onosSetName ] )
3965 threads.append( t )
3966 t.start()
3967 for t in threads:
3968 t.join()
3969 sizeResponses.append( t.result )
3970 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003971 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003972 if size != sizeResponses[ i ]:
3973 sizeResults = main.FALSE
3974 main.log.error( "ONOS" + str( i + 1 ) +
3975 " expected a size of " + str( size ) +
3976 " for set " + onosSetName +
3977 " but got " + str( sizeResponses[ i ] ) )
3978 addAllResults = addAllResults and getResults and sizeResults
3979 utilities.assert_equals( expect=main.TRUE,
3980 actual=addAllResults,
3981 onpass="Set addAll correct",
3982 onfail="Set addAll was incorrect" )
3983
3984 main.step( "Distributed Set clear()" )
3985 onosSet.clear()
3986 clearResponses = []
3987 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003988 for i in range( main.numCtrls ):
3989 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003990 name="setTestClear-" + str( i ),
3991 args=[ onosSetName, " "], # Values doesn't matter
3992 kwargs={ "clear": True } )
3993 threads.append( t )
3994 t.start()
3995 for t in threads:
3996 t.join()
3997 clearResponses.append( t.result )
3998
3999 # main.TRUE = successfully changed the set
4000 # main.FALSE = action resulted in no change in set
4001 # main.ERROR - Some error in executing the function
4002 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004003 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004004 if clearResponses[ i ] == main.TRUE:
4005 # All is well
4006 pass
4007 elif clearResponses[ i ] == main.FALSE:
4008 # Nothing set, probably fine
4009 pass
4010 elif clearResponses[ i ] == main.ERROR:
4011 # Error in execution
4012 clearResults = main.FALSE
4013 else:
4014 # unexpected result
4015 clearResults = main.FALSE
4016 if clearResults != main.TRUE:
4017 main.log.error( "Error executing set clear" )
4018
4019 # Check if set is still correct
4020 size = len( onosSet )
4021 getResponses = []
4022 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004023 for i in range( main.numCtrls ):
4024 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004025 name="setTestGet-" + str( i ),
4026 args=[ onosSetName ] )
4027 threads.append( t )
4028 t.start()
4029 for t in threads:
4030 t.join()
4031 getResponses.append( t.result )
4032 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004033 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004034 if isinstance( getResponses[ i ], list):
4035 current = set( getResponses[ i ] )
4036 if len( current ) == len( getResponses[ i ] ):
4037 # no repeats
4038 if onosSet != current:
4039 main.log.error( "ONOS" + str( i + 1 ) +
4040 " has incorrect view" +
4041 " of set " + onosSetName + ":\n" +
4042 str( getResponses[ i ] ) )
4043 main.log.debug( "Expected: " + str( onosSet ) )
4044 main.log.debug( "Actual: " + str( current ) )
4045 getResults = main.FALSE
4046 else:
4047 # error, set is not a set
4048 main.log.error( "ONOS" + str( i + 1 ) +
4049 " has repeat elements in" +
4050 " set " + onosSetName + ":\n" +
4051 str( getResponses[ i ] ) )
4052 getResults = main.FALSE
4053 elif getResponses[ i ] == main.ERROR:
4054 getResults = main.FALSE
4055 sizeResponses = []
4056 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004057 for i in range( main.numCtrls ):
4058 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004059 name="setTestSize-" + str( i ),
4060 args=[ onosSetName ] )
4061 threads.append( t )
4062 t.start()
4063 for t in threads:
4064 t.join()
4065 sizeResponses.append( t.result )
4066 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004067 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004068 if size != sizeResponses[ i ]:
4069 sizeResults = main.FALSE
4070 main.log.error( "ONOS" + str( i + 1 ) +
4071 " expected a size of " + str( size ) +
4072 " for set " + onosSetName +
4073 " but got " + str( sizeResponses[ i ] ) )
4074 clearResults = clearResults and getResults and sizeResults
4075 utilities.assert_equals( expect=main.TRUE,
4076 actual=clearResults,
4077 onpass="Set clear correct",
4078 onfail="Set clear was incorrect" )
4079
4080 main.step( "Distributed Set addAll()" )
4081 onosSet.update( addAllValue.split() )
4082 addResponses = []
4083 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004084 for i in range( main.numCtrls ):
4085 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004086 name="setTestAddAll-" + str( i ),
4087 args=[ onosSetName, addAllValue ] )
4088 threads.append( t )
4089 t.start()
4090 for t in threads:
4091 t.join()
4092 addResponses.append( t.result )
4093
4094 # main.TRUE = successfully changed the set
4095 # main.FALSE = action resulted in no change in set
4096 # main.ERROR - Some error in executing the function
4097 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004098 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004099 if addResponses[ i ] == main.TRUE:
4100 # All is well
4101 pass
4102 elif addResponses[ i ] == main.FALSE:
4103 # Already in set, probably fine
4104 pass
4105 elif addResponses[ i ] == main.ERROR:
4106 # Error in execution
4107 addAllResults = main.FALSE
4108 else:
4109 # unexpected result
4110 addAllResults = main.FALSE
4111 if addAllResults != main.TRUE:
4112 main.log.error( "Error executing set addAll" )
4113
4114 # Check if set is still correct
4115 size = len( onosSet )
4116 getResponses = []
4117 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004118 for i in range( main.numCtrls ):
4119 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004120 name="setTestGet-" + str( i ),
4121 args=[ onosSetName ] )
4122 threads.append( t )
4123 t.start()
4124 for t in threads:
4125 t.join()
4126 getResponses.append( t.result )
4127 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004128 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004129 if isinstance( getResponses[ i ], list):
4130 current = set( getResponses[ i ] )
4131 if len( current ) == len( getResponses[ i ] ):
4132 # no repeats
4133 if onosSet != current:
4134 main.log.error( "ONOS" + str( i + 1 ) +
4135 " has incorrect view" +
4136 " of set " + onosSetName + ":\n" +
4137 str( getResponses[ i ] ) )
4138 main.log.debug( "Expected: " + str( onosSet ) )
4139 main.log.debug( "Actual: " + str( current ) )
4140 getResults = main.FALSE
4141 else:
4142 # error, set is not a set
4143 main.log.error( "ONOS" + str( i + 1 ) +
4144 " has repeat elements in" +
4145 " set " + onosSetName + ":\n" +
4146 str( getResponses[ i ] ) )
4147 getResults = main.FALSE
4148 elif getResponses[ i ] == main.ERROR:
4149 getResults = main.FALSE
4150 sizeResponses = []
4151 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004152 for i in range( main.numCtrls ):
4153 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004154 name="setTestSize-" + str( i ),
4155 args=[ onosSetName ] )
4156 threads.append( t )
4157 t.start()
4158 for t in threads:
4159 t.join()
4160 sizeResponses.append( t.result )
4161 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004162 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004163 if size != sizeResponses[ i ]:
4164 sizeResults = main.FALSE
4165 main.log.error( "ONOS" + str( i + 1 ) +
4166 " expected a size of " + str( size ) +
4167 " for set " + onosSetName +
4168 " but got " + str( sizeResponses[ i ] ) )
4169 addAllResults = addAllResults and getResults and sizeResults
4170 utilities.assert_equals( expect=main.TRUE,
4171 actual=addAllResults,
4172 onpass="Set addAll correct",
4173 onfail="Set addAll was incorrect" )
4174
4175 main.step( "Distributed Set retain()" )
4176 onosSet.intersection_update( retainValue.split() )
4177 retainResponses = []
4178 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004179 for i in range( main.numCtrls ):
4180 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004181 name="setTestRetain-" + str( i ),
4182 args=[ onosSetName, retainValue ],
4183 kwargs={ "retain": True } )
4184 threads.append( t )
4185 t.start()
4186 for t in threads:
4187 t.join()
4188 retainResponses.append( t.result )
4189
4190 # main.TRUE = successfully changed the set
4191 # main.FALSE = action resulted in no change in set
4192 # main.ERROR - Some error in executing the function
4193 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004194 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004195 if retainResponses[ i ] == main.TRUE:
4196 # All is well
4197 pass
4198 elif retainResponses[ i ] == main.FALSE:
4199 # Already in set, probably fine
4200 pass
4201 elif retainResponses[ i ] == main.ERROR:
4202 # Error in execution
4203 retainResults = main.FALSE
4204 else:
4205 # unexpected result
4206 retainResults = main.FALSE
4207 if retainResults != main.TRUE:
4208 main.log.error( "Error executing set retain" )
4209
4210 # Check if set is still correct
4211 size = len( onosSet )
4212 getResponses = []
4213 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004214 for i in range( main.numCtrls ):
4215 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004216 name="setTestGet-" + str( i ),
4217 args=[ onosSetName ] )
4218 threads.append( t )
4219 t.start()
4220 for t in threads:
4221 t.join()
4222 getResponses.append( t.result )
4223 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004224 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004225 if isinstance( getResponses[ i ], list):
4226 current = set( getResponses[ i ] )
4227 if len( current ) == len( getResponses[ i ] ):
4228 # no repeats
4229 if onosSet != current:
4230 main.log.error( "ONOS" + str( i + 1 ) +
4231 " has incorrect view" +
4232 " of set " + onosSetName + ":\n" +
4233 str( getResponses[ i ] ) )
4234 main.log.debug( "Expected: " + str( onosSet ) )
4235 main.log.debug( "Actual: " + str( current ) )
4236 getResults = main.FALSE
4237 else:
4238 # error, set is not a set
4239 main.log.error( "ONOS" + str( i + 1 ) +
4240 " has repeat elements in" +
4241 " set " + onosSetName + ":\n" +
4242 str( getResponses[ i ] ) )
4243 getResults = main.FALSE
4244 elif getResponses[ i ] == main.ERROR:
4245 getResults = main.FALSE
4246 sizeResponses = []
4247 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004248 for i in range( main.numCtrls ):
4249 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004250 name="setTestSize-" + str( i ),
4251 args=[ onosSetName ] )
4252 threads.append( t )
4253 t.start()
4254 for t in threads:
4255 t.join()
4256 sizeResponses.append( t.result )
4257 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004258 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004259 if size != sizeResponses[ i ]:
4260 sizeResults = main.FALSE
4261 main.log.error( "ONOS" + str( i + 1 ) +
4262 " expected a size of " +
4263 str( size ) + " for set " + onosSetName +
4264 " but got " + str( sizeResponses[ i ] ) )
4265 retainResults = retainResults and getResults and sizeResults
4266 utilities.assert_equals( expect=main.TRUE,
4267 actual=retainResults,
4268 onpass="Set retain correct",
4269 onfail="Set retain was incorrect" )
4270
Jon Hall2a5002c2015-08-21 16:49:11 -07004271 # Transactional maps
4272 main.step( "Partitioned Transactional maps put" )
4273 tMapValue = "Testing"
4274 numKeys = 100
4275 putResult = True
4276 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4277 if len( putResponses ) == 100:
4278 for i in putResponses:
4279 if putResponses[ i ][ 'value' ] != tMapValue:
4280 putResult = False
4281 else:
4282 putResult = False
4283 if not putResult:
4284 main.log.debug( "Put response values: " + str( putResponses ) )
4285 utilities.assert_equals( expect=True,
4286 actual=putResult,
4287 onpass="Partitioned Transactional Map put successful",
4288 onfail="Partitioned Transactional Map put values are incorrect" )
4289
4290 main.step( "Partitioned Transactional maps get" )
4291 getCheck = True
4292 for n in range( 1, numKeys + 1 ):
4293 getResponses = []
4294 threads = []
4295 valueCheck = True
4296 for i in range( main.numCtrls ):
4297 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4298 name="TMap-get-" + str( i ),
4299 args=[ "Key" + str ( n ) ] )
4300 threads.append( t )
4301 t.start()
4302 for t in threads:
4303 t.join()
4304 getResponses.append( t.result )
4305 for node in getResponses:
4306 if node != tMapValue:
4307 valueCheck = False
4308 if not valueCheck:
4309 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4310 main.log.warn( getResponses )
4311 getCheck = getCheck and valueCheck
4312 utilities.assert_equals( expect=True,
4313 actual=getCheck,
4314 onpass="Partitioned Transactional Map get values were correct",
4315 onfail="Partitioned Transactional Map values incorrect" )
4316
4317 main.step( "In-memory Transactional maps put" )
4318 tMapValue = "Testing"
4319 numKeys = 100
4320 putResult = True
4321 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4322 if len( putResponses ) == 100:
4323 for i in putResponses:
4324 if putResponses[ i ][ 'value' ] != tMapValue:
4325 putResult = False
4326 else:
4327 putResult = False
4328 if not putResult:
4329 main.log.debug( "Put response values: " + str( putResponses ) )
4330 utilities.assert_equals( expect=True,
4331 actual=putResult,
4332 onpass="In-Memory Transactional Map put successful",
4333 onfail="In-Memory Transactional Map put values are incorrect" )
4334
4335 main.step( "In-Memory Transactional maps get" )
4336 getCheck = True
4337 for n in range( 1, numKeys + 1 ):
4338 getResponses = []
4339 threads = []
4340 valueCheck = True
4341 for i in range( main.numCtrls ):
4342 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4343 name="TMap-get-" + str( i ),
4344 args=[ "Key" + str ( n ) ],
4345 kwargs={ "inMemory": True } )
4346 threads.append( t )
4347 t.start()
4348 for t in threads:
4349 t.join()
4350 getResponses.append( t.result )
4351 for node in getResponses:
4352 if node != tMapValue:
4353 valueCheck = False
4354 if not valueCheck:
4355 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4356 main.log.warn( getResponses )
4357 getCheck = getCheck and valueCheck
4358 utilities.assert_equals( expect=True,
4359 actual=getCheck,
4360 onpass="In-Memory Transactional Map get values were correct",
4361 onfail="In-Memory Transactional Map values incorrect" )