blob: 5768a2d36b0588c1286842cf0407fc4f9a3000e2 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
Jon Hallb3ed8ed2015-10-28 16:43:55 -070012CASE61: The Failure inducing case.
13CASE62: The Failure recovery case.
Jon Hall5cf14d52015-07-16 12:15:19 -070014CASE7: 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
Jon Hallb3ed8ed2015-10-28 16:43:55 -070028class HAkillNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -070029
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 Hallf3d16e72015-12-16 17:45:08 -080052 import time
Jon Hall3b489db2015-10-05 14:38:37 -070053 import pexpect
Jon Hall5cf14d52015-07-16 12:15:19 -070054 main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
55 "initialization" )
56 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070057 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070058 "installing ONOS, starting Mininet and ONOS" +\
59 "cli sessions."
60 # TODO: save all the timers and output them for plotting
61
62 # load some variables from the params file
63 PULLCODE = False
64 if main.params[ 'Git' ] == 'True':
65 PULLCODE = True
66 gitBranch = main.params[ 'branch' ]
67 cellName = main.params[ 'ENV' ][ 'cellName' ]
68
Jon Halle1a3b752015-07-22 13:02:46 -070069 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070070 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070071 if main.ONOSbench.maxNodes < main.numCtrls:
72 main.numCtrls = int( main.ONOSbench.maxNodes )
73 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070074 global ONOS1Port
75 global ONOS2Port
76 global ONOS3Port
77 global ONOS4Port
78 global ONOS5Port
79 global ONOS6Port
80 global ONOS7Port
81
82 # FIXME: just get controller port from params?
83 # TODO: do we really need all these?
84 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
85 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
86 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
87 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
88 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
89 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
90 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
91
Jon Halle1a3b752015-07-22 13:02:46 -070092 try:
93 fileName = "Counters"
94 # TODO: Maybe make a library folder somewhere?
95 path = main.params[ 'imports' ][ 'path' ]
96 main.Counters = imp.load_source( fileName,
97 path + fileName + ".py" )
98 except Exception as e:
99 main.log.exception( e )
100 main.cleanup()
101 main.exit()
102
103 main.CLIs = []
104 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700105 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700106 for i in range( 1, main.numCtrls + 1 ):
107 try:
108 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
109 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
110 ipList.append( main.nodes[ -1 ].ip_address )
111 except AttributeError:
112 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700113
114 main.step( "Create cell file" )
115 cellAppString = main.params[ 'ENV' ][ 'appString' ]
116 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
117 main.Mininet1.ip_address,
118 cellAppString, ipList )
119 main.step( "Applying cell variable to environment" )
120 cellResult = main.ONOSbench.setCell( cellName )
121 verifyResult = main.ONOSbench.verifyCell()
122
123 # FIXME:this is short term fix
124 main.log.info( "Removing raft logs" )
125 main.ONOSbench.onosRemoveRaftLogs()
126
127 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700128 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700129 main.ONOSbench.onosUninstall( node.ip_address )
130
131 # Make sure ONOS is DEAD
132 main.log.info( "Killing any ONOS processes" )
133 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700134 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700135 killed = main.ONOSbench.onosKill( node.ip_address )
136 killResults = killResults and killed
137
138 cleanInstallResult = main.TRUE
139 gitPullResult = main.TRUE
140
141 main.step( "Starting Mininet" )
142 # scp topo file to mininet
143 # TODO: move to params?
144 topoName = "obelisk.py"
145 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700146 main.ONOSbench.scp( main.Mininet1,
147 filePath + topoName,
148 main.Mininet1.home,
149 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700150 mnResult = main.Mininet1.startNet( )
151 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
152 onpass="Mininet Started",
153 onfail="Error starting Mininet" )
154
155 main.step( "Git checkout and pull " + gitBranch )
156 if PULLCODE:
157 main.ONOSbench.gitCheckout( gitBranch )
158 gitPullResult = main.ONOSbench.gitPull()
159 # values of 1 or 3 are good
160 utilities.assert_lesser( expect=0, actual=gitPullResult,
161 onpass="Git pull successful",
162 onfail="Git pull failed" )
163 main.ONOSbench.getVersion( report=True )
164
165 main.step( "Using mvn clean install" )
166 cleanInstallResult = main.TRUE
167 if PULLCODE and gitPullResult == main.TRUE:
168 cleanInstallResult = main.ONOSbench.cleanInstall()
169 else:
170 main.log.warn( "Did not pull new code so skipping mvn " +
171 "clean install" )
172 utilities.assert_equals( expect=main.TRUE,
173 actual=cleanInstallResult,
174 onpass="MCI successful",
175 onfail="MCI failed" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700176
177 main.step( "Make sure ONOS service doesn't automatically respawn" )
178 handle = main.ONOSbench.handle
179 handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
180 handle.expect( "\$" ) # $ from the command
181 handle.expect( "\$" ) # $ from the prompt
182
Jon Hall5cf14d52015-07-16 12:15:19 -0700183 # GRAPHS
184 # NOTE: important params here:
185 # job = name of Jenkins job
186 # Plot Name = Plot-HA, only can be used if multiple plots
187 # index = The number of the graph under plot name
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700188 job = "HAkillNodes"
Jon Hall5cf14d52015-07-16 12:15:19 -0700189 plotName = "Plot-HA"
190 graphs = '<ac:structured-macro ac:name="html">\n'
191 graphs += '<ac:plain-text-body><![CDATA[\n'
192 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
193 '/plot/' + plotName + '/getPlot?index=0' +\
194 '&width=500&height=300"' +\
195 'noborder="0" width="500" height="300" scrolling="yes" ' +\
196 'seamless="seamless"></iframe>\n'
197 graphs += ']]></ac:plain-text-body>\n'
198 graphs += '</ac:structured-macro>\n'
199 main.log.wiki(graphs)
200
201 main.step( "Creating ONOS package" )
Jon Hall3b489db2015-10-05 14:38:37 -0700202 # copy gen-partions file to ONOS
203 # NOTE: this assumes TestON and ONOS are on the same machine
204 srcFile = main.testDir + "/" + main.TEST + "/dependencies/onos-gen-partitions"
205 dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
206 cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
207 main.ONOSbench.ip_address,
208 srcFile,
209 dstDir,
210 pwd=main.ONOSbench.pwd,
211 direction="from" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700212 packageResult = main.ONOSbench.onosPackage()
213 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
214 onpass="ONOS package successful",
215 onfail="ONOS package failed" )
216
217 main.step( "Installing ONOS package" )
218 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700219 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700220 tmpResult = main.ONOSbench.onosInstall( options="-f",
221 node=node.ip_address )
222 onosInstallResult = onosInstallResult and tmpResult
223 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
224 onpass="ONOS install successful",
225 onfail="ONOS install failed" )
Jon Hall3b489db2015-10-05 14:38:37 -0700226 # clean up gen-partitions file
227 try:
228 main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
229 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
230 main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
231 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
232 main.log.info( " Cleaning custom gen partitions file, response was: \n" +
233 str( main.ONOSbench.handle.before ) )
234 except ( pexpect.TIMEOUT, pexpect.EOF ):
235 main.log.exception( "ONOSbench: pexpect exception found:" +
236 main.ONOSbench.handle.before )
237 main.cleanup()
238 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -0700239
240 main.step( "Checking if ONOS is up yet" )
241 for i in range( 2 ):
242 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700243 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700244 started = main.ONOSbench.isup( node.ip_address )
245 if not started:
246 main.log.error( node.name + " didn't start!" )
247 main.ONOSbench.onosStop( node.ip_address )
248 main.ONOSbench.onosStart( node.ip_address )
249 onosIsupResult = onosIsupResult and started
250 if onosIsupResult == main.TRUE:
251 break
252 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
253 onpass="ONOS startup successful",
254 onfail="ONOS startup failed" )
255
256 main.log.step( "Starting ONOS CLI sessions" )
257 cliResults = main.TRUE
258 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700259 for i in range( main.numCtrls ):
260 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700261 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700262 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700263 threads.append( t )
264 t.start()
265
266 for t in threads:
267 t.join()
268 cliResults = cliResults and t.result
269 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
270 onpass="ONOS cli startup successful",
271 onfail="ONOS cli startup failed" )
272
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700273 # Create a list of active nodes for use when some nodes are stopped
274 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
275
Jon Hall5cf14d52015-07-16 12:15:19 -0700276 if main.params[ 'tcpdump' ].lower() == "true":
277 main.step( "Start Packet Capture MN" )
278 main.Mininet2.startTcpdump(
279 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
280 + "-MN.pcap",
281 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
282 port=main.params[ 'MNtcpdump' ][ 'port' ] )
283
284 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800285 time.sleep(60)
Jon Hall5cf14d52015-07-16 12:15:19 -0700286 appCheck = main.TRUE
287 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700288 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700289 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700290 name="appToIDCheck-" + str( i ),
291 args=[] )
292 threads.append( t )
293 t.start()
294
295 for t in threads:
296 t.join()
297 appCheck = appCheck and t.result
298 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700299 node = main.activeNodes[0]
300 main.log.warn( main.CLIs[node].apps() )
301 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700302 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
303 onpass="App Ids seem to be correct",
304 onfail="Something is wrong with app Ids" )
305
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700306 main.step( "Clean up ONOS service changes" )
307 handle.sendline( "git checkout -- tools/package/init/onos.conf" )
308 handle.expect( "\$" )
309
Jon Hall5cf14d52015-07-16 12:15:19 -0700310 if cliResults == main.FALSE:
311 main.log.error( "Failed to start ONOS, stopping test" )
312 main.cleanup()
313 main.exit()
314
315 def CASE2( self, main ):
316 """
317 Assign devices to controllers
318 """
319 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700320 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700321 assert main, "main not defined"
322 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700323 assert main.CLIs, "main.CLIs not defined"
324 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700325 assert ONOS1Port, "ONOS1Port not defined"
326 assert ONOS2Port, "ONOS2Port not defined"
327 assert ONOS3Port, "ONOS3Port not defined"
328 assert ONOS4Port, "ONOS4Port not defined"
329 assert ONOS5Port, "ONOS5Port not defined"
330 assert ONOS6Port, "ONOS6Port not defined"
331 assert ONOS7Port, "ONOS7Port not defined"
332
333 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700334 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700335 "and check that an ONOS node becomes the " +\
336 "master of the device."
337 main.step( "Assign switches to controllers" )
338
339 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700340 for i in range( main.numCtrls ):
341 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700342 swList = []
343 for i in range( 1, 29 ):
344 swList.append( "s" + str( i ) )
345 main.Mininet1.assignSwController( sw=swList, ip=ipList )
346
347 mastershipCheck = main.TRUE
348 for i in range( 1, 29 ):
349 response = main.Mininet1.getSwController( "s" + str( i ) )
350 try:
351 main.log.info( str( response ) )
352 except Exception:
353 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700354 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700355 if re.search( "tcp:" + node.ip_address, response ):
356 mastershipCheck = mastershipCheck and main.TRUE
357 else:
358 main.log.error( "Error, node " + node.ip_address + " is " +
359 "not in the list of controllers s" +
360 str( i ) + " is connecting to." )
361 mastershipCheck = main.FALSE
362 utilities.assert_equals(
363 expect=main.TRUE,
364 actual=mastershipCheck,
365 onpass="Switch mastership assigned correctly",
366 onfail="Switches not assigned correctly to controllers" )
367
368 def CASE21( self, main ):
369 """
370 Assign mastership to controllers
371 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700372 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700373 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700374 assert main, "main not defined"
375 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700376 assert main.CLIs, "main.CLIs not defined"
377 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700378 assert ONOS1Port, "ONOS1Port not defined"
379 assert ONOS2Port, "ONOS2Port not defined"
380 assert ONOS3Port, "ONOS3Port not defined"
381 assert ONOS4Port, "ONOS4Port not defined"
382 assert ONOS5Port, "ONOS5Port not defined"
383 assert ONOS6Port, "ONOS6Port not defined"
384 assert ONOS7Port, "ONOS7Port not defined"
385
386 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700387 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700388 "device. Then manually assign" +\
389 " mastership to specific ONOS nodes using" +\
390 " 'device-role'"
391 main.step( "Assign mastership of switches to specific controllers" )
392 # Manually assign mastership to the controller we want
393 roleCall = main.TRUE
394
395 ipList = [ ]
396 deviceList = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700397 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700398 try:
399 # Assign mastership to specific controllers. This assignment was
400 # determined for a 7 node cluser, but will work with any sized
401 # cluster
402 for i in range( 1, 29 ): # switches 1 through 28
403 # set up correct variables:
404 if i == 1:
405 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700406 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700407 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700408 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700409 c = 1 % main.numCtrls
410 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700411 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700412 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700413 c = 1 % main.numCtrls
414 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700415 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700416 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700417 c = 3 % main.numCtrls
418 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700419 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700420 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700421 c = 2 % main.numCtrls
422 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700423 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700424 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700425 c = 2 % main.numCtrls
426 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700427 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700428 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700429 c = 5 % main.numCtrls
430 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700431 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700432 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700433 c = 4 % main.numCtrls
434 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700435 dpid = '3' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700436 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700437 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700438 c = 6 % main.numCtrls
439 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700440 dpid = '6' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700441 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700442 elif i == 28:
443 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700444 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700445 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700446 else:
447 main.log.error( "You didn't write an else statement for " +
448 "switch s" + str( i ) )
449 roleCall = main.FALSE
450 # Assign switch
451 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
452 # TODO: make this controller dynamic
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700453 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700454 ipList.append( ip )
455 deviceList.append( deviceId )
456 except ( AttributeError, AssertionError ):
457 main.log.exception( "Something is wrong with ONOS device view" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700458 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 utilities.assert_equals(
460 expect=main.TRUE,
461 actual=roleCall,
462 onpass="Re-assigned switch mastership to designated controller",
463 onfail="Something wrong with deviceRole calls" )
464
465 main.step( "Check mastership was correctly assigned" )
466 roleCheck = main.TRUE
467 # NOTE: This is due to the fact that device mastership change is not
468 # atomic and is actually a multi step process
469 time.sleep( 5 )
470 for i in range( len( ipList ) ):
471 ip = ipList[i]
472 deviceId = deviceList[i]
473 # Check assignment
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700474 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700475 if ip in master:
476 roleCheck = roleCheck and main.TRUE
477 else:
478 roleCheck = roleCheck and main.FALSE
479 main.log.error( "Error, controller " + ip + " is not" +
480 " master " + "of device " +
481 str( deviceId ) + ". Master is " +
482 repr( master ) + "." )
483 utilities.assert_equals(
484 expect=main.TRUE,
485 actual=roleCheck,
486 onpass="Switches were successfully reassigned to designated " +
487 "controller",
488 onfail="Switches were not successfully reassigned" )
489
490 def CASE3( self, main ):
491 """
492 Assign intents
493 """
494 import time
495 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700496 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700497 assert main, "main not defined"
498 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700499 assert main.CLIs, "main.CLIs not defined"
500 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700501 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700502 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700503 "assign predetermined host-to-host intents." +\
504 " After installation, check that the intent" +\
505 " is distributed to all nodes and the state" +\
506 " is INSTALLED"
507
508 # install onos-app-fwd
509 main.step( "Install reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700510 onosCli = main.CLIs[ main.activeNodes[0] ]
511 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700512 utilities.assert_equals( expect=main.TRUE, actual=installResults,
513 onpass="Install fwd successful",
514 onfail="Install fwd failed" )
515
516 main.step( "Check app ids" )
517 appCheck = main.TRUE
518 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700519 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700520 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700521 name="appToIDCheck-" + str( i ),
522 args=[] )
523 threads.append( t )
524 t.start()
525
526 for t in threads:
527 t.join()
528 appCheck = appCheck and t.result
529 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700530 main.log.warn( onosCli.apps() )
531 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700532 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
533 onpass="App Ids seem to be correct",
534 onfail="Something is wrong with app Ids" )
535
536 main.step( "Discovering Hosts( Via pingall for now )" )
537 # FIXME: Once we have a host discovery mechanism, use that instead
538 # REACTIVE FWD test
539 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700540 passMsg = "Reactive Pingall test passed"
541 time1 = time.time()
542 pingResult = main.Mininet1.pingall()
543 time2 = time.time()
544 if not pingResult:
545 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700546 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700547 passMsg += " on the second try"
548 utilities.assert_equals(
549 expect=main.TRUE,
550 actual=pingResult,
551 onpass= passMsg,
552 onfail="Reactive Pingall failed, " +
553 "one or more ping pairs failed" )
554 main.log.info( "Time for pingall: %2f seconds" %
555 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700556 # timeout for fwd flows
557 time.sleep( 11 )
558 # uninstall onos-app-fwd
559 main.step( "Uninstall reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700560 node = main.activeNodes[0]
561 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700562 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
563 onpass="Uninstall fwd successful",
564 onfail="Uninstall fwd failed" )
565
566 main.step( "Check app ids" )
567 threads = []
568 appCheck2 = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700569 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700570 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700571 name="appToIDCheck-" + str( i ),
572 args=[] )
573 threads.append( t )
574 t.start()
575
576 for t in threads:
577 t.join()
578 appCheck2 = appCheck2 and t.result
579 if appCheck2 != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700580 node = main.activeNodes[0]
581 main.log.warn( main.CLIs[node].apps() )
582 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700583 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
584 onpass="App Ids seem to be correct",
585 onfail="Something is wrong with app Ids" )
586
587 main.step( "Add host intents via cli" )
588 intentIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700589 # TODO: move the host numbers to params
590 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700591 intentAddResult = True
592 hostResult = main.TRUE
593 for i in range( 8, 18 ):
594 main.log.info( "Adding host intent between h" + str( i ) +
595 " and h" + str( i + 10 ) )
596 host1 = "00:00:00:00:00:" + \
597 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
598 host2 = "00:00:00:00:00:" + \
599 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
600 # NOTE: getHost can return None
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700601 host1Dict = onosCli.getHost( host1 )
602 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700603 host1Id = None
604 host2Id = None
605 if host1Dict and host2Dict:
606 host1Id = host1Dict.get( 'id', None )
607 host2Id = host2Dict.get( 'id', None )
608 if host1Id and host2Id:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700609 nodeNum = ( i % len( main.activeNodes ) )
610 node = main.activeNodes[nodeNum]
611 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700612 if tmpId:
613 main.log.info( "Added intent with id: " + tmpId )
614 intentIds.append( tmpId )
615 else:
616 main.log.error( "addHostIntent returned: " +
617 repr( tmpId ) )
618 else:
619 main.log.error( "Error, getHost() failed for h" + str( i ) +
620 " and/or h" + str( i + 10 ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700621 node = main.activeNodes[0]
622 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700623 main.log.warn( "Hosts output: " )
624 try:
625 main.log.warn( json.dumps( json.loads( hosts ),
626 sort_keys=True,
627 indent=4,
628 separators=( ',', ': ' ) ) )
629 except ( ValueError, TypeError ):
630 main.log.warn( repr( hosts ) )
631 hostResult = main.FALSE
632 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
633 onpass="Found a host id for each host",
634 onfail="Error looking up host ids" )
635
636 intentStart = time.time()
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700637 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700638 main.log.info( "Submitted intents: " + str( intentIds ) )
639 main.log.info( "Intents in ONOS: " + str( onosIds ) )
640 for intent in intentIds:
641 if intent in onosIds:
642 pass # intent submitted is in onos
643 else:
644 intentAddResult = False
645 if intentAddResult:
646 intentStop = time.time()
647 else:
648 intentStop = None
649 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700650 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700651 intentStates = []
652 installedCheck = True
653 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
654 count = 0
655 try:
656 for intent in json.loads( intents ):
657 state = intent.get( 'state', None )
658 if "INSTALLED" not in state:
659 installedCheck = False
660 intentId = intent.get( 'id', None )
661 intentStates.append( ( intentId, state ) )
662 except ( ValueError, TypeError ):
663 main.log.exception( "Error parsing intents" )
664 # add submitted intents not in the store
665 tmplist = [ i for i, s in intentStates ]
666 missingIntents = False
667 for i in intentIds:
668 if i not in tmplist:
669 intentStates.append( ( i, " - " ) )
670 missingIntents = True
671 intentStates.sort()
672 for i, s in intentStates:
673 count += 1
674 main.log.info( "%-6s%-15s%-15s" %
675 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700676 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700677 try:
678 missing = False
679 if leaders:
680 parsedLeaders = json.loads( leaders )
681 main.log.warn( json.dumps( parsedLeaders,
682 sort_keys=True,
683 indent=4,
684 separators=( ',', ': ' ) ) )
685 # check for all intent partitions
686 topics = []
687 for i in range( 14 ):
688 topics.append( "intent-partition-" + str( i ) )
689 main.log.debug( topics )
690 ONOStopics = [ j['topic'] for j in parsedLeaders ]
691 for topic in topics:
692 if topic not in ONOStopics:
693 main.log.error( "Error: " + topic +
694 " not in leaders" )
695 missing = True
696 else:
697 main.log.error( "leaders() returned None" )
698 except ( ValueError, TypeError ):
699 main.log.exception( "Error parsing leaders" )
700 main.log.error( repr( leaders ) )
701 # Check all nodes
702 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700703 for i in main.activeNodes:
704 response = main.CLIs[i].leaders( jsonFormat=False)
705 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700706 str( response ) )
707
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700708 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700709 try:
710 if partitions :
711 parsedPartitions = json.loads( partitions )
712 main.log.warn( json.dumps( parsedPartitions,
713 sort_keys=True,
714 indent=4,
715 separators=( ',', ': ' ) ) )
716 # TODO check for a leader in all paritions
717 # TODO check for consistency among nodes
718 else:
719 main.log.error( "partitions() returned None" )
720 except ( ValueError, TypeError ):
721 main.log.exception( "Error parsing partitions" )
722 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700723 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700724 try:
725 if pendingMap :
726 parsedPending = json.loads( pendingMap )
727 main.log.warn( json.dumps( parsedPending,
728 sort_keys=True,
729 indent=4,
730 separators=( ',', ': ' ) ) )
731 # TODO check something here?
732 else:
733 main.log.error( "pendingMap() returned None" )
734 except ( ValueError, TypeError ):
735 main.log.exception( "Error parsing pending map" )
736 main.log.error( repr( pendingMap ) )
737
738 intentAddResult = bool( intentAddResult and not missingIntents and
739 installedCheck )
740 if not intentAddResult:
741 main.log.error( "Error in pushing host intents to ONOS" )
742
743 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700744 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700745 correct = True
746 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700747 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700748 onosIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700749 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700750 onosIds.append( ids )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700751 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700752 str( sorted( onosIds ) ) )
753 if sorted( ids ) != sorted( intentIds ):
754 main.log.warn( "Set of intent IDs doesn't match" )
755 correct = False
756 break
757 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700758 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700759 for intent in intents:
760 if intent[ 'state' ] != "INSTALLED":
761 main.log.warn( "Intent " + intent[ 'id' ] +
762 " is " + intent[ 'state' ] )
763 correct = False
764 break
765 if correct:
766 break
767 else:
768 time.sleep(1)
769 if not intentStop:
770 intentStop = time.time()
771 global gossipTime
772 gossipTime = intentStop - intentStart
773 main.log.info( "It took about " + str( gossipTime ) +
774 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700775 gossipPeriod = int( main.params['timers']['gossip'] )
776 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700777 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700778 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700779 onpass="ECM anti-entropy for intents worked within " +
780 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700781 onfail="Intent ECM anti-entropy took too long. " +
782 "Expected time:{}, Actual time:{}".format( maxGossipTime,
783 gossipTime ) )
784 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700785 intentAddResult = True
786
787 if not intentAddResult or "key" in pendingMap:
788 import time
789 installedCheck = True
790 main.log.info( "Sleeping 60 seconds to see if intents are found" )
791 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700792 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700793 main.log.info( "Submitted intents: " + str( intentIds ) )
794 main.log.info( "Intents in ONOS: " + str( onosIds ) )
795 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700796 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700797 intentStates = []
798 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
799 count = 0
800 try:
801 for intent in json.loads( intents ):
802 # Iter through intents of a node
803 state = intent.get( 'state', None )
804 if "INSTALLED" not in state:
805 installedCheck = False
806 intentId = intent.get( 'id', None )
807 intentStates.append( ( intentId, state ) )
808 except ( ValueError, TypeError ):
809 main.log.exception( "Error parsing intents" )
810 # add submitted intents not in the store
811 tmplist = [ i for i, s in intentStates ]
812 for i in intentIds:
813 if i not in tmplist:
814 intentStates.append( ( i, " - " ) )
815 intentStates.sort()
816 for i, s in intentStates:
817 count += 1
818 main.log.info( "%-6s%-15s%-15s" %
819 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700820 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700821 try:
822 missing = False
823 if leaders:
824 parsedLeaders = json.loads( leaders )
825 main.log.warn( json.dumps( parsedLeaders,
826 sort_keys=True,
827 indent=4,
828 separators=( ',', ': ' ) ) )
829 # check for all intent partitions
830 # check for election
831 topics = []
832 for i in range( 14 ):
833 topics.append( "intent-partition-" + str( i ) )
834 # FIXME: this should only be after we start the app
835 topics.append( "org.onosproject.election" )
836 main.log.debug( topics )
837 ONOStopics = [ j['topic'] for j in parsedLeaders ]
838 for topic in topics:
839 if topic not in ONOStopics:
840 main.log.error( "Error: " + topic +
841 " not in leaders" )
842 missing = True
843 else:
844 main.log.error( "leaders() returned None" )
845 except ( ValueError, TypeError ):
846 main.log.exception( "Error parsing leaders" )
847 main.log.error( repr( leaders ) )
848 # Check all nodes
849 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700850 for i in main.activeNodes:
851 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700852 response = node.leaders( jsonFormat=False)
853 main.log.warn( str( node.name ) + " leaders output: \n" +
854 str( response ) )
855
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700856 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700857 try:
858 if partitions :
859 parsedPartitions = json.loads( partitions )
860 main.log.warn( json.dumps( parsedPartitions,
861 sort_keys=True,
862 indent=4,
863 separators=( ',', ': ' ) ) )
864 # TODO check for a leader in all paritions
865 # TODO check for consistency among nodes
866 else:
867 main.log.error( "partitions() returned None" )
868 except ( ValueError, TypeError ):
869 main.log.exception( "Error parsing partitions" )
870 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700871 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700872 try:
873 if pendingMap :
874 parsedPending = json.loads( pendingMap )
875 main.log.warn( json.dumps( parsedPending,
876 sort_keys=True,
877 indent=4,
878 separators=( ',', ': ' ) ) )
879 # TODO check something here?
880 else:
881 main.log.error( "pendingMap() returned None" )
882 except ( ValueError, TypeError ):
883 main.log.exception( "Error parsing pending map" )
884 main.log.error( repr( pendingMap ) )
885
886 def CASE4( self, main ):
887 """
888 Ping across added host intents
889 """
890 import json
891 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700892 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700893 assert main, "main not defined"
894 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700895 assert main.CLIs, "main.CLIs not defined"
896 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700897 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700898 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700899 "functionality and check the state of " +\
900 "the intent"
901 main.step( "Ping across added host intents" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700902 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700903 PingResult = main.TRUE
904 for i in range( 8, 18 ):
905 ping = main.Mininet1.pingHost( src="h" + str( i ),
906 target="h" + str( i + 10 ) )
907 PingResult = PingResult and ping
908 if ping == main.FALSE:
909 main.log.warn( "Ping failed between h" + str( i ) +
910 " and h" + str( i + 10 ) )
911 elif ping == main.TRUE:
912 main.log.info( "Ping test passed!" )
913 # Don't set PingResult or you'd override failures
914 if PingResult == main.FALSE:
915 main.log.error(
916 "Intents have not been installed correctly, pings failed." )
917 # TODO: pretty print
918 main.log.warn( "ONOS1 intents: " )
919 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700920 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700921 main.log.warn( json.dumps( json.loads( tmpIntents ),
922 sort_keys=True,
923 indent=4,
924 separators=( ',', ': ' ) ) )
925 except ( ValueError, TypeError ):
926 main.log.warn( repr( tmpIntents ) )
927 utilities.assert_equals(
928 expect=main.TRUE,
929 actual=PingResult,
930 onpass="Intents have been installed correctly and pings work",
931 onfail="Intents have not been installed correctly, pings failed." )
932
933 main.step( "Check Intent state" )
934 installedCheck = False
935 loopCount = 0
936 while not installedCheck and loopCount < 40:
937 installedCheck = True
938 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700939 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700940 intentStates = []
941 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
942 count = 0
943 # Iter through intents of a node
944 try:
945 for intent in json.loads( intents ):
946 state = intent.get( 'state', None )
947 if "INSTALLED" not in state:
948 installedCheck = False
949 intentId = intent.get( 'id', None )
950 intentStates.append( ( intentId, state ) )
951 except ( ValueError, TypeError ):
952 main.log.exception( "Error parsing intents." )
953 # Print states
954 intentStates.sort()
955 for i, s in intentStates:
956 count += 1
957 main.log.info( "%-6s%-15s%-15s" %
958 ( str( count ), str( i ), str( s ) ) )
959 if not installedCheck:
960 time.sleep( 1 )
961 loopCount += 1
962 utilities.assert_equals( expect=True, actual=installedCheck,
963 onpass="Intents are all INSTALLED",
964 onfail="Intents are not all in " +
965 "INSTALLED state" )
966
967 main.step( "Check leadership of topics" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700968 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700969 topicCheck = main.TRUE
970 try:
971 if leaders:
972 parsedLeaders = json.loads( leaders )
973 main.log.warn( json.dumps( parsedLeaders,
974 sort_keys=True,
975 indent=4,
976 separators=( ',', ': ' ) ) )
977 # check for all intent partitions
978 # check for election
979 # TODO: Look at Devices as topics now that it uses this system
980 topics = []
981 for i in range( 14 ):
982 topics.append( "intent-partition-" + str( i ) )
983 # FIXME: this should only be after we start the app
984 # FIXME: topics.append( "org.onosproject.election" )
985 # Print leaders output
986 main.log.debug( topics )
987 ONOStopics = [ j['topic'] for j in parsedLeaders ]
988 for topic in topics:
989 if topic not in ONOStopics:
990 main.log.error( "Error: " + topic +
991 " not in leaders" )
992 topicCheck = main.FALSE
993 else:
994 main.log.error( "leaders() returned None" )
995 topicCheck = main.FALSE
996 except ( ValueError, TypeError ):
997 topicCheck = main.FALSE
998 main.log.exception( "Error parsing leaders" )
999 main.log.error( repr( leaders ) )
1000 # TODO: Check for a leader of these topics
1001 # Check all nodes
1002 if topicCheck:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001003 for i in main.activeNodes:
1004 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001005 response = node.leaders( jsonFormat=False)
1006 main.log.warn( str( node.name ) + " leaders output: \n" +
1007 str( response ) )
1008
1009 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1010 onpass="intent Partitions is in leaders",
1011 onfail="Some topics were lost " )
1012 # Print partitions
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001013 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001014 try:
1015 if partitions :
1016 parsedPartitions = json.loads( partitions )
1017 main.log.warn( json.dumps( parsedPartitions,
1018 sort_keys=True,
1019 indent=4,
1020 separators=( ',', ': ' ) ) )
1021 # TODO check for a leader in all paritions
1022 # TODO check for consistency among nodes
1023 else:
1024 main.log.error( "partitions() returned None" )
1025 except ( ValueError, TypeError ):
1026 main.log.exception( "Error parsing partitions" )
1027 main.log.error( repr( partitions ) )
1028 # Print Pending Map
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001029 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001030 try:
1031 if pendingMap :
1032 parsedPending = json.loads( pendingMap )
1033 main.log.warn( json.dumps( parsedPending,
1034 sort_keys=True,
1035 indent=4,
1036 separators=( ',', ': ' ) ) )
1037 # TODO check something here?
1038 else:
1039 main.log.error( "pendingMap() returned None" )
1040 except ( ValueError, TypeError ):
1041 main.log.exception( "Error parsing pending map" )
1042 main.log.error( repr( pendingMap ) )
1043
1044 if not installedCheck:
1045 main.log.info( "Waiting 60 seconds to see if the state of " +
1046 "intents change" )
1047 time.sleep( 60 )
1048 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001049 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001050 intentStates = []
1051 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1052 count = 0
1053 # Iter through intents of a node
1054 try:
1055 for intent in json.loads( intents ):
1056 state = intent.get( 'state', None )
1057 if "INSTALLED" not in state:
1058 installedCheck = False
1059 intentId = intent.get( 'id', None )
1060 intentStates.append( ( intentId, state ) )
1061 except ( ValueError, TypeError ):
1062 main.log.exception( "Error parsing intents." )
1063 intentStates.sort()
1064 for i, s in intentStates:
1065 count += 1
1066 main.log.info( "%-6s%-15s%-15s" %
1067 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001068 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001069 try:
1070 missing = False
1071 if leaders:
1072 parsedLeaders = json.loads( leaders )
1073 main.log.warn( json.dumps( parsedLeaders,
1074 sort_keys=True,
1075 indent=4,
1076 separators=( ',', ': ' ) ) )
1077 # check for all intent partitions
1078 # check for election
1079 topics = []
1080 for i in range( 14 ):
1081 topics.append( "intent-partition-" + str( i ) )
1082 # FIXME: this should only be after we start the app
1083 topics.append( "org.onosproject.election" )
1084 main.log.debug( topics )
1085 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1086 for topic in topics:
1087 if topic not in ONOStopics:
1088 main.log.error( "Error: " + topic +
1089 " not in leaders" )
1090 missing = True
1091 else:
1092 main.log.error( "leaders() returned None" )
1093 except ( ValueError, TypeError ):
1094 main.log.exception( "Error parsing leaders" )
1095 main.log.error( repr( leaders ) )
1096 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001097 for i in main.activeNodes:
1098 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001099 response = node.leaders( jsonFormat=False)
1100 main.log.warn( str( node.name ) + " leaders output: \n" +
1101 str( response ) )
1102
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001103 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001104 try:
1105 if partitions :
1106 parsedPartitions = json.loads( partitions )
1107 main.log.warn( json.dumps( parsedPartitions,
1108 sort_keys=True,
1109 indent=4,
1110 separators=( ',', ': ' ) ) )
1111 # TODO check for a leader in all paritions
1112 # TODO check for consistency among nodes
1113 else:
1114 main.log.error( "partitions() returned None" )
1115 except ( ValueError, TypeError ):
1116 main.log.exception( "Error parsing partitions" )
1117 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001118 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001119 try:
1120 if pendingMap :
1121 parsedPending = json.loads( pendingMap )
1122 main.log.warn( json.dumps( parsedPending,
1123 sort_keys=True,
1124 indent=4,
1125 separators=( ',', ': ' ) ) )
1126 # TODO check something here?
1127 else:
1128 main.log.error( "pendingMap() returned None" )
1129 except ( ValueError, TypeError ):
1130 main.log.exception( "Error parsing pending map" )
1131 main.log.error( repr( pendingMap ) )
1132 # Print flowrules
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001133 node = main.activeNodes[0]
1134 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001135 main.step( "Wait a minute then ping again" )
1136 # the wait is above
1137 PingResult = main.TRUE
1138 for i in range( 8, 18 ):
1139 ping = main.Mininet1.pingHost( src="h" + str( i ),
1140 target="h" + str( i + 10 ) )
1141 PingResult = PingResult and ping
1142 if ping == main.FALSE:
1143 main.log.warn( "Ping failed between h" + str( i ) +
1144 " and h" + str( i + 10 ) )
1145 elif ping == main.TRUE:
1146 main.log.info( "Ping test passed!" )
1147 # Don't set PingResult or you'd override failures
1148 if PingResult == main.FALSE:
1149 main.log.error(
1150 "Intents have not been installed correctly, pings failed." )
1151 # TODO: pretty print
1152 main.log.warn( "ONOS1 intents: " )
1153 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001154 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001155 main.log.warn( json.dumps( json.loads( tmpIntents ),
1156 sort_keys=True,
1157 indent=4,
1158 separators=( ',', ': ' ) ) )
1159 except ( ValueError, TypeError ):
1160 main.log.warn( repr( tmpIntents ) )
1161 utilities.assert_equals(
1162 expect=main.TRUE,
1163 actual=PingResult,
1164 onpass="Intents have been installed correctly and pings work",
1165 onfail="Intents have not been installed correctly, pings failed." )
1166
1167 def CASE5( self, main ):
1168 """
1169 Reading state of ONOS
1170 """
1171 import json
1172 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001173 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001174 assert main, "main not defined"
1175 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001176 assert main.CLIs, "main.CLIs not defined"
1177 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001178
1179 main.case( "Setting up and gathering data for current state" )
1180 # The general idea for this test case is to pull the state of
1181 # ( intents,flows, topology,... ) from each ONOS node
1182 # We can then compare them with each other and also with past states
1183
1184 main.step( "Check that each switch has a master" )
1185 global mastershipState
1186 mastershipState = '[]'
1187
1188 # Assert that each device has a master
1189 rolesNotNull = main.TRUE
1190 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001191 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001192 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001193 name="rolesNotNull-" + str( i ),
1194 args=[] )
1195 threads.append( t )
1196 t.start()
1197
1198 for t in threads:
1199 t.join()
1200 rolesNotNull = rolesNotNull and t.result
1201 utilities.assert_equals(
1202 expect=main.TRUE,
1203 actual=rolesNotNull,
1204 onpass="Each device has a master",
1205 onfail="Some devices don't have a master assigned" )
1206
1207 main.step( "Get the Mastership of each switch from each controller" )
1208 ONOSMastership = []
1209 mastershipCheck = main.FALSE
1210 consistentMastership = True
1211 rolesResults = True
1212 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001213 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001214 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001215 name="roles-" + str( i ),
1216 args=[] )
1217 threads.append( t )
1218 t.start()
1219
1220 for t in threads:
1221 t.join()
1222 ONOSMastership.append( t.result )
1223
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001224 for i in range( len( ONOSMastership ) ):
1225 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001226 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001227 main.log.error( "Error in getting ONOS" + node + " roles" )
1228 main.log.warn( "ONOS" + node + " mastership response: " +
1229 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001230 rolesResults = False
1231 utilities.assert_equals(
1232 expect=True,
1233 actual=rolesResults,
1234 onpass="No error in reading roles output",
1235 onfail="Error in reading roles from ONOS" )
1236
1237 main.step( "Check for consistency in roles from each controller" )
1238 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1239 main.log.info(
1240 "Switch roles are consistent across all ONOS nodes" )
1241 else:
1242 consistentMastership = False
1243 utilities.assert_equals(
1244 expect=True,
1245 actual=consistentMastership,
1246 onpass="Switch roles are consistent across all ONOS nodes",
1247 onfail="ONOS nodes have different views of switch roles" )
1248
1249 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001250 for i in range( len( main.activeNodes ) ):
1251 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001252 try:
1253 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001254 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001255 json.dumps(
1256 json.loads( ONOSMastership[ i ] ),
1257 sort_keys=True,
1258 indent=4,
1259 separators=( ',', ': ' ) ) )
1260 except ( ValueError, TypeError ):
1261 main.log.warn( repr( ONOSMastership[ i ] ) )
1262 elif rolesResults and consistentMastership:
1263 mastershipCheck = main.TRUE
1264 mastershipState = ONOSMastership[ 0 ]
1265
1266 main.step( "Get the intents from each controller" )
1267 global intentState
1268 intentState = []
1269 ONOSIntents = []
1270 intentCheck = main.FALSE
1271 consistentIntents = True
1272 intentsResults = True
1273 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001274 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001275 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001276 name="intents-" + str( i ),
1277 args=[],
1278 kwargs={ 'jsonFormat': True } )
1279 threads.append( t )
1280 t.start()
1281
1282 for t in threads:
1283 t.join()
1284 ONOSIntents.append( t.result )
1285
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001286 for i in range( len( ONOSIntents ) ):
1287 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001288 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001289 main.log.error( "Error in getting ONOS" + node + " intents" )
1290 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001291 repr( ONOSIntents[ i ] ) )
1292 intentsResults = False
1293 utilities.assert_equals(
1294 expect=True,
1295 actual=intentsResults,
1296 onpass="No error in reading intents output",
1297 onfail="Error in reading intents from ONOS" )
1298
1299 main.step( "Check for consistency in Intents from each controller" )
1300 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1301 main.log.info( "Intents are consistent across all ONOS " +
1302 "nodes" )
1303 else:
1304 consistentIntents = False
1305 main.log.error( "Intents not consistent" )
1306 utilities.assert_equals(
1307 expect=True,
1308 actual=consistentIntents,
1309 onpass="Intents are consistent across all ONOS nodes",
1310 onfail="ONOS nodes have different views of intents" )
1311
1312 if intentsResults:
1313 # Try to make it easy to figure out what is happening
1314 #
1315 # Intent ONOS1 ONOS2 ...
1316 # 0x01 INSTALLED INSTALLING
1317 # ... ... ...
1318 # ... ... ...
1319 title = " Id"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001320 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001321 title += " " * 10 + "ONOS" + str( n + 1 )
1322 main.log.warn( title )
1323 # get all intent keys in the cluster
1324 keys = []
1325 for nodeStr in ONOSIntents:
1326 node = json.loads( nodeStr )
1327 for intent in node:
1328 keys.append( intent.get( 'id' ) )
1329 keys = set( keys )
1330 for key in keys:
1331 row = "%-13s" % key
1332 for nodeStr in ONOSIntents:
1333 node = json.loads( nodeStr )
1334 for intent in node:
1335 if intent.get( 'id', "Error" ) == key:
1336 row += "%-15s" % intent.get( 'state' )
1337 main.log.warn( row )
1338 # End table view
1339
1340 if intentsResults and not consistentIntents:
1341 # print the json objects
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001342 n = str( main.activeNodes[-1] + 1 )
1343 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001344 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1345 sort_keys=True,
1346 indent=4,
1347 separators=( ',', ': ' ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001348 for i in range( len( ONOSIntents ) ):
1349 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001350 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001351 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001352 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1353 sort_keys=True,
1354 indent=4,
1355 separators=( ',', ': ' ) ) )
1356 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001357 main.log.debug( "ONOS" + node + " intents match ONOS" +
1358 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001359 elif intentsResults and consistentIntents:
1360 intentCheck = main.TRUE
1361 intentState = ONOSIntents[ 0 ]
1362
1363 main.step( "Get the flows from each controller" )
1364 global flowState
1365 flowState = []
1366 ONOSFlows = []
1367 ONOSFlowsJson = []
1368 flowCheck = main.FALSE
1369 consistentFlows = True
1370 flowsResults = True
1371 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001372 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001373 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001374 name="flows-" + str( i ),
1375 args=[],
1376 kwargs={ 'jsonFormat': True } )
1377 threads.append( t )
1378 t.start()
1379
1380 # NOTE: Flows command can take some time to run
1381 time.sleep(30)
1382 for t in threads:
1383 t.join()
1384 result = t.result
1385 ONOSFlows.append( result )
1386
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001387 for i in range( len( ONOSFlows ) ):
1388 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001389 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1390 main.log.error( "Error in getting ONOS" + num + " flows" )
1391 main.log.warn( "ONOS" + num + " flows response: " +
1392 repr( ONOSFlows[ i ] ) )
1393 flowsResults = False
1394 ONOSFlowsJson.append( None )
1395 else:
1396 try:
1397 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1398 except ( ValueError, TypeError ):
1399 # FIXME: change this to log.error?
1400 main.log.exception( "Error in parsing ONOS" + num +
1401 " response as json." )
1402 main.log.error( repr( ONOSFlows[ i ] ) )
1403 ONOSFlowsJson.append( None )
1404 flowsResults = False
1405 utilities.assert_equals(
1406 expect=True,
1407 actual=flowsResults,
1408 onpass="No error in reading flows output",
1409 onfail="Error in reading flows from ONOS" )
1410
1411 main.step( "Check for consistency in Flows from each controller" )
1412 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1413 if all( tmp ):
1414 main.log.info( "Flow count is consistent across all ONOS nodes" )
1415 else:
1416 consistentFlows = False
1417 utilities.assert_equals(
1418 expect=True,
1419 actual=consistentFlows,
1420 onpass="The flow count is consistent across all ONOS nodes",
1421 onfail="ONOS nodes have different flow counts" )
1422
1423 if flowsResults and not consistentFlows:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001424 for i in range( len( ONOSFlows ) ):
1425 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001426 try:
1427 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001428 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001429 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1430 indent=4, separators=( ',', ': ' ) ) )
1431 except ( ValueError, TypeError ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001432 main.log.warn( "ONOS" + node + " flows: " +
1433 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001434 elif flowsResults and consistentFlows:
1435 flowCheck = main.TRUE
1436 flowState = ONOSFlows[ 0 ]
1437
1438 main.step( "Get the OF Table entries" )
1439 global flows
1440 flows = []
1441 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001442 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001443 if flowCheck == main.FALSE:
1444 for table in flows:
1445 main.log.warn( table )
1446 # TODO: Compare switch flow tables with ONOS flow tables
1447
1448 main.step( "Start continuous pings" )
1449 main.Mininet2.pingLong(
1450 src=main.params[ 'PING' ][ 'source1' ],
1451 target=main.params[ 'PING' ][ 'target1' ],
1452 pingTime=500 )
1453 main.Mininet2.pingLong(
1454 src=main.params[ 'PING' ][ 'source2' ],
1455 target=main.params[ 'PING' ][ 'target2' ],
1456 pingTime=500 )
1457 main.Mininet2.pingLong(
1458 src=main.params[ 'PING' ][ 'source3' ],
1459 target=main.params[ 'PING' ][ 'target3' ],
1460 pingTime=500 )
1461 main.Mininet2.pingLong(
1462 src=main.params[ 'PING' ][ 'source4' ],
1463 target=main.params[ 'PING' ][ 'target4' ],
1464 pingTime=500 )
1465 main.Mininet2.pingLong(
1466 src=main.params[ 'PING' ][ 'source5' ],
1467 target=main.params[ 'PING' ][ 'target5' ],
1468 pingTime=500 )
1469 main.Mininet2.pingLong(
1470 src=main.params[ 'PING' ][ 'source6' ],
1471 target=main.params[ 'PING' ][ 'target6' ],
1472 pingTime=500 )
1473 main.Mininet2.pingLong(
1474 src=main.params[ 'PING' ][ 'source7' ],
1475 target=main.params[ 'PING' ][ 'target7' ],
1476 pingTime=500 )
1477 main.Mininet2.pingLong(
1478 src=main.params[ 'PING' ][ 'source8' ],
1479 target=main.params[ 'PING' ][ 'target8' ],
1480 pingTime=500 )
1481 main.Mininet2.pingLong(
1482 src=main.params[ 'PING' ][ 'source9' ],
1483 target=main.params[ 'PING' ][ 'target9' ],
1484 pingTime=500 )
1485 main.Mininet2.pingLong(
1486 src=main.params[ 'PING' ][ 'source10' ],
1487 target=main.params[ 'PING' ][ 'target10' ],
1488 pingTime=500 )
1489
1490 main.step( "Collecting topology information from ONOS" )
1491 devices = []
1492 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001493 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001494 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001495 name="devices-" + str( i ),
1496 args=[ ] )
1497 threads.append( t )
1498 t.start()
1499
1500 for t in threads:
1501 t.join()
1502 devices.append( t.result )
1503 hosts = []
1504 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001505 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001506 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001507 name="hosts-" + str( i ),
1508 args=[ ] )
1509 threads.append( t )
1510 t.start()
1511
1512 for t in threads:
1513 t.join()
1514 try:
1515 hosts.append( json.loads( t.result ) )
1516 except ( ValueError, TypeError ):
1517 # FIXME: better handling of this, print which node
1518 # Maybe use thread name?
1519 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001520 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001521 hosts.append( None )
1522
1523 ports = []
1524 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001525 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001526 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001527 name="ports-" + str( i ),
1528 args=[ ] )
1529 threads.append( t )
1530 t.start()
1531
1532 for t in threads:
1533 t.join()
1534 ports.append( t.result )
1535 links = []
1536 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001537 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001538 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001539 name="links-" + str( i ),
1540 args=[ ] )
1541 threads.append( t )
1542 t.start()
1543
1544 for t in threads:
1545 t.join()
1546 links.append( t.result )
1547 clusters = []
1548 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001549 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001550 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001551 name="clusters-" + str( i ),
1552 args=[ ] )
1553 threads.append( t )
1554 t.start()
1555
1556 for t in threads:
1557 t.join()
1558 clusters.append( t.result )
1559 # Compare json objects for hosts and dataplane clusters
1560
1561 # hosts
1562 main.step( "Host view is consistent across ONOS nodes" )
1563 consistentHostsResult = main.TRUE
1564 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001565 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001566 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001567 if hosts[ controller ] == hosts[ 0 ]:
1568 continue
1569 else: # hosts not consistent
1570 main.log.error( "hosts from ONOS" +
1571 controllerStr +
1572 " is inconsistent with ONOS1" )
1573 main.log.warn( repr( hosts[ controller ] ) )
1574 consistentHostsResult = main.FALSE
1575
1576 else:
1577 main.log.error( "Error in getting ONOS hosts from ONOS" +
1578 controllerStr )
1579 consistentHostsResult = main.FALSE
1580 main.log.warn( "ONOS" + controllerStr +
1581 " hosts response: " +
1582 repr( hosts[ controller ] ) )
1583 utilities.assert_equals(
1584 expect=main.TRUE,
1585 actual=consistentHostsResult,
1586 onpass="Hosts view is consistent across all ONOS nodes",
1587 onfail="ONOS nodes have different views of hosts" )
1588
1589 main.step( "Each host has an IP address" )
1590 ipResult = main.TRUE
1591 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001592 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001593 if hosts[ controller ]:
1594 for host in hosts[ controller ]:
1595 if not host.get( 'ipAddresses', [ ] ):
1596 main.log.error( "Error with host ips on controller" +
1597 controllerStr + ": " + str( host ) )
1598 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001599 utilities.assert_equals(
1600 expect=main.TRUE,
1601 actual=ipResult,
1602 onpass="The ips of the hosts aren't empty",
1603 onfail="The ip of at least one host is missing" )
1604
1605 # Strongly connected clusters of devices
1606 main.step( "Cluster view is consistent across ONOS nodes" )
1607 consistentClustersResult = main.TRUE
1608 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001609 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001610 if "Error" not in clusters[ controller ]:
1611 if clusters[ controller ] == clusters[ 0 ]:
1612 continue
1613 else: # clusters not consistent
1614 main.log.error( "clusters from ONOS" + controllerStr +
1615 " is inconsistent with ONOS1" )
1616 consistentClustersResult = main.FALSE
1617
1618 else:
1619 main.log.error( "Error in getting dataplane clusters " +
1620 "from ONOS" + controllerStr )
1621 consistentClustersResult = main.FALSE
1622 main.log.warn( "ONOS" + controllerStr +
1623 " clusters response: " +
1624 repr( clusters[ controller ] ) )
1625 utilities.assert_equals(
1626 expect=main.TRUE,
1627 actual=consistentClustersResult,
1628 onpass="Clusters view is consistent across all ONOS nodes",
1629 onfail="ONOS nodes have different views of clusters" )
1630 # there should always only be one cluster
1631 main.step( "Cluster view correct across ONOS nodes" )
1632 try:
1633 numClusters = len( json.loads( clusters[ 0 ] ) )
1634 except ( ValueError, TypeError ):
1635 main.log.exception( "Error parsing clusters[0]: " +
1636 repr( clusters[ 0 ] ) )
1637 clusterResults = main.FALSE
1638 if numClusters == 1:
1639 clusterResults = main.TRUE
1640 utilities.assert_equals(
1641 expect=1,
1642 actual=numClusters,
1643 onpass="ONOS shows 1 SCC",
1644 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1645
1646 main.step( "Comparing ONOS topology to MN" )
1647 devicesResults = main.TRUE
1648 linksResults = main.TRUE
1649 hostsResults = main.TRUE
1650 mnSwitches = main.Mininet1.getSwitches()
1651 mnLinks = main.Mininet1.getLinks()
1652 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001653 for controller in main.activeNodes:
1654 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001655 if devices[ controller ] and ports[ controller ] and\
1656 "Error" not in devices[ controller ] and\
1657 "Error" not in ports[ controller ]:
1658
1659 currentDevicesResult = main.Mininet1.compareSwitches(
1660 mnSwitches,
1661 json.loads( devices[ controller ] ),
1662 json.loads( ports[ controller ] ) )
1663 else:
1664 currentDevicesResult = main.FALSE
1665 utilities.assert_equals( expect=main.TRUE,
1666 actual=currentDevicesResult,
1667 onpass="ONOS" + controllerStr +
1668 " Switches view is correct",
1669 onfail="ONOS" + controllerStr +
1670 " Switches view is incorrect" )
1671 if links[ controller ] and "Error" not in links[ controller ]:
1672 currentLinksResult = main.Mininet1.compareLinks(
1673 mnSwitches, mnLinks,
1674 json.loads( links[ controller ] ) )
1675 else:
1676 currentLinksResult = main.FALSE
1677 utilities.assert_equals( expect=main.TRUE,
1678 actual=currentLinksResult,
1679 onpass="ONOS" + controllerStr +
1680 " links view is correct",
1681 onfail="ONOS" + controllerStr +
1682 " links view is incorrect" )
1683
1684 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1685 currentHostsResult = main.Mininet1.compareHosts(
1686 mnHosts,
1687 hosts[ controller ] )
1688 else:
1689 currentHostsResult = main.FALSE
1690 utilities.assert_equals( expect=main.TRUE,
1691 actual=currentHostsResult,
1692 onpass="ONOS" + controllerStr +
1693 " hosts exist in Mininet",
1694 onfail="ONOS" + controllerStr +
1695 " hosts don't match Mininet" )
1696
1697 devicesResults = devicesResults and currentDevicesResult
1698 linksResults = linksResults and currentLinksResult
1699 hostsResults = hostsResults and currentHostsResult
1700
1701 main.step( "Device information is correct" )
1702 utilities.assert_equals(
1703 expect=main.TRUE,
1704 actual=devicesResults,
1705 onpass="Device information is correct",
1706 onfail="Device information is incorrect" )
1707
1708 main.step( "Links are correct" )
1709 utilities.assert_equals(
1710 expect=main.TRUE,
1711 actual=linksResults,
1712 onpass="Link are correct",
1713 onfail="Links are incorrect" )
1714
1715 main.step( "Hosts are correct" )
1716 utilities.assert_equals(
1717 expect=main.TRUE,
1718 actual=hostsResults,
1719 onpass="Hosts are correct",
1720 onfail="Hosts are incorrect" )
1721
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001722 def CASE61( self, main ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001723 """
1724 The Failure case.
1725 """
Jon Halle1a3b752015-07-22 13:02:46 -07001726 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001727 assert main, "main not defined"
1728 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001729 assert main.CLIs, "main.CLIs not defined"
1730 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001731 main.case( "Kill minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -07001732
1733 main.step( "Checking ONOS Logs for errors" )
1734 for node in main.nodes:
1735 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1736 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1737
Jon Hall3b489db2015-10-05 14:38:37 -07001738 n = len( main.nodes ) # Number of nodes
1739 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
1740 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
1741 if n > 3:
1742 main.kill.append( p - 1 )
1743 # NOTE: This only works for cluster sizes of 3,5, or 7.
1744
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001745 main.step( "Kill " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07001746 killResults = main.TRUE
1747 for i in main.kill:
1748 killResults = killResults and\
1749 main.ONOSbench.onosKill( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001750 main.activeNodes.remove( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001751 utilities.assert_equals( expect=main.TRUE, actual=killResults,
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001752 onpass="ONOS nodes killed successfully",
1753 onfail="ONOS nodes NOT successfully killed" )
1754
1755 def CASE62( self, main ):
1756 """
1757 The bring up stopped nodes
1758 """
1759 import time
1760 assert main.numCtrls, "main.numCtrls not defined"
1761 assert main, "main not defined"
1762 assert utilities.assert_equals, "utilities.assert_equals not defined"
1763 assert main.CLIs, "main.CLIs not defined"
1764 assert main.nodes, "main.nodes not defined"
1765 assert main.kill, "main.kill not defined"
1766 main.case( "Restart minority of ONOS nodes" )
1767
1768 main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
1769 startResults = main.TRUE
1770 restartTime = time.time()
1771 for i in main.kill:
1772 startResults = startResults and\
1773 main.ONOSbench.onosStart( main.nodes[i].ip_address )
1774 utilities.assert_equals( expect=main.TRUE, actual=startResults,
1775 onpass="ONOS nodes started successfully",
1776 onfail="ONOS nodes NOT successfully started" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001777
1778 main.step( "Checking if ONOS is up yet" )
1779 count = 0
1780 onosIsupResult = main.FALSE
1781 while onosIsupResult == main.FALSE and count < 10:
Jon Hall3b489db2015-10-05 14:38:37 -07001782 onosIsupResult = main.TRUE
1783 for i in main.kill:
1784 onosIsupResult = onosIsupResult and\
1785 main.ONOSbench.isup( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001786 count = count + 1
Jon Hall5cf14d52015-07-16 12:15:19 -07001787 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1788 onpass="ONOS restarted successfully",
1789 onfail="ONOS restart NOT successful" )
1790
Jon Halle1a3b752015-07-22 13:02:46 -07001791 main.step( "Restarting ONOS main.CLIs" )
Jon Hall3b489db2015-10-05 14:38:37 -07001792 cliResults = main.TRUE
1793 for i in main.kill:
1794 cliResults = cliResults and\
1795 main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001796 main.activeNodes.append( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001797 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1798 onpass="ONOS cli restarted",
1799 onfail="ONOS cli did not restart" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001800 main.activeNodes.sort()
1801 try:
1802 assert list( set( main.activeNodes ) ) == main.activeNodes,\
1803 "List of active nodes has duplicates, this likely indicates something was run out of order"
1804 except AssertionError:
1805 main.log.exception( "" )
1806 main.cleanup()
1807 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -07001808
1809 # Grab the time of restart so we chan check how long the gossip
1810 # protocol has had time to work
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001811 main.restartTime = time.time() - restartTime
Jon Hall5cf14d52015-07-16 12:15:19 -07001812 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001813 # TODO: MAke this configurable. Also, we are breaking the above timer
1814 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001815 node = main.activeNodes[0]
1816 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1817 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1818 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001819
1820 def CASE7( self, main ):
1821 """
1822 Check state after ONOS failure
1823 """
1824 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001825 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001826 assert main, "main not defined"
1827 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001828 assert main.CLIs, "main.CLIs not defined"
1829 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001830 try:
1831 main.kill
1832 except AttributeError:
1833 main.kill = []
1834
Jon Hall5cf14d52015-07-16 12:15:19 -07001835 main.case( "Running ONOS Constant State Tests" )
1836
1837 main.step( "Check that each switch has a master" )
1838 # Assert that each device has a master
1839 rolesNotNull = main.TRUE
1840 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001841 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001842 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001843 name="rolesNotNull-" + str( i ),
1844 args=[ ] )
1845 threads.append( t )
1846 t.start()
1847
1848 for t in threads:
1849 t.join()
1850 rolesNotNull = rolesNotNull and t.result
1851 utilities.assert_equals(
1852 expect=main.TRUE,
1853 actual=rolesNotNull,
1854 onpass="Each device has a master",
1855 onfail="Some devices don't have a master assigned" )
1856
1857 main.step( "Read device roles from ONOS" )
1858 ONOSMastership = []
1859 consistentMastership = True
1860 rolesResults = True
1861 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001862 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001863 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001864 name="roles-" + str( i ),
1865 args=[] )
1866 threads.append( t )
1867 t.start()
1868
1869 for t in threads:
1870 t.join()
1871 ONOSMastership.append( t.result )
1872
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001873 for i in range( len( ONOSMastership ) ):
1874 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001875 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001876 main.log.error( "Error in getting ONOS" + node + " roles" )
1877 main.log.warn( "ONOS" + node + " mastership response: " +
1878 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001879 rolesResults = False
1880 utilities.assert_equals(
1881 expect=True,
1882 actual=rolesResults,
1883 onpass="No error in reading roles output",
1884 onfail="Error in reading roles from ONOS" )
1885
1886 main.step( "Check for consistency in roles from each controller" )
1887 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1888 main.log.info(
1889 "Switch roles are consistent across all ONOS nodes" )
1890 else:
1891 consistentMastership = False
1892 utilities.assert_equals(
1893 expect=True,
1894 actual=consistentMastership,
1895 onpass="Switch roles are consistent across all ONOS nodes",
1896 onfail="ONOS nodes have different views of switch roles" )
1897
1898 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001899 for i in range( len( ONOSMastership ) ):
1900 node = str( main.activeNodes[i] + 1 )
1901 main.log.warn( "ONOS" + node + " roles: ",
1902 json.dumps( json.loads( ONOSMastership[ i ] ),
1903 sort_keys=True,
1904 indent=4,
1905 separators=( ',', ': ' ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001906
1907 # NOTE: we expect mastership to change on controller failure
Jon Hall5cf14d52015-07-16 12:15:19 -07001908
1909 main.step( "Get the intents and compare across all nodes" )
1910 ONOSIntents = []
1911 intentCheck = main.FALSE
1912 consistentIntents = True
1913 intentsResults = True
1914 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001915 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001916 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001917 name="intents-" + str( i ),
1918 args=[],
1919 kwargs={ 'jsonFormat': True } )
1920 threads.append( t )
1921 t.start()
1922
1923 for t in threads:
1924 t.join()
1925 ONOSIntents.append( t.result )
1926
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001927 for i in range( len( ONOSIntents) ):
1928 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001929 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001930 main.log.error( "Error in getting ONOS" + node + " intents" )
1931 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001932 repr( ONOSIntents[ i ] ) )
1933 intentsResults = False
1934 utilities.assert_equals(
1935 expect=True,
1936 actual=intentsResults,
1937 onpass="No error in reading intents output",
1938 onfail="Error in reading intents from ONOS" )
1939
1940 main.step( "Check for consistency in Intents from each controller" )
1941 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1942 main.log.info( "Intents are consistent across all ONOS " +
1943 "nodes" )
1944 else:
1945 consistentIntents = False
1946
1947 # Try to make it easy to figure out what is happening
1948 #
1949 # Intent ONOS1 ONOS2 ...
1950 # 0x01 INSTALLED INSTALLING
1951 # ... ... ...
1952 # ... ... ...
1953 title = " ID"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001954 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001955 title += " " * 10 + "ONOS" + str( n + 1 )
1956 main.log.warn( title )
1957 # get all intent keys in the cluster
1958 keys = []
1959 for nodeStr in ONOSIntents:
1960 node = json.loads( nodeStr )
1961 for intent in node:
1962 keys.append( intent.get( 'id' ) )
1963 keys = set( keys )
1964 for key in keys:
1965 row = "%-13s" % key
1966 for nodeStr in ONOSIntents:
1967 node = json.loads( nodeStr )
1968 for intent in node:
1969 if intent.get( 'id' ) == key:
1970 row += "%-15s" % intent.get( 'state' )
1971 main.log.warn( row )
1972 # End table view
1973
1974 utilities.assert_equals(
1975 expect=True,
1976 actual=consistentIntents,
1977 onpass="Intents are consistent across all ONOS nodes",
1978 onfail="ONOS nodes have different views of intents" )
1979 intentStates = []
1980 for node in ONOSIntents: # Iter through ONOS nodes
1981 nodeStates = []
1982 # Iter through intents of a node
1983 try:
1984 for intent in json.loads( node ):
1985 nodeStates.append( intent[ 'state' ] )
1986 except ( ValueError, TypeError ):
1987 main.log.exception( "Error in parsing intents" )
1988 main.log.error( repr( node ) )
1989 intentStates.append( nodeStates )
1990 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1991 main.log.info( dict( out ) )
1992
1993 if intentsResults and not consistentIntents:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001994 for i in range( len( main.activeNodes ) ):
1995 node = str( main.activeNodes[i] + 1 )
1996 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001997 main.log.warn( json.dumps(
1998 json.loads( ONOSIntents[ i ] ),
1999 sort_keys=True,
2000 indent=4,
2001 separators=( ',', ': ' ) ) )
2002 elif intentsResults and consistentIntents:
2003 intentCheck = main.TRUE
2004
2005 # NOTE: Store has no durability, so intents are lost across system
2006 # restarts
2007 main.step( "Compare current intents with intents before the failure" )
2008 # NOTE: this requires case 5 to pass for intentState to be set.
2009 # maybe we should stop the test if that fails?
2010 sameIntents = main.FALSE
2011 if intentState and intentState == ONOSIntents[ 0 ]:
2012 sameIntents = main.TRUE
2013 main.log.info( "Intents are consistent with before failure" )
2014 # TODO: possibly the states have changed? we may need to figure out
2015 # what the acceptable states are
2016 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2017 sameIntents = main.TRUE
2018 try:
2019 before = json.loads( intentState )
2020 after = json.loads( ONOSIntents[ 0 ] )
2021 for intent in before:
2022 if intent not in after:
2023 sameIntents = main.FALSE
2024 main.log.debug( "Intent is not currently in ONOS " +
2025 "(at least in the same form):" )
2026 main.log.debug( json.dumps( intent ) )
2027 except ( ValueError, TypeError ):
2028 main.log.exception( "Exception printing intents" )
2029 main.log.debug( repr( ONOSIntents[0] ) )
2030 main.log.debug( repr( intentState ) )
2031 if sameIntents == main.FALSE:
2032 try:
2033 main.log.debug( "ONOS intents before: " )
2034 main.log.debug( json.dumps( json.loads( intentState ),
2035 sort_keys=True, indent=4,
2036 separators=( ',', ': ' ) ) )
2037 main.log.debug( "Current ONOS intents: " )
2038 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2039 sort_keys=True, indent=4,
2040 separators=( ',', ': ' ) ) )
2041 except ( ValueError, TypeError ):
2042 main.log.exception( "Exception printing intents" )
2043 main.log.debug( repr( ONOSIntents[0] ) )
2044 main.log.debug( repr( intentState ) )
2045 utilities.assert_equals(
2046 expect=main.TRUE,
2047 actual=sameIntents,
2048 onpass="Intents are consistent with before failure",
2049 onfail="The Intents changed during failure" )
2050 intentCheck = intentCheck and sameIntents
2051
2052 main.step( "Get the OF Table entries and compare to before " +
2053 "component failure" )
2054 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002055 for i in range( 28 ):
2056 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002057 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2058 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002059 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002060 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
2061
Jon Hall5cf14d52015-07-16 12:15:19 -07002062 utilities.assert_equals(
2063 expect=main.TRUE,
2064 actual=FlowTables,
2065 onpass="No changes were found in the flow tables",
2066 onfail="Changes were found in the flow tables" )
2067
2068 main.Mininet2.pingLongKill()
2069 '''
2070 main.step( "Check the continuous pings to ensure that no packets " +
2071 "were dropped during component failure" )
2072 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2073 main.params[ 'TESTONIP' ] )
2074 LossInPings = main.FALSE
2075 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2076 for i in range( 8, 18 ):
2077 main.log.info(
2078 "Checking for a loss in pings along flow from s" +
2079 str( i ) )
2080 LossInPings = main.Mininet2.checkForLoss(
2081 "/tmp/ping.h" +
2082 str( i ) ) or LossInPings
2083 if LossInPings == main.TRUE:
2084 main.log.info( "Loss in ping detected" )
2085 elif LossInPings == main.ERROR:
2086 main.log.info( "There are multiple mininet process running" )
2087 elif LossInPings == main.FALSE:
2088 main.log.info( "No Loss in the pings" )
2089 main.log.info( "No loss of dataplane connectivity" )
2090 utilities.assert_equals(
2091 expect=main.FALSE,
2092 actual=LossInPings,
2093 onpass="No Loss of connectivity",
2094 onfail="Loss of dataplane connectivity detected" )
2095 '''
2096
2097 main.step( "Leadership Election is still functional" )
2098 # Test of LeadershipElection
2099 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -07002100
Jon Hall3b489db2015-10-05 14:38:37 -07002101 restarted = []
2102 for i in main.kill:
2103 restarted.append( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002104 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -07002105
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002106 for i in main.activeNodes:
2107 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002108 leaderN = cli.electionTestLeader()
2109 leaderList.append( leaderN )
2110 if leaderN == main.FALSE:
2111 # error in response
2112 main.log.error( "Something is wrong with " +
2113 "electionTestLeader function, check the" +
2114 " error logs" )
2115 leaderResult = main.FALSE
2116 elif leaderN is None:
2117 main.log.error( cli.name +
2118 " shows no leader for the election-app was" +
2119 " elected after the old one died" )
2120 leaderResult = main.FALSE
2121 elif leaderN in restarted:
2122 main.log.error( cli.name + " shows " + str( leaderN ) +
2123 " as leader for the election-app, but it " +
2124 "was restarted" )
2125 leaderResult = main.FALSE
2126 if len( set( leaderList ) ) != 1:
2127 leaderResult = main.FALSE
2128 main.log.error(
2129 "Inconsistent view of leader for the election test app" )
2130 # TODO: print the list
2131 utilities.assert_equals(
2132 expect=main.TRUE,
2133 actual=leaderResult,
2134 onpass="Leadership election passed",
2135 onfail="Something went wrong with Leadership election" )
2136
2137 def CASE8( self, main ):
2138 """
2139 Compare topo
2140 """
2141 import json
2142 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002143 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002144 assert main, "main not defined"
2145 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002146 assert main.CLIs, "main.CLIs not defined"
2147 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002148
2149 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002150 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002151 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002152 topoResult = main.FALSE
2153 elapsed = 0
2154 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002155 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002156 startTime = time.time()
2157 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002158 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002159 devicesResults = main.TRUE
2160 linksResults = main.TRUE
2161 hostsResults = main.TRUE
2162 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002163 count += 1
2164 cliStart = time.time()
2165 devices = []
2166 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002167 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002168 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002169 name="devices-" + str( i ),
2170 args=[ ] )
2171 threads.append( t )
2172 t.start()
2173
2174 for t in threads:
2175 t.join()
2176 devices.append( t.result )
2177 hosts = []
2178 ipResult = main.TRUE
2179 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002180 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002181 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002182 name="hosts-" + str( i ),
2183 args=[ ] )
2184 threads.append( t )
2185 t.start()
2186
2187 for t in threads:
2188 t.join()
2189 try:
2190 hosts.append( json.loads( t.result ) )
2191 except ( ValueError, TypeError ):
2192 main.log.exception( "Error parsing hosts results" )
2193 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002194 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002195 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002196 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002197 if hosts[ controller ]:
2198 for host in hosts[ controller ]:
2199 if host is None or host.get( 'ipAddresses', [] ) == []:
2200 main.log.error(
2201 "Error with host ipAddresses on controller" +
2202 controllerStr + ": " + str( host ) )
2203 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002204 ports = []
2205 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002206 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002207 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002208 name="ports-" + str( i ),
2209 args=[ ] )
2210 threads.append( t )
2211 t.start()
2212
2213 for t in threads:
2214 t.join()
2215 ports.append( t.result )
2216 links = []
2217 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002218 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002219 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002220 name="links-" + str( i ),
2221 args=[ ] )
2222 threads.append( t )
2223 t.start()
2224
2225 for t in threads:
2226 t.join()
2227 links.append( t.result )
2228 clusters = []
2229 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002230 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002231 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002232 name="clusters-" + str( i ),
2233 args=[ ] )
2234 threads.append( t )
2235 t.start()
2236
2237 for t in threads:
2238 t.join()
2239 clusters.append( t.result )
2240
2241 elapsed = time.time() - startTime
2242 cliTime = time.time() - cliStart
2243 print "Elapsed time: " + str( elapsed )
2244 print "CLI time: " + str( cliTime )
2245
2246 mnSwitches = main.Mininet1.getSwitches()
2247 mnLinks = main.Mininet1.getLinks()
2248 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002249 for controller in range( len( main.activeNodes ) ):
2250 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002251 if devices[ controller ] and ports[ controller ] and\
2252 "Error" not in devices[ controller ] and\
2253 "Error" not in ports[ controller ]:
2254
2255 currentDevicesResult = main.Mininet1.compareSwitches(
2256 mnSwitches,
2257 json.loads( devices[ controller ] ),
2258 json.loads( ports[ controller ] ) )
2259 else:
2260 currentDevicesResult = main.FALSE
2261 utilities.assert_equals( expect=main.TRUE,
2262 actual=currentDevicesResult,
2263 onpass="ONOS" + controllerStr +
2264 " Switches view is correct",
2265 onfail="ONOS" + controllerStr +
2266 " Switches view is incorrect" )
2267
2268 if links[ controller ] and "Error" not in links[ controller ]:
2269 currentLinksResult = main.Mininet1.compareLinks(
2270 mnSwitches, mnLinks,
2271 json.loads( links[ controller ] ) )
2272 else:
2273 currentLinksResult = main.FALSE
2274 utilities.assert_equals( expect=main.TRUE,
2275 actual=currentLinksResult,
2276 onpass="ONOS" + controllerStr +
2277 " links view is correct",
2278 onfail="ONOS" + controllerStr +
2279 " links view is incorrect" )
2280
2281 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2282 currentHostsResult = main.Mininet1.compareHosts(
2283 mnHosts,
2284 hosts[ controller ] )
2285 else:
2286 currentHostsResult = main.FALSE
2287 utilities.assert_equals( expect=main.TRUE,
2288 actual=currentHostsResult,
2289 onpass="ONOS" + controllerStr +
2290 " hosts exist in Mininet",
2291 onfail="ONOS" + controllerStr +
2292 " hosts don't match Mininet" )
2293 # CHECKING HOST ATTACHMENT POINTS
2294 hostAttachment = True
2295 zeroHosts = False
2296 # FIXME: topo-HA/obelisk specific mappings:
2297 # key is mac and value is dpid
2298 mappings = {}
2299 for i in range( 1, 29 ): # hosts 1 through 28
2300 # set up correct variables:
2301 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2302 if i == 1:
2303 deviceId = "1000".zfill(16)
2304 elif i == 2:
2305 deviceId = "2000".zfill(16)
2306 elif i == 3:
2307 deviceId = "3000".zfill(16)
2308 elif i == 4:
2309 deviceId = "3004".zfill(16)
2310 elif i == 5:
2311 deviceId = "5000".zfill(16)
2312 elif i == 6:
2313 deviceId = "6000".zfill(16)
2314 elif i == 7:
2315 deviceId = "6007".zfill(16)
2316 elif i >= 8 and i <= 17:
2317 dpid = '3' + str( i ).zfill( 3 )
2318 deviceId = dpid.zfill(16)
2319 elif i >= 18 and i <= 27:
2320 dpid = '6' + str( i ).zfill( 3 )
2321 deviceId = dpid.zfill(16)
2322 elif i == 28:
2323 deviceId = "2800".zfill(16)
2324 mappings[ macId ] = deviceId
2325 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2326 if hosts[ controller ] == []:
2327 main.log.warn( "There are no hosts discovered" )
2328 zeroHosts = True
2329 else:
2330 for host in hosts[ controller ]:
2331 mac = None
2332 location = None
2333 device = None
2334 port = None
2335 try:
2336 mac = host.get( 'mac' )
2337 assert mac, "mac field could not be found for this host object"
2338
2339 location = host.get( 'location' )
2340 assert location, "location field could not be found for this host object"
2341
2342 # Trim the protocol identifier off deviceId
2343 device = str( location.get( 'elementId' ) ).split(':')[1]
2344 assert device, "elementId field could not be found for this host location object"
2345
2346 port = location.get( 'port' )
2347 assert port, "port field could not be found for this host location object"
2348
2349 # Now check if this matches where they should be
2350 if mac and device and port:
2351 if str( port ) != "1":
2352 main.log.error( "The attachment port is incorrect for " +
2353 "host " + str( mac ) +
2354 ". Expected: 1 Actual: " + str( port) )
2355 hostAttachment = False
2356 if device != mappings[ str( mac ) ]:
2357 main.log.error( "The attachment device is incorrect for " +
2358 "host " + str( mac ) +
2359 ". Expected: " + mappings[ str( mac ) ] +
2360 " Actual: " + device )
2361 hostAttachment = False
2362 else:
2363 hostAttachment = False
2364 except AssertionError:
2365 main.log.exception( "Json object not as expected" )
2366 main.log.error( repr( host ) )
2367 hostAttachment = False
2368 else:
2369 main.log.error( "No hosts json output or \"Error\"" +
2370 " in output. hosts = " +
2371 repr( hosts[ controller ] ) )
2372 if zeroHosts is False:
2373 hostAttachment = True
2374
2375 # END CHECKING HOST ATTACHMENT POINTS
2376 devicesResults = devicesResults and currentDevicesResult
2377 linksResults = linksResults and currentLinksResult
2378 hostsResults = hostsResults and currentHostsResult
2379 hostAttachmentResults = hostAttachmentResults and\
2380 hostAttachment
Jon Halle9b1fa32015-12-08 15:32:21 -08002381 topoResult = devicesResults and linksResults and\
2382 hostsResults and hostAttachmentResults
2383 utilities.assert_equals( expect=True,
2384 actual=topoResult,
2385 onpass="ONOS topology matches Mininet",
2386 onfail="ONOS topology don't match Mininet" )
2387 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002388
2389 # Compare json objects for hosts and dataplane clusters
2390
2391 # hosts
2392 main.step( "Hosts view is consistent across all ONOS nodes" )
2393 consistentHostsResult = main.TRUE
2394 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002395 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08002396 if hosts[ controller ] or "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002397 if hosts[ controller ] == hosts[ 0 ]:
2398 continue
2399 else: # hosts not consistent
2400 main.log.error( "hosts from ONOS" + controllerStr +
2401 " is inconsistent with ONOS1" )
2402 main.log.warn( repr( hosts[ controller ] ) )
2403 consistentHostsResult = main.FALSE
2404
2405 else:
2406 main.log.error( "Error in getting ONOS hosts from ONOS" +
2407 controllerStr )
2408 consistentHostsResult = main.FALSE
2409 main.log.warn( "ONOS" + controllerStr +
2410 " hosts response: " +
2411 repr( hosts[ controller ] ) )
2412 utilities.assert_equals(
2413 expect=main.TRUE,
2414 actual=consistentHostsResult,
2415 onpass="Hosts view is consistent across all ONOS nodes",
2416 onfail="ONOS nodes have different views of hosts" )
2417
2418 main.step( "Hosts information is correct" )
2419 hostsResults = hostsResults and ipResult
2420 utilities.assert_equals(
2421 expect=main.TRUE,
2422 actual=hostsResults,
2423 onpass="Host information is correct",
2424 onfail="Host information is incorrect" )
2425
2426 main.step( "Host attachment points to the network" )
2427 utilities.assert_equals(
2428 expect=True,
2429 actual=hostAttachmentResults,
2430 onpass="Hosts are correctly attached to the network",
2431 onfail="ONOS did not correctly attach hosts to the network" )
2432
2433 # Strongly connected clusters of devices
2434 main.step( "Clusters view is consistent across all ONOS nodes" )
2435 consistentClustersResult = main.TRUE
2436 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002437 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002438 if "Error" not in clusters[ controller ]:
2439 if clusters[ controller ] == clusters[ 0 ]:
2440 continue
2441 else: # clusters not consistent
2442 main.log.error( "clusters from ONOS" +
2443 controllerStr +
2444 " is inconsistent with ONOS1" )
2445 consistentClustersResult = main.FALSE
2446
2447 else:
2448 main.log.error( "Error in getting dataplane clusters " +
2449 "from ONOS" + controllerStr )
2450 consistentClustersResult = main.FALSE
2451 main.log.warn( "ONOS" + controllerStr +
2452 " clusters response: " +
2453 repr( clusters[ controller ] ) )
2454 utilities.assert_equals(
2455 expect=main.TRUE,
2456 actual=consistentClustersResult,
2457 onpass="Clusters view is consistent across all ONOS nodes",
2458 onfail="ONOS nodes have different views of clusters" )
2459
2460 main.step( "There is only one SCC" )
2461 # there should always only be one cluster
2462 try:
2463 numClusters = len( json.loads( clusters[ 0 ] ) )
2464 except ( ValueError, TypeError ):
2465 main.log.exception( "Error parsing clusters[0]: " +
2466 repr( clusters[0] ) )
2467 clusterResults = main.FALSE
2468 if numClusters == 1:
2469 clusterResults = main.TRUE
2470 utilities.assert_equals(
2471 expect=1,
2472 actual=numClusters,
2473 onpass="ONOS shows 1 SCC",
2474 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2475
2476 topoResult = ( devicesResults and linksResults
2477 and hostsResults and consistentHostsResult
2478 and consistentClustersResult and clusterResults
2479 and ipResult and hostAttachmentResults )
2480
2481 topoResult = topoResult and int( count <= 2 )
2482 note = "note it takes about " + str( int( cliTime ) ) + \
2483 " seconds for the test to make all the cli calls to fetch " +\
2484 "the topology from each ONOS instance"
2485 main.log.info(
2486 "Very crass estimate for topology discovery/convergence( " +
2487 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2488 str( count ) + " tries" )
2489
2490 main.step( "Device information is correct" )
2491 utilities.assert_equals(
2492 expect=main.TRUE,
2493 actual=devicesResults,
2494 onpass="Device information is correct",
2495 onfail="Device information is incorrect" )
2496
2497 main.step( "Links are correct" )
2498 utilities.assert_equals(
2499 expect=main.TRUE,
2500 actual=linksResults,
2501 onpass="Link are correct",
2502 onfail="Links are incorrect" )
2503
2504 # FIXME: move this to an ONOS state case
2505 main.step( "Checking ONOS nodes" )
2506 nodesOutput = []
2507 nodeResults = main.TRUE
2508 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002509 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002510 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002511 name="nodes-" + str( i ),
2512 args=[ ] )
2513 threads.append( t )
2514 t.start()
2515
2516 for t in threads:
2517 t.join()
2518 nodesOutput.append( t.result )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002519 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002520 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002521 for i in nodesOutput:
2522 try:
2523 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002524 activeIps = []
2525 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002526 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002527 if node['state'] == 'ACTIVE':
2528 activeIps.append( node['ip'] )
2529 activeIps.sort()
2530 if ips == activeIps:
2531 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002532 except ( ValueError, TypeError ):
2533 main.log.error( "Error parsing nodes output" )
2534 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002535 currentResult = main.FALSE
2536 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002537 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2538 onpass="Nodes check successful",
2539 onfail="Nodes check NOT successful" )
2540
2541 def CASE9( self, main ):
2542 """
2543 Link s3-s28 down
2544 """
2545 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002546 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002547 assert main, "main not defined"
2548 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002549 assert main.CLIs, "main.CLIs not defined"
2550 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002551 # NOTE: You should probably run a topology check after this
2552
2553 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2554
2555 description = "Turn off a link to ensure that Link Discovery " +\
2556 "is working properly"
2557 main.case( description )
2558
2559 main.step( "Kill Link between s3 and s28" )
2560 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2561 main.log.info( "Waiting " + str( linkSleep ) +
2562 " seconds for link down to be discovered" )
2563 time.sleep( linkSleep )
2564 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2565 onpass="Link down successful",
2566 onfail="Failed to bring link down" )
2567 # TODO do some sort of check here
2568
2569 def CASE10( self, main ):
2570 """
2571 Link s3-s28 up
2572 """
2573 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002574 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002575 assert main, "main not defined"
2576 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002577 assert main.CLIs, "main.CLIs not defined"
2578 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002579 # NOTE: You should probably run a topology check after this
2580
2581 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2582
2583 description = "Restore a link to ensure that Link Discovery is " + \
2584 "working properly"
2585 main.case( description )
2586
2587 main.step( "Bring link between s3 and s28 back up" )
2588 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2589 main.log.info( "Waiting " + str( linkSleep ) +
2590 " seconds for link up to be discovered" )
2591 time.sleep( linkSleep )
2592 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2593 onpass="Link up successful",
2594 onfail="Failed to bring link up" )
2595 # TODO do some sort of check here
2596
2597 def CASE11( self, main ):
2598 """
2599 Switch Down
2600 """
2601 # NOTE: You should probably run a topology check after this
2602 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002603 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002604 assert main, "main not defined"
2605 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002606 assert main.CLIs, "main.CLIs not defined"
2607 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002608
2609 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2610
2611 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002612 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002613 main.case( description )
2614 switch = main.params[ 'kill' ][ 'switch' ]
2615 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2616
2617 # TODO: Make this switch parameterizable
2618 main.step( "Kill " + switch )
2619 main.log.info( "Deleting " + switch )
2620 main.Mininet1.delSwitch( switch )
2621 main.log.info( "Waiting " + str( switchSleep ) +
2622 " seconds for switch down to be discovered" )
2623 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002624 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002625 # Peek at the deleted switch
2626 main.log.warn( str( device ) )
2627 result = main.FALSE
2628 if device and device[ 'available' ] is False:
2629 result = main.TRUE
2630 utilities.assert_equals( expect=main.TRUE, actual=result,
2631 onpass="Kill switch successful",
2632 onfail="Failed to kill switch?" )
2633
2634 def CASE12( self, main ):
2635 """
2636 Switch Up
2637 """
2638 # NOTE: You should probably run a topology check after this
2639 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002640 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002641 assert main, "main not defined"
2642 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002643 assert main.CLIs, "main.CLIs not defined"
2644 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002645 assert ONOS1Port, "ONOS1Port not defined"
2646 assert ONOS2Port, "ONOS2Port not defined"
2647 assert ONOS3Port, "ONOS3Port not defined"
2648 assert ONOS4Port, "ONOS4Port not defined"
2649 assert ONOS5Port, "ONOS5Port not defined"
2650 assert ONOS6Port, "ONOS6Port not defined"
2651 assert ONOS7Port, "ONOS7Port not defined"
2652
2653 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2654 switch = main.params[ 'kill' ][ 'switch' ]
2655 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2656 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002657 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002658 description = "Adding a switch to ensure it is discovered correctly"
2659 main.case( description )
2660
2661 main.step( "Add back " + switch )
2662 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2663 for peer in links:
2664 main.Mininet1.addLink( switch, peer )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002665 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002666 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2667 main.log.info( "Waiting " + str( switchSleep ) +
2668 " seconds for switch up to be discovered" )
2669 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002670 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002671 # Peek at the deleted switch
2672 main.log.warn( str( device ) )
2673 result = main.FALSE
2674 if device and device[ 'available' ]:
2675 result = main.TRUE
2676 utilities.assert_equals( expect=main.TRUE, actual=result,
2677 onpass="add switch successful",
2678 onfail="Failed to add switch?" )
2679
2680 def CASE13( self, main ):
2681 """
2682 Clean up
2683 """
2684 import os
2685 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002686 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002687 assert main, "main not defined"
2688 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002689 assert main.CLIs, "main.CLIs not defined"
2690 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002691
2692 # printing colors to terminal
2693 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2694 'blue': '\033[94m', 'green': '\033[92m',
2695 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2696 main.case( "Test Cleanup" )
2697 main.step( "Killing tcpdumps" )
2698 main.Mininet2.stopTcpdump()
2699
2700 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002701 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002702 main.step( "Copying MN pcap and ONOS log files to test station" )
2703 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2704 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002705 # NOTE: MN Pcap file is being saved to logdir.
2706 # We scp this file as MN and TestON aren't necessarily the same vm
2707
2708 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002709 # TODO: Load these from params
2710 # NOTE: must end in /
2711 logFolder = "/opt/onos/log/"
2712 logFiles = [ "karaf.log", "karaf.log.1" ]
2713 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002714 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002715 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002716 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002717 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2718 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002719 # std*.log's
2720 # NOTE: must end in /
2721 logFolder = "/opt/onos/var/"
2722 logFiles = [ "stderr.log", "stdout.log" ]
2723 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002724 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002725 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002726 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002727 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2728 logFolder + f, dstName )
2729 else:
2730 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002731
2732 main.step( "Stopping Mininet" )
2733 mnResult = main.Mininet1.stopNet()
2734 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2735 onpass="Mininet stopped",
2736 onfail="MN cleanup NOT successful" )
2737
2738 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002739 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002740 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2741 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002742
2743 try:
2744 timerLog = open( main.logdir + "/Timers.csv", 'w')
2745 # Overwrite with empty line and close
2746 labels = "Gossip Intents, Restart"
2747 data = str( gossipTime ) + ", " + str( main.restartTime )
2748 timerLog.write( labels + "\n" + data )
2749 timerLog.close()
2750 except NameError, e:
2751 main.log.exception(e)
2752
2753 def CASE14( self, main ):
2754 """
2755 start election app on all onos nodes
2756 """
Jon Halle1a3b752015-07-22 13:02:46 -07002757 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002758 assert main, "main not defined"
2759 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002760 assert main.CLIs, "main.CLIs not defined"
2761 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002762
2763 main.case("Start Leadership Election app")
2764 main.step( "Install leadership election app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002765 onosCli = main.CLIs[ main.activeNodes[0] ]
2766 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002767 utilities.assert_equals(
2768 expect=main.TRUE,
2769 actual=appResult,
2770 onpass="Election app installed",
2771 onfail="Something went wrong with installing Leadership election" )
2772
2773 main.step( "Run for election on each node" )
2774 leaderResult = main.TRUE
2775 leaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002776 for i in main.activeNodes:
2777 main.CLIs[i].electionTestRun()
2778 for i in main.activeNodes:
2779 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002780 leader = cli.electionTestLeader()
2781 if leader is None or leader == main.FALSE:
2782 main.log.error( cli.name + ": Leader for the election app " +
2783 "should be an ONOS node, instead got '" +
2784 str( leader ) + "'" )
2785 leaderResult = main.FALSE
2786 leaders.append( leader )
2787 utilities.assert_equals(
2788 expect=main.TRUE,
2789 actual=leaderResult,
2790 onpass="Successfully ran for leadership",
2791 onfail="Failed to run for leadership" )
2792
2793 main.step( "Check that each node shows the same leader" )
2794 sameLeader = main.TRUE
2795 if len( set( leaders ) ) != 1:
2796 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002797 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002798 str( leaders ) )
2799 utilities.assert_equals(
2800 expect=main.TRUE,
2801 actual=sameLeader,
2802 onpass="Leadership is consistent for the election topic",
2803 onfail="Nodes have different leaders" )
2804
2805 def CASE15( self, main ):
2806 """
2807 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002808 15.1 Run election on each node
2809 15.2 Check that each node has the same leaders and candidates
2810 15.3 Find current leader and withdraw
2811 15.4 Check that a new node was elected leader
2812 15.5 Check that that new leader was the candidate of old leader
2813 15.6 Run for election on old leader
2814 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2815 15.8 Make sure that the old leader was added to the candidate list
2816
2817 old and new variable prefixes refer to data from before vs after
2818 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002819 """
2820 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002821 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002822 assert main, "main not defined"
2823 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002824 assert main.CLIs, "main.CLIs not defined"
2825 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002826
Jon Hall5cf14d52015-07-16 12:15:19 -07002827 description = "Check that Leadership Election is still functional"
2828 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002829 # NOTE: Need to re-run since being a canidate is not persistant
2830 # TODO: add check for "Command not found:" in the driver, this
2831 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002832
acsmars71adceb2015-08-31 15:09:26 -07002833 oldLeaders = [] # leaders by node before withdrawl from candidates
2834 newLeaders = [] # leaders by node after withdrawl from candidates
2835 oldAllCandidates = [] # list of lists of each nodes' candidates before
2836 newAllCandidates = [] # list of lists of each nodes' candidates after
2837 oldCandidates = [] # list of candidates from node 0 before withdrawl
2838 newCandidates = [] # list of candidates from node 0 after withdrawl
2839 oldLeader = '' # the old leader from oldLeaders, None if not same
2840 newLeader = '' # the new leaders fron newLoeaders, None if not same
2841 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2842 expectNoLeader = False # True when there is only one leader
2843 if main.numCtrls == 1:
2844 expectNoLeader = True
2845
2846 main.step( "Run for election on each node" )
2847 electionResult = main.TRUE
2848
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002849 for i in main.activeNodes: # run test election on each node
2850 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002851 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002852 utilities.assert_equals(
2853 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002854 actual=electionResult,
2855 onpass="All nodes successfully ran for leadership",
2856 onfail="At least one node failed to run for leadership" )
2857
acsmars3a72bde2015-09-02 14:16:22 -07002858 if electionResult == main.FALSE:
2859 main.log.error(
2860 "Skipping Test Case because Election Test App isn't loaded" )
2861 main.skipCase()
2862
acsmars71adceb2015-08-31 15:09:26 -07002863 main.step( "Check that each node shows the same leader and candidates" )
2864 sameResult = main.TRUE
2865 failMessage = "Nodes have different leaders"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002866 for i in main.activeNodes:
2867 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07002868 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2869 oldAllCandidates.append( node )
2870 oldLeaders.append( node[ 0 ] )
2871 oldCandidates = oldAllCandidates[ 0 ]
2872
2873 # Check that each node has the same leader. Defines oldLeader
2874 if len( set( oldLeaders ) ) != 1:
2875 sameResult = main.FALSE
2876 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2877 oldLeader = None
2878 else:
2879 oldLeader = oldLeaders[ 0 ]
2880
2881 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002882 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07002883 for candidates in oldAllCandidates:
2884 if set( candidates ) != set( oldCandidates ):
2885 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002886 candidateDiscrepancy = True
2887
2888 if candidateDiscrepancy:
2889 failMessage += " and candidates"
2890
acsmars71adceb2015-08-31 15:09:26 -07002891 utilities.assert_equals(
2892 expect=main.TRUE,
2893 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002894 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002895 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002896
2897 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002898 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002899 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002900 if oldLeader is None:
2901 main.log.error( "Leadership isn't consistent." )
2902 withdrawResult = main.FALSE
2903 # Get the CLI of the oldLeader
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002904 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002905 if oldLeader == main.nodes[ i ].ip_address:
2906 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002907 break
2908 else: # FOR/ELSE statement
2909 main.log.error( "Leader election, could not find current leader" )
2910 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002911 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002912 utilities.assert_equals(
2913 expect=main.TRUE,
2914 actual=withdrawResult,
2915 onpass="Node was withdrawn from election",
2916 onfail="Node was not withdrawn from election" )
2917
acsmars71adceb2015-08-31 15:09:26 -07002918 main.step( "Check that a new node was elected leader" )
2919
Jon Hall5cf14d52015-07-16 12:15:19 -07002920 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002921 newLeaderResult = main.TRUE
2922 failMessage = "Nodes have different leaders"
2923
2924 # Get new leaders and candidates
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002925 for i in main.activeNodes:
2926 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07002927 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2928 # elections might no have finished yet
2929 if node[ 0 ] == 'none' and not expectNoLeader:
2930 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2931 "sure elections are complete." )
2932 time.sleep(5)
2933 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2934 # election still isn't done or there is a problem
2935 if node[ 0 ] == 'none':
2936 main.log.error( "No leader was elected on at least 1 node" )
2937 newLeaderResult = main.FALSE
2938 newAllCandidates.append( node )
2939 newLeaders.append( node[ 0 ] )
2940 newCandidates = newAllCandidates[ 0 ]
2941
2942 # Check that each node has the same leader. Defines newLeader
2943 if len( set( newLeaders ) ) != 1:
2944 newLeaderResult = main.FALSE
2945 main.log.error( "Nodes have different leaders: " +
2946 str( newLeaders ) )
2947 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002948 else:
acsmars71adceb2015-08-31 15:09:26 -07002949 newLeader = newLeaders[ 0 ]
2950
2951 # Check that each node's candidate list is the same
2952 for candidates in newAllCandidates:
2953 if set( candidates ) != set( newCandidates ):
2954 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002955 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002956
2957 # Check that the new leader is not the older leader, which was withdrawn
2958 if newLeader == oldLeader:
2959 newLeaderResult = main.FALSE
2960 main.log.error( "All nodes still see old leader: " + oldLeader +
2961 " as the current leader" )
2962
Jon Hall5cf14d52015-07-16 12:15:19 -07002963 utilities.assert_equals(
2964 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002965 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002966 onpass="Leadership election passed",
2967 onfail="Something went wrong with Leadership election" )
2968
acsmars71adceb2015-08-31 15:09:26 -07002969 main.step( "Check that that new leader was the candidate of old leader")
2970 # candidates[ 2 ] should be come the top candidate after withdrawl
2971 correctCandidateResult = main.TRUE
2972 if expectNoLeader:
2973 if newLeader == 'none':
2974 main.log.info( "No leader expected. None found. Pass" )
2975 correctCandidateResult = main.TRUE
2976 else:
2977 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2978 correctCandidateResult = main.FALSE
2979 elif newLeader != oldCandidates[ 2 ]:
2980 correctCandidateResult = main.FALSE
2981 main.log.error( "Candidate " + newLeader + " was elected. " +
2982 oldCandidates[ 2 ] + " should have had priority." )
2983
2984 utilities.assert_equals(
2985 expect=main.TRUE,
2986 actual=correctCandidateResult,
2987 onpass="Correct Candidate Elected",
2988 onfail="Incorrect Candidate Elected" )
2989
Jon Hall5cf14d52015-07-16 12:15:19 -07002990 main.step( "Run for election on old leader( just so everyone " +
2991 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002992 if oldLeaderCLI is not None:
2993 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002994 else:
acsmars71adceb2015-08-31 15:09:26 -07002995 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002996 runResult = main.FALSE
2997 utilities.assert_equals(
2998 expect=main.TRUE,
2999 actual=runResult,
3000 onpass="App re-ran for election",
3001 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07003002 main.step(
3003 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003004 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07003005 positionResult = main.TRUE
3006 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3007
3008 # Reset and reuse the new candidate and leaders lists
3009 newAllCandidates = []
3010 newCandidates = []
3011 newLeaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003012 for i in main.activeNodes:
3013 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07003014 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3015 if oldLeader not in node: # election might no have finished yet
3016 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3017 "be sure elections are complete" )
3018 time.sleep(5)
3019 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3020 if oldLeader not in node: # election still isn't done, errors
3021 main.log.error(
3022 "Old leader was not elected on at least one node" )
3023 positionResult = main.FALSE
3024 newAllCandidates.append( node )
3025 newLeaders.append( node[ 0 ] )
3026 newCandidates = newAllCandidates[ 0 ]
3027
3028 # Check that each node has the same leader. Defines newLeader
3029 if len( set( newLeaders ) ) != 1:
3030 positionResult = main.FALSE
3031 main.log.error( "Nodes have different leaders: " +
3032 str( newLeaders ) )
3033 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003034 else:
acsmars71adceb2015-08-31 15:09:26 -07003035 newLeader = newLeaders[ 0 ]
3036
3037 # Check that each node's candidate list is the same
3038 for candidates in newAllCandidates:
3039 if set( candidates ) != set( newCandidates ):
3040 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003041 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003042
3043 # Check that the re-elected node is last on the candidate List
3044 if oldLeader != newCandidates[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003045 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
acsmars71adceb2015-08-31 15:09:26 -07003046 str( newCandidates ) )
3047 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003048
3049 utilities.assert_equals(
3050 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07003051 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003052 onpass="Old leader successfully re-ran for election",
3053 onfail="Something went wrong with Leadership election after " +
3054 "the old leader re-ran for election" )
3055
3056 def CASE16( self, main ):
3057 """
3058 Install Distributed Primitives app
3059 """
3060 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003061 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003062 assert main, "main not defined"
3063 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003064 assert main.CLIs, "main.CLIs not defined"
3065 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003066
3067 # Variables for the distributed primitives tests
3068 global pCounterName
3069 global iCounterName
3070 global pCounterValue
3071 global iCounterValue
3072 global onosSet
3073 global onosSetName
3074 pCounterName = "TestON-Partitions"
3075 iCounterName = "TestON-inMemory"
3076 pCounterValue = 0
3077 iCounterValue = 0
3078 onosSet = set([])
3079 onosSetName = "TestON-set"
3080
3081 description = "Install Primitives app"
3082 main.case( description )
3083 main.step( "Install Primitives app" )
3084 appName = "org.onosproject.distributedprimitives"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003085 node = main.activeNodes[0]
3086 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003087 utilities.assert_equals( expect=main.TRUE,
3088 actual=appResults,
3089 onpass="Primitives app activated",
3090 onfail="Primitives app not activated" )
3091 time.sleep( 5 ) # To allow all nodes to activate
3092
3093 def CASE17( self, main ):
3094 """
3095 Check for basic functionality with distributed primitives
3096 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003098 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003099 assert main, "main not defined"
3100 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003101 assert main.CLIs, "main.CLIs not defined"
3102 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003103 assert pCounterName, "pCounterName not defined"
3104 assert iCounterName, "iCounterName not defined"
3105 assert onosSetName, "onosSetName not defined"
3106 # NOTE: assert fails if value is 0/None/Empty/False
3107 try:
3108 pCounterValue
3109 except NameError:
3110 main.log.error( "pCounterValue not defined, setting to 0" )
3111 pCounterValue = 0
3112 try:
3113 iCounterValue
3114 except NameError:
3115 main.log.error( "iCounterValue not defined, setting to 0" )
3116 iCounterValue = 0
3117 try:
3118 onosSet
3119 except NameError:
3120 main.log.error( "onosSet not defined, setting to empty Set" )
3121 onosSet = set([])
3122 # Variables for the distributed primitives tests. These are local only
3123 addValue = "a"
3124 addAllValue = "a b c d e f"
3125 retainValue = "c d e f"
3126
3127 description = "Check for basic functionality with distributed " +\
3128 "primitives"
3129 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003130 main.caseExplanation = "Test the methods of the distributed " +\
3131 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003132 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003133 # Partitioned counters
3134 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003135 pCounters = []
3136 threads = []
3137 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003138 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003139 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3140 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003141 args=[ pCounterName ] )
3142 pCounterValue += 1
3143 addedPValues.append( pCounterValue )
3144 threads.append( t )
3145 t.start()
3146
3147 for t in threads:
3148 t.join()
3149 pCounters.append( t.result )
3150 # Check that counter incremented numController times
3151 pCounterResults = True
3152 for i in addedPValues:
3153 tmpResult = i in pCounters
3154 pCounterResults = pCounterResults and tmpResult
3155 if not tmpResult:
3156 main.log.error( str( i ) + " is not in partitioned "
3157 "counter incremented results" )
3158 utilities.assert_equals( expect=True,
3159 actual=pCounterResults,
3160 onpass="Default counter incremented",
3161 onfail="Error incrementing default" +
3162 " counter" )
3163
Jon Halle1a3b752015-07-22 13:02:46 -07003164 main.step( "Get then Increment a default counter on each node" )
3165 pCounters = []
3166 threads = []
3167 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003168 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003169 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3170 name="counterGetAndAdd-" + str( i ),
3171 args=[ pCounterName ] )
3172 addedPValues.append( pCounterValue )
3173 pCounterValue += 1
3174 threads.append( t )
3175 t.start()
3176
3177 for t in threads:
3178 t.join()
3179 pCounters.append( t.result )
3180 # Check that counter incremented numController times
3181 pCounterResults = True
3182 for i in addedPValues:
3183 tmpResult = i in pCounters
3184 pCounterResults = pCounterResults and tmpResult
3185 if not tmpResult:
3186 main.log.error( str( i ) + " is not in partitioned "
3187 "counter incremented results" )
3188 utilities.assert_equals( expect=True,
3189 actual=pCounterResults,
3190 onpass="Default counter incremented",
3191 onfail="Error incrementing default" +
3192 " counter" )
3193
3194 main.step( "Counters we added have the correct values" )
3195 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3196 utilities.assert_equals( expect=main.TRUE,
3197 actual=incrementCheck,
3198 onpass="Added counters are correct",
3199 onfail="Added counters are incorrect" )
3200
3201 main.step( "Add -8 to then get a default counter on each node" )
3202 pCounters = []
3203 threads = []
3204 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003205 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003206 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3207 name="counterIncrement-" + str( i ),
3208 args=[ pCounterName ],
3209 kwargs={ "delta": -8 } )
3210 pCounterValue += -8
3211 addedPValues.append( pCounterValue )
3212 threads.append( t )
3213 t.start()
3214
3215 for t in threads:
3216 t.join()
3217 pCounters.append( t.result )
3218 # Check that counter incremented numController times
3219 pCounterResults = True
3220 for i in addedPValues:
3221 tmpResult = i in pCounters
3222 pCounterResults = pCounterResults and tmpResult
3223 if not tmpResult:
3224 main.log.error( str( i ) + " is not in partitioned "
3225 "counter incremented results" )
3226 utilities.assert_equals( expect=True,
3227 actual=pCounterResults,
3228 onpass="Default counter incremented",
3229 onfail="Error incrementing default" +
3230 " counter" )
3231
3232 main.step( "Add 5 to then get a default counter on each node" )
3233 pCounters = []
3234 threads = []
3235 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003236 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003237 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3238 name="counterIncrement-" + str( i ),
3239 args=[ pCounterName ],
3240 kwargs={ "delta": 5 } )
3241 pCounterValue += 5
3242 addedPValues.append( pCounterValue )
3243 threads.append( t )
3244 t.start()
3245
3246 for t in threads:
3247 t.join()
3248 pCounters.append( t.result )
3249 # Check that counter incremented numController times
3250 pCounterResults = True
3251 for i in addedPValues:
3252 tmpResult = i in pCounters
3253 pCounterResults = pCounterResults and tmpResult
3254 if not tmpResult:
3255 main.log.error( str( i ) + " is not in partitioned "
3256 "counter incremented results" )
3257 utilities.assert_equals( expect=True,
3258 actual=pCounterResults,
3259 onpass="Default counter incremented",
3260 onfail="Error incrementing default" +
3261 " counter" )
3262
3263 main.step( "Get then add 5 to a default counter on each node" )
3264 pCounters = []
3265 threads = []
3266 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003267 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003268 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3269 name="counterIncrement-" + str( i ),
3270 args=[ pCounterName ],
3271 kwargs={ "delta": 5 } )
3272 addedPValues.append( pCounterValue )
3273 pCounterValue += 5
3274 threads.append( t )
3275 t.start()
3276
3277 for t in threads:
3278 t.join()
3279 pCounters.append( t.result )
3280 # Check that counter incremented numController times
3281 pCounterResults = True
3282 for i in addedPValues:
3283 tmpResult = i in pCounters
3284 pCounterResults = pCounterResults and tmpResult
3285 if not tmpResult:
3286 main.log.error( str( i ) + " is not in partitioned "
3287 "counter incremented results" )
3288 utilities.assert_equals( expect=True,
3289 actual=pCounterResults,
3290 onpass="Default counter incremented",
3291 onfail="Error incrementing default" +
3292 " counter" )
3293
3294 main.step( "Counters we added have the correct values" )
3295 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3296 utilities.assert_equals( expect=main.TRUE,
3297 actual=incrementCheck,
3298 onpass="Added counters are correct",
3299 onfail="Added counters are incorrect" )
3300
3301 # In-Memory counters
3302 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003303 iCounters = []
3304 addedIValues = []
3305 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003306 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003307 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003308 name="icounterIncrement-" + str( i ),
3309 args=[ iCounterName ],
3310 kwargs={ "inMemory": True } )
3311 iCounterValue += 1
3312 addedIValues.append( iCounterValue )
3313 threads.append( t )
3314 t.start()
3315
3316 for t in threads:
3317 t.join()
3318 iCounters.append( t.result )
3319 # Check that counter incremented numController times
3320 iCounterResults = True
3321 for i in addedIValues:
3322 tmpResult = i in iCounters
3323 iCounterResults = iCounterResults and tmpResult
3324 if not tmpResult:
3325 main.log.error( str( i ) + " is not in the in-memory "
3326 "counter incremented results" )
3327 utilities.assert_equals( expect=True,
3328 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003329 onpass="In-memory counter incremented",
3330 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003331 " counter" )
3332
Jon Halle1a3b752015-07-22 13:02:46 -07003333 main.step( "Get then Increment a in-memory counter on each node" )
3334 iCounters = []
3335 threads = []
3336 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003337 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003338 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3339 name="counterGetAndAdd-" + str( i ),
3340 args=[ iCounterName ],
3341 kwargs={ "inMemory": True } )
3342 addedIValues.append( iCounterValue )
3343 iCounterValue += 1
3344 threads.append( t )
3345 t.start()
3346
3347 for t in threads:
3348 t.join()
3349 iCounters.append( t.result )
3350 # Check that counter incremented numController times
3351 iCounterResults = True
3352 for i in addedIValues:
3353 tmpResult = i in iCounters
3354 iCounterResults = iCounterResults and tmpResult
3355 if not tmpResult:
3356 main.log.error( str( i ) + " is not in in-memory "
3357 "counter incremented results" )
3358 utilities.assert_equals( expect=True,
3359 actual=iCounterResults,
3360 onpass="In-memory counter incremented",
3361 onfail="Error incrementing in-memory" +
3362 " counter" )
3363
3364 main.step( "Counters we added have the correct values" )
3365 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3366 utilities.assert_equals( expect=main.TRUE,
3367 actual=incrementCheck,
3368 onpass="Added counters are correct",
3369 onfail="Added counters are incorrect" )
3370
3371 main.step( "Add -8 to then get a in-memory counter on each node" )
3372 iCounters = []
3373 threads = []
3374 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003375 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003376 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3377 name="counterIncrement-" + str( i ),
3378 args=[ iCounterName ],
3379 kwargs={ "delta": -8, "inMemory": True } )
3380 iCounterValue += -8
3381 addedIValues.append( iCounterValue )
3382 threads.append( t )
3383 t.start()
3384
3385 for t in threads:
3386 t.join()
3387 iCounters.append( t.result )
3388 # Check that counter incremented numController times
3389 iCounterResults = True
3390 for i in addedIValues:
3391 tmpResult = i in iCounters
3392 iCounterResults = iCounterResults and tmpResult
3393 if not tmpResult:
3394 main.log.error( str( i ) + " is not in in-memory "
3395 "counter incremented results" )
3396 utilities.assert_equals( expect=True,
3397 actual=pCounterResults,
3398 onpass="In-memory counter incremented",
3399 onfail="Error incrementing in-memory" +
3400 " counter" )
3401
3402 main.step( "Add 5 to then get a in-memory counter on each node" )
3403 iCounters = []
3404 threads = []
3405 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003406 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003407 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3408 name="counterIncrement-" + str( i ),
3409 args=[ iCounterName ],
3410 kwargs={ "delta": 5, "inMemory": True } )
3411 iCounterValue += 5
3412 addedIValues.append( iCounterValue )
3413 threads.append( t )
3414 t.start()
3415
3416 for t in threads:
3417 t.join()
3418 iCounters.append( t.result )
3419 # Check that counter incremented numController times
3420 iCounterResults = True
3421 for i in addedIValues:
3422 tmpResult = i in iCounters
3423 iCounterResults = iCounterResults and tmpResult
3424 if not tmpResult:
3425 main.log.error( str( i ) + " is not in in-memory "
3426 "counter incremented results" )
3427 utilities.assert_equals( expect=True,
3428 actual=pCounterResults,
3429 onpass="In-memory counter incremented",
3430 onfail="Error incrementing in-memory" +
3431 " counter" )
3432
3433 main.step( "Get then add 5 to a in-memory counter on each node" )
3434 iCounters = []
3435 threads = []
3436 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003437 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003438 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3439 name="counterIncrement-" + str( i ),
3440 args=[ iCounterName ],
3441 kwargs={ "delta": 5, "inMemory": True } )
3442 addedIValues.append( iCounterValue )
3443 iCounterValue += 5
3444 threads.append( t )
3445 t.start()
3446
3447 for t in threads:
3448 t.join()
3449 iCounters.append( t.result )
3450 # Check that counter incremented numController times
3451 iCounterResults = True
3452 for i in addedIValues:
3453 tmpResult = i in iCounters
3454 iCounterResults = iCounterResults and tmpResult
3455 if not tmpResult:
3456 main.log.error( str( i ) + " is not in in-memory "
3457 "counter incremented results" )
3458 utilities.assert_equals( expect=True,
3459 actual=iCounterResults,
3460 onpass="In-memory counter incremented",
3461 onfail="Error incrementing in-memory" +
3462 " counter" )
3463
3464 main.step( "Counters we added have the correct values" )
3465 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3466 utilities.assert_equals( expect=main.TRUE,
3467 actual=incrementCheck,
3468 onpass="Added counters are correct",
3469 onfail="Added counters are incorrect" )
3470
Jon Hall5cf14d52015-07-16 12:15:19 -07003471 main.step( "Check counters are consistant across nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07003472 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003473 utilities.assert_equals( expect=main.TRUE,
3474 actual=consistentCounterResults,
3475 onpass="ONOS counters are consistent " +
3476 "across nodes",
3477 onfail="ONOS Counters are inconsistent " +
3478 "across nodes" )
3479
3480 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003481 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3482 incrementCheck = incrementCheck and \
3483 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003484 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003485 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003486 onpass="Added counters are correct",
3487 onfail="Added counters are incorrect" )
3488 # DISTRIBUTED SETS
3489 main.step( "Distributed Set get" )
3490 size = len( onosSet )
3491 getResponses = []
3492 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003493 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003494 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003495 name="setTestGet-" + str( i ),
3496 args=[ onosSetName ] )
3497 threads.append( t )
3498 t.start()
3499 for t in threads:
3500 t.join()
3501 getResponses.append( t.result )
3502
3503 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003504 for i in range( len( main.activeNodes ) ):
3505 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003506 if isinstance( getResponses[ i ], list):
3507 current = set( getResponses[ i ] )
3508 if len( current ) == len( getResponses[ i ] ):
3509 # no repeats
3510 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003511 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003512 " has incorrect view" +
3513 " of set " + onosSetName + ":\n" +
3514 str( getResponses[ i ] ) )
3515 main.log.debug( "Expected: " + str( onosSet ) )
3516 main.log.debug( "Actual: " + str( current ) )
3517 getResults = main.FALSE
3518 else:
3519 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003520 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003521 " has repeat elements in" +
3522 " set " + onosSetName + ":\n" +
3523 str( getResponses[ i ] ) )
3524 getResults = main.FALSE
3525 elif getResponses[ i ] == main.ERROR:
3526 getResults = main.FALSE
3527 utilities.assert_equals( expect=main.TRUE,
3528 actual=getResults,
3529 onpass="Set elements are correct",
3530 onfail="Set elements are incorrect" )
3531
3532 main.step( "Distributed Set size" )
3533 sizeResponses = []
3534 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003535 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003536 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003537 name="setTestSize-" + str( i ),
3538 args=[ onosSetName ] )
3539 threads.append( t )
3540 t.start()
3541 for t in threads:
3542 t.join()
3543 sizeResponses.append( t.result )
3544
3545 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003546 for i in range( len( main.activeNodes ) ):
3547 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003548 if size != sizeResponses[ i ]:
3549 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003550 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003551 " expected a size of " + str( size ) +
3552 " for set " + onosSetName +
3553 " but got " + str( sizeResponses[ i ] ) )
3554 utilities.assert_equals( expect=main.TRUE,
3555 actual=sizeResults,
3556 onpass="Set sizes are correct",
3557 onfail="Set sizes are incorrect" )
3558
3559 main.step( "Distributed Set add()" )
3560 onosSet.add( addValue )
3561 addResponses = []
3562 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003563 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003564 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003565 name="setTestAdd-" + str( i ),
3566 args=[ onosSetName, addValue ] )
3567 threads.append( t )
3568 t.start()
3569 for t in threads:
3570 t.join()
3571 addResponses.append( t.result )
3572
3573 # main.TRUE = successfully changed the set
3574 # main.FALSE = action resulted in no change in set
3575 # main.ERROR - Some error in executing the function
3576 addResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003577 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003578 if addResponses[ i ] == main.TRUE:
3579 # All is well
3580 pass
3581 elif addResponses[ i ] == main.FALSE:
3582 # Already in set, probably fine
3583 pass
3584 elif addResponses[ i ] == main.ERROR:
3585 # Error in execution
3586 addResults = main.FALSE
3587 else:
3588 # unexpected result
3589 addResults = main.FALSE
3590 if addResults != main.TRUE:
3591 main.log.error( "Error executing set add" )
3592
3593 # Check if set is still correct
3594 size = len( onosSet )
3595 getResponses = []
3596 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003597 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003598 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003599 name="setTestGet-" + str( i ),
3600 args=[ onosSetName ] )
3601 threads.append( t )
3602 t.start()
3603 for t in threads:
3604 t.join()
3605 getResponses.append( t.result )
3606 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003607 for i in range( len( main.activeNodes ) ):
3608 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003609 if isinstance( getResponses[ i ], list):
3610 current = set( getResponses[ i ] )
3611 if len( current ) == len( getResponses[ i ] ):
3612 # no repeats
3613 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003614 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003615 " of set " + onosSetName + ":\n" +
3616 str( getResponses[ i ] ) )
3617 main.log.debug( "Expected: " + str( onosSet ) )
3618 main.log.debug( "Actual: " + str( current ) )
3619 getResults = main.FALSE
3620 else:
3621 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003622 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003623 " set " + onosSetName + ":\n" +
3624 str( getResponses[ i ] ) )
3625 getResults = main.FALSE
3626 elif getResponses[ i ] == main.ERROR:
3627 getResults = main.FALSE
3628 sizeResponses = []
3629 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003630 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003631 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003632 name="setTestSize-" + str( i ),
3633 args=[ onosSetName ] )
3634 threads.append( t )
3635 t.start()
3636 for t in threads:
3637 t.join()
3638 sizeResponses.append( t.result )
3639 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003640 for i in range( len( main.activeNodes ) ):
3641 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003642 if size != sizeResponses[ i ]:
3643 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003644 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003645 " expected a size of " + str( size ) +
3646 " for set " + onosSetName +
3647 " but got " + str( sizeResponses[ i ] ) )
3648 addResults = addResults and getResults and sizeResults
3649 utilities.assert_equals( expect=main.TRUE,
3650 actual=addResults,
3651 onpass="Set add correct",
3652 onfail="Set add was incorrect" )
3653
3654 main.step( "Distributed Set addAll()" )
3655 onosSet.update( addAllValue.split() )
3656 addResponses = []
3657 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003658 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003659 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003660 name="setTestAddAll-" + str( i ),
3661 args=[ onosSetName, addAllValue ] )
3662 threads.append( t )
3663 t.start()
3664 for t in threads:
3665 t.join()
3666 addResponses.append( t.result )
3667
3668 # main.TRUE = successfully changed the set
3669 # main.FALSE = action resulted in no change in set
3670 # main.ERROR - Some error in executing the function
3671 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003672 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003673 if addResponses[ i ] == main.TRUE:
3674 # All is well
3675 pass
3676 elif addResponses[ i ] == main.FALSE:
3677 # Already in set, probably fine
3678 pass
3679 elif addResponses[ i ] == main.ERROR:
3680 # Error in execution
3681 addAllResults = main.FALSE
3682 else:
3683 # unexpected result
3684 addAllResults = main.FALSE
3685 if addAllResults != main.TRUE:
3686 main.log.error( "Error executing set addAll" )
3687
3688 # Check if set is still correct
3689 size = len( onosSet )
3690 getResponses = []
3691 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003692 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003693 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003694 name="setTestGet-" + str( i ),
3695 args=[ onosSetName ] )
3696 threads.append( t )
3697 t.start()
3698 for t in threads:
3699 t.join()
3700 getResponses.append( t.result )
3701 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003702 for i in range( len( main.activeNodes ) ):
3703 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003704 if isinstance( getResponses[ i ], list):
3705 current = set( getResponses[ i ] )
3706 if len( current ) == len( getResponses[ i ] ):
3707 # no repeats
3708 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003709 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003710 " has incorrect view" +
3711 " of set " + onosSetName + ":\n" +
3712 str( getResponses[ i ] ) )
3713 main.log.debug( "Expected: " + str( onosSet ) )
3714 main.log.debug( "Actual: " + str( current ) )
3715 getResults = main.FALSE
3716 else:
3717 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003718 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003719 " has repeat elements in" +
3720 " set " + onosSetName + ":\n" +
3721 str( getResponses[ i ] ) )
3722 getResults = main.FALSE
3723 elif getResponses[ i ] == main.ERROR:
3724 getResults = main.FALSE
3725 sizeResponses = []
3726 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003727 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003728 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003729 name="setTestSize-" + str( i ),
3730 args=[ onosSetName ] )
3731 threads.append( t )
3732 t.start()
3733 for t in threads:
3734 t.join()
3735 sizeResponses.append( t.result )
3736 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003737 for i in range( len( main.activeNodes ) ):
3738 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003739 if size != sizeResponses[ i ]:
3740 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003741 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003742 " expected a size of " + str( size ) +
3743 " for set " + onosSetName +
3744 " but got " + str( sizeResponses[ i ] ) )
3745 addAllResults = addAllResults and getResults and sizeResults
3746 utilities.assert_equals( expect=main.TRUE,
3747 actual=addAllResults,
3748 onpass="Set addAll correct",
3749 onfail="Set addAll was incorrect" )
3750
3751 main.step( "Distributed Set contains()" )
3752 containsResponses = []
3753 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003754 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003755 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003756 name="setContains-" + str( i ),
3757 args=[ onosSetName ],
3758 kwargs={ "values": addValue } )
3759 threads.append( t )
3760 t.start()
3761 for t in threads:
3762 t.join()
3763 # NOTE: This is the tuple
3764 containsResponses.append( t.result )
3765
3766 containsResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003767 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003768 if containsResponses[ i ] == main.ERROR:
3769 containsResults = main.FALSE
3770 else:
3771 containsResults = containsResults and\
3772 containsResponses[ i ][ 1 ]
3773 utilities.assert_equals( expect=main.TRUE,
3774 actual=containsResults,
3775 onpass="Set contains is functional",
3776 onfail="Set contains failed" )
3777
3778 main.step( "Distributed Set containsAll()" )
3779 containsAllResponses = []
3780 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003781 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003782 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003783 name="setContainsAll-" + str( i ),
3784 args=[ onosSetName ],
3785 kwargs={ "values": addAllValue } )
3786 threads.append( t )
3787 t.start()
3788 for t in threads:
3789 t.join()
3790 # NOTE: This is the tuple
3791 containsAllResponses.append( t.result )
3792
3793 containsAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003794 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003795 if containsResponses[ i ] == main.ERROR:
3796 containsResults = main.FALSE
3797 else:
3798 containsResults = containsResults and\
3799 containsResponses[ i ][ 1 ]
3800 utilities.assert_equals( expect=main.TRUE,
3801 actual=containsAllResults,
3802 onpass="Set containsAll is functional",
3803 onfail="Set containsAll failed" )
3804
3805 main.step( "Distributed Set remove()" )
3806 onosSet.remove( addValue )
3807 removeResponses = []
3808 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003809 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003810 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003811 name="setTestRemove-" + str( i ),
3812 args=[ onosSetName, addValue ] )
3813 threads.append( t )
3814 t.start()
3815 for t in threads:
3816 t.join()
3817 removeResponses.append( t.result )
3818
3819 # main.TRUE = successfully changed the set
3820 # main.FALSE = action resulted in no change in set
3821 # main.ERROR - Some error in executing the function
3822 removeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003823 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003824 if removeResponses[ i ] == main.TRUE:
3825 # All is well
3826 pass
3827 elif removeResponses[ i ] == main.FALSE:
3828 # not in set, probably fine
3829 pass
3830 elif removeResponses[ i ] == main.ERROR:
3831 # Error in execution
3832 removeResults = main.FALSE
3833 else:
3834 # unexpected result
3835 removeResults = main.FALSE
3836 if removeResults != main.TRUE:
3837 main.log.error( "Error executing set remove" )
3838
3839 # Check if set is still correct
3840 size = len( onosSet )
3841 getResponses = []
3842 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003843 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003844 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003845 name="setTestGet-" + str( i ),
3846 args=[ onosSetName ] )
3847 threads.append( t )
3848 t.start()
3849 for t in threads:
3850 t.join()
3851 getResponses.append( t.result )
3852 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003853 for i in range( len( main.activeNodes ) ):
3854 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003855 if isinstance( getResponses[ i ], list):
3856 current = set( getResponses[ i ] )
3857 if len( current ) == len( getResponses[ i ] ):
3858 # no repeats
3859 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003860 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003861 " has incorrect view" +
3862 " of set " + onosSetName + ":\n" +
3863 str( getResponses[ i ] ) )
3864 main.log.debug( "Expected: " + str( onosSet ) )
3865 main.log.debug( "Actual: " + str( current ) )
3866 getResults = main.FALSE
3867 else:
3868 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003869 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003870 " has repeat elements in" +
3871 " set " + onosSetName + ":\n" +
3872 str( getResponses[ i ] ) )
3873 getResults = main.FALSE
3874 elif getResponses[ i ] == main.ERROR:
3875 getResults = main.FALSE
3876 sizeResponses = []
3877 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003878 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003879 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003880 name="setTestSize-" + str( i ),
3881 args=[ onosSetName ] )
3882 threads.append( t )
3883 t.start()
3884 for t in threads:
3885 t.join()
3886 sizeResponses.append( t.result )
3887 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003888 for i in range( len( main.activeNodes ) ):
3889 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003890 if size != sizeResponses[ i ]:
3891 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003892 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003893 " expected a size of " + str( size ) +
3894 " for set " + onosSetName +
3895 " but got " + str( sizeResponses[ i ] ) )
3896 removeResults = removeResults and getResults and sizeResults
3897 utilities.assert_equals( expect=main.TRUE,
3898 actual=removeResults,
3899 onpass="Set remove correct",
3900 onfail="Set remove was incorrect" )
3901
3902 main.step( "Distributed Set removeAll()" )
3903 onosSet.difference_update( addAllValue.split() )
3904 removeAllResponses = []
3905 threads = []
3906 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003907 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003908 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003909 name="setTestRemoveAll-" + str( i ),
3910 args=[ onosSetName, addAllValue ] )
3911 threads.append( t )
3912 t.start()
3913 for t in threads:
3914 t.join()
3915 removeAllResponses.append( t.result )
3916 except Exception, e:
3917 main.log.exception(e)
3918
3919 # main.TRUE = successfully changed the set
3920 # main.FALSE = action resulted in no change in set
3921 # main.ERROR - Some error in executing the function
3922 removeAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003923 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003924 if removeAllResponses[ i ] == main.TRUE:
3925 # All is well
3926 pass
3927 elif removeAllResponses[ i ] == main.FALSE:
3928 # not in set, probably fine
3929 pass
3930 elif removeAllResponses[ i ] == main.ERROR:
3931 # Error in execution
3932 removeAllResults = main.FALSE
3933 else:
3934 # unexpected result
3935 removeAllResults = main.FALSE
3936 if removeAllResults != main.TRUE:
3937 main.log.error( "Error executing set removeAll" )
3938
3939 # Check if set is still correct
3940 size = len( onosSet )
3941 getResponses = []
3942 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003943 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003944 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003945 name="setTestGet-" + str( i ),
3946 args=[ onosSetName ] )
3947 threads.append( t )
3948 t.start()
3949 for t in threads:
3950 t.join()
3951 getResponses.append( t.result )
3952 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003953 for i in range( len( main.activeNodes ) ):
3954 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003955 if isinstance( getResponses[ i ], list):
3956 current = set( getResponses[ i ] )
3957 if len( current ) == len( getResponses[ i ] ):
3958 # no repeats
3959 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003960 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003961 " has incorrect view" +
3962 " of set " + onosSetName + ":\n" +
3963 str( getResponses[ i ] ) )
3964 main.log.debug( "Expected: " + str( onosSet ) )
3965 main.log.debug( "Actual: " + str( current ) )
3966 getResults = main.FALSE
3967 else:
3968 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003969 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003970 " has repeat elements in" +
3971 " set " + onosSetName + ":\n" +
3972 str( getResponses[ i ] ) )
3973 getResults = main.FALSE
3974 elif getResponses[ i ] == main.ERROR:
3975 getResults = main.FALSE
3976 sizeResponses = []
3977 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003978 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003979 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003980 name="setTestSize-" + str( i ),
3981 args=[ onosSetName ] )
3982 threads.append( t )
3983 t.start()
3984 for t in threads:
3985 t.join()
3986 sizeResponses.append( t.result )
3987 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003988 for i in range( len( main.activeNodes ) ):
3989 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003990 if size != sizeResponses[ i ]:
3991 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003992 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003993 " expected a size of " + str( size ) +
3994 " for set " + onosSetName +
3995 " but got " + str( sizeResponses[ i ] ) )
3996 removeAllResults = removeAllResults and getResults and sizeResults
3997 utilities.assert_equals( expect=main.TRUE,
3998 actual=removeAllResults,
3999 onpass="Set removeAll correct",
4000 onfail="Set removeAll was incorrect" )
4001
4002 main.step( "Distributed Set addAll()" )
4003 onosSet.update( addAllValue.split() )
4004 addResponses = []
4005 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004006 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004007 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004008 name="setTestAddAll-" + str( i ),
4009 args=[ onosSetName, addAllValue ] )
4010 threads.append( t )
4011 t.start()
4012 for t in threads:
4013 t.join()
4014 addResponses.append( t.result )
4015
4016 # main.TRUE = successfully changed the set
4017 # main.FALSE = action resulted in no change in set
4018 # main.ERROR - Some error in executing the function
4019 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004020 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004021 if addResponses[ i ] == main.TRUE:
4022 # All is well
4023 pass
4024 elif addResponses[ i ] == main.FALSE:
4025 # Already in set, probably fine
4026 pass
4027 elif addResponses[ i ] == main.ERROR:
4028 # Error in execution
4029 addAllResults = main.FALSE
4030 else:
4031 # unexpected result
4032 addAllResults = main.FALSE
4033 if addAllResults != main.TRUE:
4034 main.log.error( "Error executing set addAll" )
4035
4036 # Check if set is still correct
4037 size = len( onosSet )
4038 getResponses = []
4039 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004040 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004041 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004042 name="setTestGet-" + str( i ),
4043 args=[ onosSetName ] )
4044 threads.append( t )
4045 t.start()
4046 for t in threads:
4047 t.join()
4048 getResponses.append( t.result )
4049 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004050 for i in range( len( main.activeNodes ) ):
4051 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004052 if isinstance( getResponses[ i ], list):
4053 current = set( getResponses[ i ] )
4054 if len( current ) == len( getResponses[ i ] ):
4055 # no repeats
4056 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004057 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004058 " has incorrect view" +
4059 " of set " + onosSetName + ":\n" +
4060 str( getResponses[ i ] ) )
4061 main.log.debug( "Expected: " + str( onosSet ) )
4062 main.log.debug( "Actual: " + str( current ) )
4063 getResults = main.FALSE
4064 else:
4065 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004066 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004067 " has repeat elements in" +
4068 " set " + onosSetName + ":\n" +
4069 str( getResponses[ i ] ) )
4070 getResults = main.FALSE
4071 elif getResponses[ i ] == main.ERROR:
4072 getResults = main.FALSE
4073 sizeResponses = []
4074 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004075 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004076 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004077 name="setTestSize-" + str( i ),
4078 args=[ onosSetName ] )
4079 threads.append( t )
4080 t.start()
4081 for t in threads:
4082 t.join()
4083 sizeResponses.append( t.result )
4084 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004085 for i in range( len( main.activeNodes ) ):
4086 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004087 if size != sizeResponses[ i ]:
4088 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004089 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004090 " expected a size of " + str( size ) +
4091 " for set " + onosSetName +
4092 " but got " + str( sizeResponses[ i ] ) )
4093 addAllResults = addAllResults and getResults and sizeResults
4094 utilities.assert_equals( expect=main.TRUE,
4095 actual=addAllResults,
4096 onpass="Set addAll correct",
4097 onfail="Set addAll was incorrect" )
4098
4099 main.step( "Distributed Set clear()" )
4100 onosSet.clear()
4101 clearResponses = []
4102 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004103 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004104 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004105 name="setTestClear-" + str( i ),
4106 args=[ onosSetName, " "], # Values doesn't matter
4107 kwargs={ "clear": True } )
4108 threads.append( t )
4109 t.start()
4110 for t in threads:
4111 t.join()
4112 clearResponses.append( t.result )
4113
4114 # main.TRUE = successfully changed the set
4115 # main.FALSE = action resulted in no change in set
4116 # main.ERROR - Some error in executing the function
4117 clearResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004118 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004119 if clearResponses[ i ] == main.TRUE:
4120 # All is well
4121 pass
4122 elif clearResponses[ i ] == main.FALSE:
4123 # Nothing set, probably fine
4124 pass
4125 elif clearResponses[ i ] == main.ERROR:
4126 # Error in execution
4127 clearResults = main.FALSE
4128 else:
4129 # unexpected result
4130 clearResults = main.FALSE
4131 if clearResults != main.TRUE:
4132 main.log.error( "Error executing set clear" )
4133
4134 # Check if set is still correct
4135 size = len( onosSet )
4136 getResponses = []
4137 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004138 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004139 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004140 name="setTestGet-" + str( i ),
4141 args=[ onosSetName ] )
4142 threads.append( t )
4143 t.start()
4144 for t in threads:
4145 t.join()
4146 getResponses.append( t.result )
4147 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004148 for i in range( len( main.activeNodes ) ):
4149 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004150 if isinstance( getResponses[ i ], list):
4151 current = set( getResponses[ i ] )
4152 if len( current ) == len( getResponses[ i ] ):
4153 # no repeats
4154 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004155 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004156 " has incorrect view" +
4157 " of set " + onosSetName + ":\n" +
4158 str( getResponses[ i ] ) )
4159 main.log.debug( "Expected: " + str( onosSet ) )
4160 main.log.debug( "Actual: " + str( current ) )
4161 getResults = main.FALSE
4162 else:
4163 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004164 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004165 " has repeat elements in" +
4166 " set " + onosSetName + ":\n" +
4167 str( getResponses[ i ] ) )
4168 getResults = main.FALSE
4169 elif getResponses[ i ] == main.ERROR:
4170 getResults = main.FALSE
4171 sizeResponses = []
4172 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004173 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004174 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004175 name="setTestSize-" + str( i ),
4176 args=[ onosSetName ] )
4177 threads.append( t )
4178 t.start()
4179 for t in threads:
4180 t.join()
4181 sizeResponses.append( t.result )
4182 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004183 for i in range( len( main.activeNodes ) ):
4184 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004185 if size != sizeResponses[ i ]:
4186 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004187 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004188 " expected a size of " + str( size ) +
4189 " for set " + onosSetName +
4190 " but got " + str( sizeResponses[ i ] ) )
4191 clearResults = clearResults and getResults and sizeResults
4192 utilities.assert_equals( expect=main.TRUE,
4193 actual=clearResults,
4194 onpass="Set clear correct",
4195 onfail="Set clear was incorrect" )
4196
4197 main.step( "Distributed Set addAll()" )
4198 onosSet.update( addAllValue.split() )
4199 addResponses = []
4200 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004201 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004202 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004203 name="setTestAddAll-" + str( i ),
4204 args=[ onosSetName, addAllValue ] )
4205 threads.append( t )
4206 t.start()
4207 for t in threads:
4208 t.join()
4209 addResponses.append( t.result )
4210
4211 # main.TRUE = successfully changed the set
4212 # main.FALSE = action resulted in no change in set
4213 # main.ERROR - Some error in executing the function
4214 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004215 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004216 if addResponses[ i ] == main.TRUE:
4217 # All is well
4218 pass
4219 elif addResponses[ i ] == main.FALSE:
4220 # Already in set, probably fine
4221 pass
4222 elif addResponses[ i ] == main.ERROR:
4223 # Error in execution
4224 addAllResults = main.FALSE
4225 else:
4226 # unexpected result
4227 addAllResults = main.FALSE
4228 if addAllResults != main.TRUE:
4229 main.log.error( "Error executing set addAll" )
4230
4231 # Check if set is still correct
4232 size = len( onosSet )
4233 getResponses = []
4234 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004235 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004236 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004237 name="setTestGet-" + str( i ),
4238 args=[ onosSetName ] )
4239 threads.append( t )
4240 t.start()
4241 for t in threads:
4242 t.join()
4243 getResponses.append( t.result )
4244 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004245 for i in range( len( main.activeNodes ) ):
4246 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004247 if isinstance( getResponses[ i ], list):
4248 current = set( getResponses[ i ] )
4249 if len( current ) == len( getResponses[ i ] ):
4250 # no repeats
4251 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004252 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004253 " has incorrect view" +
4254 " of set " + onosSetName + ":\n" +
4255 str( getResponses[ i ] ) )
4256 main.log.debug( "Expected: " + str( onosSet ) )
4257 main.log.debug( "Actual: " + str( current ) )
4258 getResults = main.FALSE
4259 else:
4260 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004261 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004262 " has repeat elements in" +
4263 " set " + onosSetName + ":\n" +
4264 str( getResponses[ i ] ) )
4265 getResults = main.FALSE
4266 elif getResponses[ i ] == main.ERROR:
4267 getResults = main.FALSE
4268 sizeResponses = []
4269 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004270 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004271 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004272 name="setTestSize-" + str( i ),
4273 args=[ onosSetName ] )
4274 threads.append( t )
4275 t.start()
4276 for t in threads:
4277 t.join()
4278 sizeResponses.append( t.result )
4279 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004280 for i in range( len( main.activeNodes ) ):
4281 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004282 if size != sizeResponses[ i ]:
4283 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004284 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004285 " expected a size of " + str( size ) +
4286 " for set " + onosSetName +
4287 " but got " + str( sizeResponses[ i ] ) )
4288 addAllResults = addAllResults and getResults and sizeResults
4289 utilities.assert_equals( expect=main.TRUE,
4290 actual=addAllResults,
4291 onpass="Set addAll correct",
4292 onfail="Set addAll was incorrect" )
4293
4294 main.step( "Distributed Set retain()" )
4295 onosSet.intersection_update( retainValue.split() )
4296 retainResponses = []
4297 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004298 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004299 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004300 name="setTestRetain-" + str( i ),
4301 args=[ onosSetName, retainValue ],
4302 kwargs={ "retain": True } )
4303 threads.append( t )
4304 t.start()
4305 for t in threads:
4306 t.join()
4307 retainResponses.append( t.result )
4308
4309 # main.TRUE = successfully changed the set
4310 # main.FALSE = action resulted in no change in set
4311 # main.ERROR - Some error in executing the function
4312 retainResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004313 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004314 if retainResponses[ i ] == main.TRUE:
4315 # All is well
4316 pass
4317 elif retainResponses[ i ] == main.FALSE:
4318 # Already in set, probably fine
4319 pass
4320 elif retainResponses[ i ] == main.ERROR:
4321 # Error in execution
4322 retainResults = main.FALSE
4323 else:
4324 # unexpected result
4325 retainResults = main.FALSE
4326 if retainResults != main.TRUE:
4327 main.log.error( "Error executing set retain" )
4328
4329 # Check if set is still correct
4330 size = len( onosSet )
4331 getResponses = []
4332 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004333 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004334 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004335 name="setTestGet-" + str( i ),
4336 args=[ onosSetName ] )
4337 threads.append( t )
4338 t.start()
4339 for t in threads:
4340 t.join()
4341 getResponses.append( t.result )
4342 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004343 for i in range( len( main.activeNodes ) ):
4344 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004345 if isinstance( getResponses[ i ], list):
4346 current = set( getResponses[ i ] )
4347 if len( current ) == len( getResponses[ i ] ):
4348 # no repeats
4349 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004350 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004351 " has incorrect view" +
4352 " of set " + onosSetName + ":\n" +
4353 str( getResponses[ i ] ) )
4354 main.log.debug( "Expected: " + str( onosSet ) )
4355 main.log.debug( "Actual: " + str( current ) )
4356 getResults = main.FALSE
4357 else:
4358 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004359 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004360 " has repeat elements in" +
4361 " set " + onosSetName + ":\n" +
4362 str( getResponses[ i ] ) )
4363 getResults = main.FALSE
4364 elif getResponses[ i ] == main.ERROR:
4365 getResults = main.FALSE
4366 sizeResponses = []
4367 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004368 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004369 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004370 name="setTestSize-" + str( i ),
4371 args=[ onosSetName ] )
4372 threads.append( t )
4373 t.start()
4374 for t in threads:
4375 t.join()
4376 sizeResponses.append( t.result )
4377 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004378 for i in range( len( main.activeNodes ) ):
4379 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004380 if size != sizeResponses[ i ]:
4381 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004382 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004383 str( size ) + " for set " + onosSetName +
4384 " but got " + str( sizeResponses[ i ] ) )
4385 retainResults = retainResults and getResults and sizeResults
4386 utilities.assert_equals( expect=main.TRUE,
4387 actual=retainResults,
4388 onpass="Set retain correct",
4389 onfail="Set retain was incorrect" )
4390
Jon Hall2a5002c2015-08-21 16:49:11 -07004391 # Transactional maps
4392 main.step( "Partitioned Transactional maps put" )
4393 tMapValue = "Testing"
4394 numKeys = 100
4395 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004396 node = main.activeNodes[0]
4397 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall2a5002c2015-08-21 16:49:11 -07004398 if len( putResponses ) == 100:
4399 for i in putResponses:
4400 if putResponses[ i ][ 'value' ] != tMapValue:
4401 putResult = False
4402 else:
4403 putResult = False
4404 if not putResult:
4405 main.log.debug( "Put response values: " + str( putResponses ) )
4406 utilities.assert_equals( expect=True,
4407 actual=putResult,
4408 onpass="Partitioned Transactional Map put successful",
4409 onfail="Partitioned Transactional Map put values are incorrect" )
4410
4411 main.step( "Partitioned Transactional maps get" )
4412 getCheck = True
4413 for n in range( 1, numKeys + 1 ):
4414 getResponses = []
4415 threads = []
4416 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004417 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004418 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4419 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004420 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004421 threads.append( t )
4422 t.start()
4423 for t in threads:
4424 t.join()
4425 getResponses.append( t.result )
4426 for node in getResponses:
4427 if node != tMapValue:
4428 valueCheck = False
4429 if not valueCheck:
4430 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4431 main.log.warn( getResponses )
4432 getCheck = getCheck and valueCheck
4433 utilities.assert_equals( expect=True,
4434 actual=getCheck,
4435 onpass="Partitioned Transactional Map get values were correct",
4436 onfail="Partitioned Transactional Map values incorrect" )
4437
4438 main.step( "In-memory Transactional maps put" )
4439 tMapValue = "Testing"
4440 numKeys = 100
4441 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004442 node = main.activeNodes[0]
4443 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue, inMemory=True )
Jon Hall2a5002c2015-08-21 16:49:11 -07004444 if len( putResponses ) == 100:
4445 for i in putResponses:
4446 if putResponses[ i ][ 'value' ] != tMapValue:
4447 putResult = False
4448 else:
4449 putResult = False
4450 if not putResult:
4451 main.log.debug( "Put response values: " + str( putResponses ) )
4452 utilities.assert_equals( expect=True,
4453 actual=putResult,
4454 onpass="In-Memory Transactional Map put successful",
4455 onfail="In-Memory Transactional Map put values are incorrect" )
4456
4457 main.step( "In-Memory Transactional maps get" )
4458 getCheck = True
4459 for n in range( 1, numKeys + 1 ):
4460 getResponses = []
4461 threads = []
4462 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004463 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004464 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4465 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004466 args=[ "Key" + str( n ) ],
Jon Hall2a5002c2015-08-21 16:49:11 -07004467 kwargs={ "inMemory": True } )
4468 threads.append( t )
4469 t.start()
4470 for t in threads:
4471 t.join()
4472 getResponses.append( t.result )
4473 for node in getResponses:
4474 if node != tMapValue:
4475 valueCheck = False
4476 if not valueCheck:
4477 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4478 main.log.warn( getResponses )
4479 getCheck = getCheck and valueCheck
4480 utilities.assert_equals( expect=True,
4481 actual=getCheck,
4482 onpass="In-Memory Transactional Map get values were correct",
4483 onfail="In-Memory Transactional Map values incorrect" )