blob: 396e08a0b40b0321250e4633aafc99ec0f0e9cdf [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 Hall5cf14d52015-07-16 12:15:19 -07002197 for host in hosts[ controller ]:
2198 if host is None or host.get( 'ipAddresses', [] ) == []:
2199 main.log.error(
Jon Hallf3d16e72015-12-16 17:45:08 -08002200 "Error with host ipAddresses on controller" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002201 controllerStr + ": " + str( host ) )
2202 ipResult = main.FALSE
2203 ports = []
2204 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002205 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002206 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002207 name="ports-" + str( i ),
2208 args=[ ] )
2209 threads.append( t )
2210 t.start()
2211
2212 for t in threads:
2213 t.join()
2214 ports.append( t.result )
2215 links = []
2216 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002217 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002218 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002219 name="links-" + str( i ),
2220 args=[ ] )
2221 threads.append( t )
2222 t.start()
2223
2224 for t in threads:
2225 t.join()
2226 links.append( t.result )
2227 clusters = []
2228 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002229 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002230 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002231 name="clusters-" + str( i ),
2232 args=[ ] )
2233 threads.append( t )
2234 t.start()
2235
2236 for t in threads:
2237 t.join()
2238 clusters.append( t.result )
2239
2240 elapsed = time.time() - startTime
2241 cliTime = time.time() - cliStart
2242 print "Elapsed time: " + str( elapsed )
2243 print "CLI time: " + str( cliTime )
2244
2245 mnSwitches = main.Mininet1.getSwitches()
2246 mnLinks = main.Mininet1.getLinks()
2247 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002248 for controller in range( len( main.activeNodes ) ):
2249 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 if devices[ controller ] and ports[ controller ] and\
2251 "Error" not in devices[ controller ] and\
2252 "Error" not in ports[ controller ]:
2253
2254 currentDevicesResult = main.Mininet1.compareSwitches(
2255 mnSwitches,
2256 json.loads( devices[ controller ] ),
2257 json.loads( ports[ controller ] ) )
2258 else:
2259 currentDevicesResult = main.FALSE
2260 utilities.assert_equals( expect=main.TRUE,
2261 actual=currentDevicesResult,
2262 onpass="ONOS" + controllerStr +
2263 " Switches view is correct",
2264 onfail="ONOS" + controllerStr +
2265 " Switches view is incorrect" )
2266
2267 if links[ controller ] and "Error" not in links[ controller ]:
2268 currentLinksResult = main.Mininet1.compareLinks(
2269 mnSwitches, mnLinks,
2270 json.loads( links[ controller ] ) )
2271 else:
2272 currentLinksResult = main.FALSE
2273 utilities.assert_equals( expect=main.TRUE,
2274 actual=currentLinksResult,
2275 onpass="ONOS" + controllerStr +
2276 " links view is correct",
2277 onfail="ONOS" + controllerStr +
2278 " links view is incorrect" )
2279
2280 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2281 currentHostsResult = main.Mininet1.compareHosts(
2282 mnHosts,
2283 hosts[ controller ] )
2284 else:
2285 currentHostsResult = main.FALSE
2286 utilities.assert_equals( expect=main.TRUE,
2287 actual=currentHostsResult,
2288 onpass="ONOS" + controllerStr +
2289 " hosts exist in Mininet",
2290 onfail="ONOS" + controllerStr +
2291 " hosts don't match Mininet" )
2292 # CHECKING HOST ATTACHMENT POINTS
2293 hostAttachment = True
2294 zeroHosts = False
2295 # FIXME: topo-HA/obelisk specific mappings:
2296 # key is mac and value is dpid
2297 mappings = {}
2298 for i in range( 1, 29 ): # hosts 1 through 28
2299 # set up correct variables:
2300 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2301 if i == 1:
2302 deviceId = "1000".zfill(16)
2303 elif i == 2:
2304 deviceId = "2000".zfill(16)
2305 elif i == 3:
2306 deviceId = "3000".zfill(16)
2307 elif i == 4:
2308 deviceId = "3004".zfill(16)
2309 elif i == 5:
2310 deviceId = "5000".zfill(16)
2311 elif i == 6:
2312 deviceId = "6000".zfill(16)
2313 elif i == 7:
2314 deviceId = "6007".zfill(16)
2315 elif i >= 8 and i <= 17:
2316 dpid = '3' + str( i ).zfill( 3 )
2317 deviceId = dpid.zfill(16)
2318 elif i >= 18 and i <= 27:
2319 dpid = '6' + str( i ).zfill( 3 )
2320 deviceId = dpid.zfill(16)
2321 elif i == 28:
2322 deviceId = "2800".zfill(16)
2323 mappings[ macId ] = deviceId
2324 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2325 if hosts[ controller ] == []:
2326 main.log.warn( "There are no hosts discovered" )
2327 zeroHosts = True
2328 else:
2329 for host in hosts[ controller ]:
2330 mac = None
2331 location = None
2332 device = None
2333 port = None
2334 try:
2335 mac = host.get( 'mac' )
2336 assert mac, "mac field could not be found for this host object"
2337
2338 location = host.get( 'location' )
2339 assert location, "location field could not be found for this host object"
2340
2341 # Trim the protocol identifier off deviceId
2342 device = str( location.get( 'elementId' ) ).split(':')[1]
2343 assert device, "elementId field could not be found for this host location object"
2344
2345 port = location.get( 'port' )
2346 assert port, "port field could not be found for this host location object"
2347
2348 # Now check if this matches where they should be
2349 if mac and device and port:
2350 if str( port ) != "1":
2351 main.log.error( "The attachment port is incorrect for " +
2352 "host " + str( mac ) +
2353 ". Expected: 1 Actual: " + str( port) )
2354 hostAttachment = False
2355 if device != mappings[ str( mac ) ]:
2356 main.log.error( "The attachment device is incorrect for " +
2357 "host " + str( mac ) +
2358 ". Expected: " + mappings[ str( mac ) ] +
2359 " Actual: " + device )
2360 hostAttachment = False
2361 else:
2362 hostAttachment = False
2363 except AssertionError:
2364 main.log.exception( "Json object not as expected" )
2365 main.log.error( repr( host ) )
2366 hostAttachment = False
2367 else:
2368 main.log.error( "No hosts json output or \"Error\"" +
2369 " in output. hosts = " +
2370 repr( hosts[ controller ] ) )
2371 if zeroHosts is False:
2372 hostAttachment = True
2373
2374 # END CHECKING HOST ATTACHMENT POINTS
2375 devicesResults = devicesResults and currentDevicesResult
2376 linksResults = linksResults and currentLinksResult
2377 hostsResults = hostsResults and currentHostsResult
2378 hostAttachmentResults = hostAttachmentResults and\
2379 hostAttachment
Jon Halle9b1fa32015-12-08 15:32:21 -08002380 topoResult = devicesResults and linksResults and\
2381 hostsResults and hostAttachmentResults
2382 utilities.assert_equals( expect=True,
2383 actual=topoResult,
2384 onpass="ONOS topology matches Mininet",
2385 onfail="ONOS topology don't match Mininet" )
2386 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002387
2388 # Compare json objects for hosts and dataplane clusters
2389
2390 # hosts
2391 main.step( "Hosts view is consistent across all ONOS nodes" )
2392 consistentHostsResult = main.TRUE
2393 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002394 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08002395 if hosts[ controller ] or "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002396 if hosts[ controller ] == hosts[ 0 ]:
2397 continue
2398 else: # hosts not consistent
2399 main.log.error( "hosts from ONOS" + controllerStr +
2400 " is inconsistent with ONOS1" )
2401 main.log.warn( repr( hosts[ controller ] ) )
2402 consistentHostsResult = main.FALSE
2403
2404 else:
2405 main.log.error( "Error in getting ONOS hosts from ONOS" +
2406 controllerStr )
2407 consistentHostsResult = main.FALSE
2408 main.log.warn( "ONOS" + controllerStr +
2409 " hosts response: " +
2410 repr( hosts[ controller ] ) )
2411 utilities.assert_equals(
2412 expect=main.TRUE,
2413 actual=consistentHostsResult,
2414 onpass="Hosts view is consistent across all ONOS nodes",
2415 onfail="ONOS nodes have different views of hosts" )
2416
2417 main.step( "Hosts information is correct" )
2418 hostsResults = hostsResults and ipResult
2419 utilities.assert_equals(
2420 expect=main.TRUE,
2421 actual=hostsResults,
2422 onpass="Host information is correct",
2423 onfail="Host information is incorrect" )
2424
2425 main.step( "Host attachment points to the network" )
2426 utilities.assert_equals(
2427 expect=True,
2428 actual=hostAttachmentResults,
2429 onpass="Hosts are correctly attached to the network",
2430 onfail="ONOS did not correctly attach hosts to the network" )
2431
2432 # Strongly connected clusters of devices
2433 main.step( "Clusters view is consistent across all ONOS nodes" )
2434 consistentClustersResult = main.TRUE
2435 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002436 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002437 if "Error" not in clusters[ controller ]:
2438 if clusters[ controller ] == clusters[ 0 ]:
2439 continue
2440 else: # clusters not consistent
2441 main.log.error( "clusters from ONOS" +
2442 controllerStr +
2443 " is inconsistent with ONOS1" )
2444 consistentClustersResult = main.FALSE
2445
2446 else:
2447 main.log.error( "Error in getting dataplane clusters " +
2448 "from ONOS" + controllerStr )
2449 consistentClustersResult = main.FALSE
2450 main.log.warn( "ONOS" + controllerStr +
2451 " clusters response: " +
2452 repr( clusters[ controller ] ) )
2453 utilities.assert_equals(
2454 expect=main.TRUE,
2455 actual=consistentClustersResult,
2456 onpass="Clusters view is consistent across all ONOS nodes",
2457 onfail="ONOS nodes have different views of clusters" )
2458
2459 main.step( "There is only one SCC" )
2460 # there should always only be one cluster
2461 try:
2462 numClusters = len( json.loads( clusters[ 0 ] ) )
2463 except ( ValueError, TypeError ):
2464 main.log.exception( "Error parsing clusters[0]: " +
2465 repr( clusters[0] ) )
2466 clusterResults = main.FALSE
2467 if numClusters == 1:
2468 clusterResults = main.TRUE
2469 utilities.assert_equals(
2470 expect=1,
2471 actual=numClusters,
2472 onpass="ONOS shows 1 SCC",
2473 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2474
2475 topoResult = ( devicesResults and linksResults
2476 and hostsResults and consistentHostsResult
2477 and consistentClustersResult and clusterResults
2478 and ipResult and hostAttachmentResults )
2479
2480 topoResult = topoResult and int( count <= 2 )
2481 note = "note it takes about " + str( int( cliTime ) ) + \
2482 " seconds for the test to make all the cli calls to fetch " +\
2483 "the topology from each ONOS instance"
2484 main.log.info(
2485 "Very crass estimate for topology discovery/convergence( " +
2486 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2487 str( count ) + " tries" )
2488
2489 main.step( "Device information is correct" )
2490 utilities.assert_equals(
2491 expect=main.TRUE,
2492 actual=devicesResults,
2493 onpass="Device information is correct",
2494 onfail="Device information is incorrect" )
2495
2496 main.step( "Links are correct" )
2497 utilities.assert_equals(
2498 expect=main.TRUE,
2499 actual=linksResults,
2500 onpass="Link are correct",
2501 onfail="Links are incorrect" )
2502
2503 # FIXME: move this to an ONOS state case
2504 main.step( "Checking ONOS nodes" )
2505 nodesOutput = []
2506 nodeResults = main.TRUE
2507 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002508 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002509 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002510 name="nodes-" + str( i ),
2511 args=[ ] )
2512 threads.append( t )
2513 t.start()
2514
2515 for t in threads:
2516 t.join()
2517 nodesOutput.append( t.result )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002518 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002519 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002520 for i in nodesOutput:
2521 try:
2522 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002523 activeIps = []
2524 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002525 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002526 if node['state'] == 'ACTIVE':
2527 activeIps.append( node['ip'] )
2528 activeIps.sort()
2529 if ips == activeIps:
2530 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002531 except ( ValueError, TypeError ):
2532 main.log.error( "Error parsing nodes output" )
2533 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002534 currentResult = main.FALSE
2535 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002536 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2537 onpass="Nodes check successful",
2538 onfail="Nodes check NOT successful" )
2539
2540 def CASE9( self, main ):
2541 """
2542 Link s3-s28 down
2543 """
2544 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002545 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002546 assert main, "main not defined"
2547 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002548 assert main.CLIs, "main.CLIs not defined"
2549 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002550 # NOTE: You should probably run a topology check after this
2551
2552 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2553
2554 description = "Turn off a link to ensure that Link Discovery " +\
2555 "is working properly"
2556 main.case( description )
2557
2558 main.step( "Kill Link between s3 and s28" )
2559 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2560 main.log.info( "Waiting " + str( linkSleep ) +
2561 " seconds for link down to be discovered" )
2562 time.sleep( linkSleep )
2563 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2564 onpass="Link down successful",
2565 onfail="Failed to bring link down" )
2566 # TODO do some sort of check here
2567
2568 def CASE10( self, main ):
2569 """
2570 Link s3-s28 up
2571 """
2572 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002573 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002574 assert main, "main not defined"
2575 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002576 assert main.CLIs, "main.CLIs not defined"
2577 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002578 # NOTE: You should probably run a topology check after this
2579
2580 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2581
2582 description = "Restore a link to ensure that Link Discovery is " + \
2583 "working properly"
2584 main.case( description )
2585
2586 main.step( "Bring link between s3 and s28 back up" )
2587 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2588 main.log.info( "Waiting " + str( linkSleep ) +
2589 " seconds for link up to be discovered" )
2590 time.sleep( linkSleep )
2591 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2592 onpass="Link up successful",
2593 onfail="Failed to bring link up" )
2594 # TODO do some sort of check here
2595
2596 def CASE11( self, main ):
2597 """
2598 Switch Down
2599 """
2600 # NOTE: You should probably run a topology check after this
2601 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002602 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002603 assert main, "main not defined"
2604 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002605 assert main.CLIs, "main.CLIs not defined"
2606 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002607
2608 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2609
2610 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002611 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002612 main.case( description )
2613 switch = main.params[ 'kill' ][ 'switch' ]
2614 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2615
2616 # TODO: Make this switch parameterizable
2617 main.step( "Kill " + switch )
2618 main.log.info( "Deleting " + switch )
2619 main.Mininet1.delSwitch( switch )
2620 main.log.info( "Waiting " + str( switchSleep ) +
2621 " seconds for switch down to be discovered" )
2622 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002623 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002624 # Peek at the deleted switch
2625 main.log.warn( str( device ) )
2626 result = main.FALSE
2627 if device and device[ 'available' ] is False:
2628 result = main.TRUE
2629 utilities.assert_equals( expect=main.TRUE, actual=result,
2630 onpass="Kill switch successful",
2631 onfail="Failed to kill switch?" )
2632
2633 def CASE12( self, main ):
2634 """
2635 Switch Up
2636 """
2637 # NOTE: You should probably run a topology check after this
2638 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002639 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002640 assert main, "main not defined"
2641 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002642 assert main.CLIs, "main.CLIs not defined"
2643 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002644 assert ONOS1Port, "ONOS1Port not defined"
2645 assert ONOS2Port, "ONOS2Port not defined"
2646 assert ONOS3Port, "ONOS3Port not defined"
2647 assert ONOS4Port, "ONOS4Port not defined"
2648 assert ONOS5Port, "ONOS5Port not defined"
2649 assert ONOS6Port, "ONOS6Port not defined"
2650 assert ONOS7Port, "ONOS7Port not defined"
2651
2652 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2653 switch = main.params[ 'kill' ][ 'switch' ]
2654 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2655 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002656 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002657 description = "Adding a switch to ensure it is discovered correctly"
2658 main.case( description )
2659
2660 main.step( "Add back " + switch )
2661 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2662 for peer in links:
2663 main.Mininet1.addLink( switch, peer )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002664 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002665 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2666 main.log.info( "Waiting " + str( switchSleep ) +
2667 " seconds for switch up to be discovered" )
2668 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002669 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002670 # Peek at the deleted switch
2671 main.log.warn( str( device ) )
2672 result = main.FALSE
2673 if device and device[ 'available' ]:
2674 result = main.TRUE
2675 utilities.assert_equals( expect=main.TRUE, actual=result,
2676 onpass="add switch successful",
2677 onfail="Failed to add switch?" )
2678
2679 def CASE13( self, main ):
2680 """
2681 Clean up
2682 """
2683 import os
2684 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002685 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002686 assert main, "main not defined"
2687 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002688 assert main.CLIs, "main.CLIs not defined"
2689 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002690
2691 # printing colors to terminal
2692 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2693 'blue': '\033[94m', 'green': '\033[92m',
2694 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2695 main.case( "Test Cleanup" )
2696 main.step( "Killing tcpdumps" )
2697 main.Mininet2.stopTcpdump()
2698
2699 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002700 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002701 main.step( "Copying MN pcap and ONOS log files to test station" )
2702 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2703 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002704 # NOTE: MN Pcap file is being saved to logdir.
2705 # We scp this file as MN and TestON aren't necessarily the same vm
2706
2707 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002708 # TODO: Load these from params
2709 # NOTE: must end in /
2710 logFolder = "/opt/onos/log/"
2711 logFiles = [ "karaf.log", "karaf.log.1" ]
2712 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002713 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002714 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002715 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002716 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2717 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002718 # std*.log's
2719 # NOTE: must end in /
2720 logFolder = "/opt/onos/var/"
2721 logFiles = [ "stderr.log", "stdout.log" ]
2722 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002723 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002724 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002725 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002726 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2727 logFolder + f, dstName )
2728 else:
2729 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002730
2731 main.step( "Stopping Mininet" )
2732 mnResult = main.Mininet1.stopNet()
2733 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2734 onpass="Mininet stopped",
2735 onfail="MN cleanup NOT successful" )
2736
2737 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002738 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002739 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2740 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002741
2742 try:
2743 timerLog = open( main.logdir + "/Timers.csv", 'w')
2744 # Overwrite with empty line and close
2745 labels = "Gossip Intents, Restart"
2746 data = str( gossipTime ) + ", " + str( main.restartTime )
2747 timerLog.write( labels + "\n" + data )
2748 timerLog.close()
2749 except NameError, e:
2750 main.log.exception(e)
2751
2752 def CASE14( self, main ):
2753 """
2754 start election app on all onos nodes
2755 """
Jon Halle1a3b752015-07-22 13:02:46 -07002756 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002757 assert main, "main not defined"
2758 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002759 assert main.CLIs, "main.CLIs not defined"
2760 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002761
2762 main.case("Start Leadership Election app")
2763 main.step( "Install leadership election app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002764 onosCli = main.CLIs[ main.activeNodes[0] ]
2765 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002766 utilities.assert_equals(
2767 expect=main.TRUE,
2768 actual=appResult,
2769 onpass="Election app installed",
2770 onfail="Something went wrong with installing Leadership election" )
2771
2772 main.step( "Run for election on each node" )
2773 leaderResult = main.TRUE
2774 leaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002775 for i in main.activeNodes:
2776 main.CLIs[i].electionTestRun()
2777 for i in main.activeNodes:
2778 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002779 leader = cli.electionTestLeader()
2780 if leader is None or leader == main.FALSE:
2781 main.log.error( cli.name + ": Leader for the election app " +
2782 "should be an ONOS node, instead got '" +
2783 str( leader ) + "'" )
2784 leaderResult = main.FALSE
2785 leaders.append( leader )
2786 utilities.assert_equals(
2787 expect=main.TRUE,
2788 actual=leaderResult,
2789 onpass="Successfully ran for leadership",
2790 onfail="Failed to run for leadership" )
2791
2792 main.step( "Check that each node shows the same leader" )
2793 sameLeader = main.TRUE
2794 if len( set( leaders ) ) != 1:
2795 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002796 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002797 str( leaders ) )
2798 utilities.assert_equals(
2799 expect=main.TRUE,
2800 actual=sameLeader,
2801 onpass="Leadership is consistent for the election topic",
2802 onfail="Nodes have different leaders" )
2803
2804 def CASE15( self, main ):
2805 """
2806 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002807 15.1 Run election on each node
2808 15.2 Check that each node has the same leaders and candidates
2809 15.3 Find current leader and withdraw
2810 15.4 Check that a new node was elected leader
2811 15.5 Check that that new leader was the candidate of old leader
2812 15.6 Run for election on old leader
2813 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2814 15.8 Make sure that the old leader was added to the candidate list
2815
2816 old and new variable prefixes refer to data from before vs after
2817 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002818 """
2819 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002820 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002821 assert main, "main not defined"
2822 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002823 assert main.CLIs, "main.CLIs not defined"
2824 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002825
Jon Hall5cf14d52015-07-16 12:15:19 -07002826 description = "Check that Leadership Election is still functional"
2827 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002828 # NOTE: Need to re-run since being a canidate is not persistant
2829 # TODO: add check for "Command not found:" in the driver, this
2830 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002831
acsmars71adceb2015-08-31 15:09:26 -07002832 oldLeaders = [] # leaders by node before withdrawl from candidates
2833 newLeaders = [] # leaders by node after withdrawl from candidates
2834 oldAllCandidates = [] # list of lists of each nodes' candidates before
2835 newAllCandidates = [] # list of lists of each nodes' candidates after
2836 oldCandidates = [] # list of candidates from node 0 before withdrawl
2837 newCandidates = [] # list of candidates from node 0 after withdrawl
2838 oldLeader = '' # the old leader from oldLeaders, None if not same
2839 newLeader = '' # the new leaders fron newLoeaders, None if not same
2840 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2841 expectNoLeader = False # True when there is only one leader
2842 if main.numCtrls == 1:
2843 expectNoLeader = True
2844
2845 main.step( "Run for election on each node" )
2846 electionResult = main.TRUE
2847
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002848 for i in main.activeNodes: # run test election on each node
2849 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002850 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002851 utilities.assert_equals(
2852 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002853 actual=electionResult,
2854 onpass="All nodes successfully ran for leadership",
2855 onfail="At least one node failed to run for leadership" )
2856
acsmars3a72bde2015-09-02 14:16:22 -07002857 if electionResult == main.FALSE:
2858 main.log.error(
2859 "Skipping Test Case because Election Test App isn't loaded" )
2860 main.skipCase()
2861
acsmars71adceb2015-08-31 15:09:26 -07002862 main.step( "Check that each node shows the same leader and candidates" )
2863 sameResult = main.TRUE
2864 failMessage = "Nodes have different leaders"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002865 for i in main.activeNodes:
2866 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07002867 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2868 oldAllCandidates.append( node )
2869 oldLeaders.append( node[ 0 ] )
2870 oldCandidates = oldAllCandidates[ 0 ]
2871
2872 # Check that each node has the same leader. Defines oldLeader
2873 if len( set( oldLeaders ) ) != 1:
2874 sameResult = main.FALSE
2875 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2876 oldLeader = None
2877 else:
2878 oldLeader = oldLeaders[ 0 ]
2879
2880 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002881 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07002882 for candidates in oldAllCandidates:
2883 if set( candidates ) != set( oldCandidates ):
2884 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002885 candidateDiscrepancy = True
2886
2887 if candidateDiscrepancy:
2888 failMessage += " and candidates"
2889
acsmars71adceb2015-08-31 15:09:26 -07002890 utilities.assert_equals(
2891 expect=main.TRUE,
2892 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002893 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002894 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002895
2896 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002897 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002898 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002899 if oldLeader is None:
2900 main.log.error( "Leadership isn't consistent." )
2901 withdrawResult = main.FALSE
2902 # Get the CLI of the oldLeader
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002903 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002904 if oldLeader == main.nodes[ i ].ip_address:
2905 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002906 break
2907 else: # FOR/ELSE statement
2908 main.log.error( "Leader election, could not find current leader" )
2909 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002910 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002911 utilities.assert_equals(
2912 expect=main.TRUE,
2913 actual=withdrawResult,
2914 onpass="Node was withdrawn from election",
2915 onfail="Node was not withdrawn from election" )
2916
acsmars71adceb2015-08-31 15:09:26 -07002917 main.step( "Check that a new node was elected leader" )
2918
Jon Hall5cf14d52015-07-16 12:15:19 -07002919 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002920 newLeaderResult = main.TRUE
2921 failMessage = "Nodes have different leaders"
2922
2923 # Get new leaders and candidates
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002924 for i in main.activeNodes:
2925 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07002926 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2927 # elections might no have finished yet
2928 if node[ 0 ] == 'none' and not expectNoLeader:
2929 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2930 "sure elections are complete." )
2931 time.sleep(5)
2932 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2933 # election still isn't done or there is a problem
2934 if node[ 0 ] == 'none':
2935 main.log.error( "No leader was elected on at least 1 node" )
2936 newLeaderResult = main.FALSE
2937 newAllCandidates.append( node )
2938 newLeaders.append( node[ 0 ] )
2939 newCandidates = newAllCandidates[ 0 ]
2940
2941 # Check that each node has the same leader. Defines newLeader
2942 if len( set( newLeaders ) ) != 1:
2943 newLeaderResult = main.FALSE
2944 main.log.error( "Nodes have different leaders: " +
2945 str( newLeaders ) )
2946 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002947 else:
acsmars71adceb2015-08-31 15:09:26 -07002948 newLeader = newLeaders[ 0 ]
2949
2950 # Check that each node's candidate list is the same
2951 for candidates in newAllCandidates:
2952 if set( candidates ) != set( newCandidates ):
2953 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002954 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002955
2956 # Check that the new leader is not the older leader, which was withdrawn
2957 if newLeader == oldLeader:
2958 newLeaderResult = main.FALSE
2959 main.log.error( "All nodes still see old leader: " + oldLeader +
2960 " as the current leader" )
2961
Jon Hall5cf14d52015-07-16 12:15:19 -07002962 utilities.assert_equals(
2963 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002964 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002965 onpass="Leadership election passed",
2966 onfail="Something went wrong with Leadership election" )
2967
acsmars71adceb2015-08-31 15:09:26 -07002968 main.step( "Check that that new leader was the candidate of old leader")
2969 # candidates[ 2 ] should be come the top candidate after withdrawl
2970 correctCandidateResult = main.TRUE
2971 if expectNoLeader:
2972 if newLeader == 'none':
2973 main.log.info( "No leader expected. None found. Pass" )
2974 correctCandidateResult = main.TRUE
2975 else:
2976 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2977 correctCandidateResult = main.FALSE
2978 elif newLeader != oldCandidates[ 2 ]:
2979 correctCandidateResult = main.FALSE
2980 main.log.error( "Candidate " + newLeader + " was elected. " +
2981 oldCandidates[ 2 ] + " should have had priority." )
2982
2983 utilities.assert_equals(
2984 expect=main.TRUE,
2985 actual=correctCandidateResult,
2986 onpass="Correct Candidate Elected",
2987 onfail="Incorrect Candidate Elected" )
2988
Jon Hall5cf14d52015-07-16 12:15:19 -07002989 main.step( "Run for election on old leader( just so everyone " +
2990 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002991 if oldLeaderCLI is not None:
2992 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002993 else:
acsmars71adceb2015-08-31 15:09:26 -07002994 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002995 runResult = main.FALSE
2996 utilities.assert_equals(
2997 expect=main.TRUE,
2998 actual=runResult,
2999 onpass="App re-ran for election",
3000 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07003001 main.step(
3002 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003003 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07003004 positionResult = main.TRUE
3005 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3006
3007 # Reset and reuse the new candidate and leaders lists
3008 newAllCandidates = []
3009 newCandidates = []
3010 newLeaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003011 for i in main.activeNodes:
3012 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07003013 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3014 if oldLeader not in node: # election might no have finished yet
3015 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3016 "be sure elections are complete" )
3017 time.sleep(5)
3018 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3019 if oldLeader not in node: # election still isn't done, errors
3020 main.log.error(
3021 "Old leader was not elected on at least one node" )
3022 positionResult = main.FALSE
3023 newAllCandidates.append( node )
3024 newLeaders.append( node[ 0 ] )
3025 newCandidates = newAllCandidates[ 0 ]
3026
3027 # Check that each node has the same leader. Defines newLeader
3028 if len( set( newLeaders ) ) != 1:
3029 positionResult = main.FALSE
3030 main.log.error( "Nodes have different leaders: " +
3031 str( newLeaders ) )
3032 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003033 else:
acsmars71adceb2015-08-31 15:09:26 -07003034 newLeader = newLeaders[ 0 ]
3035
3036 # Check that each node's candidate list is the same
3037 for candidates in newAllCandidates:
3038 if set( candidates ) != set( newCandidates ):
3039 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003040 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003041
3042 # Check that the re-elected node is last on the candidate List
3043 if oldLeader != newCandidates[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003044 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
acsmars71adceb2015-08-31 15:09:26 -07003045 str( newCandidates ) )
3046 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003047
3048 utilities.assert_equals(
3049 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07003050 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003051 onpass="Old leader successfully re-ran for election",
3052 onfail="Something went wrong with Leadership election after " +
3053 "the old leader re-ran for election" )
3054
3055 def CASE16( self, main ):
3056 """
3057 Install Distributed Primitives app
3058 """
3059 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003060 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003061 assert main, "main not defined"
3062 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003063 assert main.CLIs, "main.CLIs not defined"
3064 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003065
3066 # Variables for the distributed primitives tests
3067 global pCounterName
3068 global iCounterName
3069 global pCounterValue
3070 global iCounterValue
3071 global onosSet
3072 global onosSetName
3073 pCounterName = "TestON-Partitions"
3074 iCounterName = "TestON-inMemory"
3075 pCounterValue = 0
3076 iCounterValue = 0
3077 onosSet = set([])
3078 onosSetName = "TestON-set"
3079
3080 description = "Install Primitives app"
3081 main.case( description )
3082 main.step( "Install Primitives app" )
3083 appName = "org.onosproject.distributedprimitives"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003084 node = main.activeNodes[0]
3085 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003086 utilities.assert_equals( expect=main.TRUE,
3087 actual=appResults,
3088 onpass="Primitives app activated",
3089 onfail="Primitives app not activated" )
3090 time.sleep( 5 ) # To allow all nodes to activate
3091
3092 def CASE17( self, main ):
3093 """
3094 Check for basic functionality with distributed primitives
3095 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003096 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003097 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 assert main, "main not defined"
3099 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003100 assert main.CLIs, "main.CLIs not defined"
3101 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 assert pCounterName, "pCounterName not defined"
3103 assert iCounterName, "iCounterName not defined"
3104 assert onosSetName, "onosSetName not defined"
3105 # NOTE: assert fails if value is 0/None/Empty/False
3106 try:
3107 pCounterValue
3108 except NameError:
3109 main.log.error( "pCounterValue not defined, setting to 0" )
3110 pCounterValue = 0
3111 try:
3112 iCounterValue
3113 except NameError:
3114 main.log.error( "iCounterValue not defined, setting to 0" )
3115 iCounterValue = 0
3116 try:
3117 onosSet
3118 except NameError:
3119 main.log.error( "onosSet not defined, setting to empty Set" )
3120 onosSet = set([])
3121 # Variables for the distributed primitives tests. These are local only
3122 addValue = "a"
3123 addAllValue = "a b c d e f"
3124 retainValue = "c d e f"
3125
3126 description = "Check for basic functionality with distributed " +\
3127 "primitives"
3128 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003129 main.caseExplanation = "Test the methods of the distributed " +\
3130 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003131 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003132 # Partitioned counters
3133 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003134 pCounters = []
3135 threads = []
3136 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003137 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003138 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3139 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003140 args=[ pCounterName ] )
3141 pCounterValue += 1
3142 addedPValues.append( pCounterValue )
3143 threads.append( t )
3144 t.start()
3145
3146 for t in threads:
3147 t.join()
3148 pCounters.append( t.result )
3149 # Check that counter incremented numController times
3150 pCounterResults = True
3151 for i in addedPValues:
3152 tmpResult = i in pCounters
3153 pCounterResults = pCounterResults and tmpResult
3154 if not tmpResult:
3155 main.log.error( str( i ) + " is not in partitioned "
3156 "counter incremented results" )
3157 utilities.assert_equals( expect=True,
3158 actual=pCounterResults,
3159 onpass="Default counter incremented",
3160 onfail="Error incrementing default" +
3161 " counter" )
3162
Jon Halle1a3b752015-07-22 13:02:46 -07003163 main.step( "Get then Increment a default counter on each node" )
3164 pCounters = []
3165 threads = []
3166 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003167 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003168 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3169 name="counterGetAndAdd-" + str( i ),
3170 args=[ pCounterName ] )
3171 addedPValues.append( pCounterValue )
3172 pCounterValue += 1
3173 threads.append( t )
3174 t.start()
3175
3176 for t in threads:
3177 t.join()
3178 pCounters.append( t.result )
3179 # Check that counter incremented numController times
3180 pCounterResults = True
3181 for i in addedPValues:
3182 tmpResult = i in pCounters
3183 pCounterResults = pCounterResults and tmpResult
3184 if not tmpResult:
3185 main.log.error( str( i ) + " is not in partitioned "
3186 "counter incremented results" )
3187 utilities.assert_equals( expect=True,
3188 actual=pCounterResults,
3189 onpass="Default counter incremented",
3190 onfail="Error incrementing default" +
3191 " counter" )
3192
3193 main.step( "Counters we added have the correct values" )
3194 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3195 utilities.assert_equals( expect=main.TRUE,
3196 actual=incrementCheck,
3197 onpass="Added counters are correct",
3198 onfail="Added counters are incorrect" )
3199
3200 main.step( "Add -8 to then get a default counter on each node" )
3201 pCounters = []
3202 threads = []
3203 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003204 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003205 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3206 name="counterIncrement-" + str( i ),
3207 args=[ pCounterName ],
3208 kwargs={ "delta": -8 } )
3209 pCounterValue += -8
3210 addedPValues.append( pCounterValue )
3211 threads.append( t )
3212 t.start()
3213
3214 for t in threads:
3215 t.join()
3216 pCounters.append( t.result )
3217 # Check that counter incremented numController times
3218 pCounterResults = True
3219 for i in addedPValues:
3220 tmpResult = i in pCounters
3221 pCounterResults = pCounterResults and tmpResult
3222 if not tmpResult:
3223 main.log.error( str( i ) + " is not in partitioned "
3224 "counter incremented results" )
3225 utilities.assert_equals( expect=True,
3226 actual=pCounterResults,
3227 onpass="Default counter incremented",
3228 onfail="Error incrementing default" +
3229 " counter" )
3230
3231 main.step( "Add 5 to then get a default counter on each node" )
3232 pCounters = []
3233 threads = []
3234 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003235 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003236 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3237 name="counterIncrement-" + str( i ),
3238 args=[ pCounterName ],
3239 kwargs={ "delta": 5 } )
3240 pCounterValue += 5
3241 addedPValues.append( pCounterValue )
3242 threads.append( t )
3243 t.start()
3244
3245 for t in threads:
3246 t.join()
3247 pCounters.append( t.result )
3248 # Check that counter incremented numController times
3249 pCounterResults = True
3250 for i in addedPValues:
3251 tmpResult = i in pCounters
3252 pCounterResults = pCounterResults and tmpResult
3253 if not tmpResult:
3254 main.log.error( str( i ) + " is not in partitioned "
3255 "counter incremented results" )
3256 utilities.assert_equals( expect=True,
3257 actual=pCounterResults,
3258 onpass="Default counter incremented",
3259 onfail="Error incrementing default" +
3260 " counter" )
3261
3262 main.step( "Get then add 5 to a default counter on each node" )
3263 pCounters = []
3264 threads = []
3265 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003266 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003267 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3268 name="counterIncrement-" + str( i ),
3269 args=[ pCounterName ],
3270 kwargs={ "delta": 5 } )
3271 addedPValues.append( pCounterValue )
3272 pCounterValue += 5
3273 threads.append( t )
3274 t.start()
3275
3276 for t in threads:
3277 t.join()
3278 pCounters.append( t.result )
3279 # Check that counter incremented numController times
3280 pCounterResults = True
3281 for i in addedPValues:
3282 tmpResult = i in pCounters
3283 pCounterResults = pCounterResults and tmpResult
3284 if not tmpResult:
3285 main.log.error( str( i ) + " is not in partitioned "
3286 "counter incremented results" )
3287 utilities.assert_equals( expect=True,
3288 actual=pCounterResults,
3289 onpass="Default counter incremented",
3290 onfail="Error incrementing default" +
3291 " counter" )
3292
3293 main.step( "Counters we added have the correct values" )
3294 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3295 utilities.assert_equals( expect=main.TRUE,
3296 actual=incrementCheck,
3297 onpass="Added counters are correct",
3298 onfail="Added counters are incorrect" )
3299
3300 # In-Memory counters
3301 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003302 iCounters = []
3303 addedIValues = []
3304 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003305 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003306 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003307 name="icounterIncrement-" + str( i ),
3308 args=[ iCounterName ],
3309 kwargs={ "inMemory": True } )
3310 iCounterValue += 1
3311 addedIValues.append( iCounterValue )
3312 threads.append( t )
3313 t.start()
3314
3315 for t in threads:
3316 t.join()
3317 iCounters.append( t.result )
3318 # Check that counter incremented numController times
3319 iCounterResults = True
3320 for i in addedIValues:
3321 tmpResult = i in iCounters
3322 iCounterResults = iCounterResults and tmpResult
3323 if not tmpResult:
3324 main.log.error( str( i ) + " is not in the in-memory "
3325 "counter incremented results" )
3326 utilities.assert_equals( expect=True,
3327 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003328 onpass="In-memory counter incremented",
3329 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003330 " counter" )
3331
Jon Halle1a3b752015-07-22 13:02:46 -07003332 main.step( "Get then Increment a in-memory counter on each node" )
3333 iCounters = []
3334 threads = []
3335 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003336 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003337 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3338 name="counterGetAndAdd-" + str( i ),
3339 args=[ iCounterName ],
3340 kwargs={ "inMemory": True } )
3341 addedIValues.append( iCounterValue )
3342 iCounterValue += 1
3343 threads.append( t )
3344 t.start()
3345
3346 for t in threads:
3347 t.join()
3348 iCounters.append( t.result )
3349 # Check that counter incremented numController times
3350 iCounterResults = True
3351 for i in addedIValues:
3352 tmpResult = i in iCounters
3353 iCounterResults = iCounterResults and tmpResult
3354 if not tmpResult:
3355 main.log.error( str( i ) + " is not in in-memory "
3356 "counter incremented results" )
3357 utilities.assert_equals( expect=True,
3358 actual=iCounterResults,
3359 onpass="In-memory counter incremented",
3360 onfail="Error incrementing in-memory" +
3361 " counter" )
3362
3363 main.step( "Counters we added have the correct values" )
3364 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3365 utilities.assert_equals( expect=main.TRUE,
3366 actual=incrementCheck,
3367 onpass="Added counters are correct",
3368 onfail="Added counters are incorrect" )
3369
3370 main.step( "Add -8 to then get a in-memory counter on each node" )
3371 iCounters = []
3372 threads = []
3373 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003374 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003375 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3376 name="counterIncrement-" + str( i ),
3377 args=[ iCounterName ],
3378 kwargs={ "delta": -8, "inMemory": True } )
3379 iCounterValue += -8
3380 addedIValues.append( iCounterValue )
3381 threads.append( t )
3382 t.start()
3383
3384 for t in threads:
3385 t.join()
3386 iCounters.append( t.result )
3387 # Check that counter incremented numController times
3388 iCounterResults = True
3389 for i in addedIValues:
3390 tmpResult = i in iCounters
3391 iCounterResults = iCounterResults and tmpResult
3392 if not tmpResult:
3393 main.log.error( str( i ) + " is not in in-memory "
3394 "counter incremented results" )
3395 utilities.assert_equals( expect=True,
3396 actual=pCounterResults,
3397 onpass="In-memory counter incremented",
3398 onfail="Error incrementing in-memory" +
3399 " counter" )
3400
3401 main.step( "Add 5 to then get a in-memory counter on each node" )
3402 iCounters = []
3403 threads = []
3404 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003405 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003406 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3407 name="counterIncrement-" + str( i ),
3408 args=[ iCounterName ],
3409 kwargs={ "delta": 5, "inMemory": True } )
3410 iCounterValue += 5
3411 addedIValues.append( iCounterValue )
3412 threads.append( t )
3413 t.start()
3414
3415 for t in threads:
3416 t.join()
3417 iCounters.append( t.result )
3418 # Check that counter incremented numController times
3419 iCounterResults = True
3420 for i in addedIValues:
3421 tmpResult = i in iCounters
3422 iCounterResults = iCounterResults and tmpResult
3423 if not tmpResult:
3424 main.log.error( str( i ) + " is not in in-memory "
3425 "counter incremented results" )
3426 utilities.assert_equals( expect=True,
3427 actual=pCounterResults,
3428 onpass="In-memory counter incremented",
3429 onfail="Error incrementing in-memory" +
3430 " counter" )
3431
3432 main.step( "Get then add 5 to a in-memory counter on each node" )
3433 iCounters = []
3434 threads = []
3435 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003436 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003437 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3438 name="counterIncrement-" + str( i ),
3439 args=[ iCounterName ],
3440 kwargs={ "delta": 5, "inMemory": True } )
3441 addedIValues.append( iCounterValue )
3442 iCounterValue += 5
3443 threads.append( t )
3444 t.start()
3445
3446 for t in threads:
3447 t.join()
3448 iCounters.append( t.result )
3449 # Check that counter incremented numController times
3450 iCounterResults = True
3451 for i in addedIValues:
3452 tmpResult = i in iCounters
3453 iCounterResults = iCounterResults and tmpResult
3454 if not tmpResult:
3455 main.log.error( str( i ) + " is not in in-memory "
3456 "counter incremented results" )
3457 utilities.assert_equals( expect=True,
3458 actual=iCounterResults,
3459 onpass="In-memory counter incremented",
3460 onfail="Error incrementing in-memory" +
3461 " counter" )
3462
3463 main.step( "Counters we added have the correct values" )
3464 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3465 utilities.assert_equals( expect=main.TRUE,
3466 actual=incrementCheck,
3467 onpass="Added counters are correct",
3468 onfail="Added counters are incorrect" )
3469
Jon Hall5cf14d52015-07-16 12:15:19 -07003470 main.step( "Check counters are consistant across nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07003471 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003472 utilities.assert_equals( expect=main.TRUE,
3473 actual=consistentCounterResults,
3474 onpass="ONOS counters are consistent " +
3475 "across nodes",
3476 onfail="ONOS Counters are inconsistent " +
3477 "across nodes" )
3478
3479 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003480 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3481 incrementCheck = incrementCheck and \
3482 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003483 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003484 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003485 onpass="Added counters are correct",
3486 onfail="Added counters are incorrect" )
3487 # DISTRIBUTED SETS
3488 main.step( "Distributed Set get" )
3489 size = len( onosSet )
3490 getResponses = []
3491 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003492 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003493 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003494 name="setTestGet-" + str( i ),
3495 args=[ onosSetName ] )
3496 threads.append( t )
3497 t.start()
3498 for t in threads:
3499 t.join()
3500 getResponses.append( t.result )
3501
3502 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003503 for i in range( len( main.activeNodes ) ):
3504 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003505 if isinstance( getResponses[ i ], list):
3506 current = set( getResponses[ i ] )
3507 if len( current ) == len( getResponses[ i ] ):
3508 # no repeats
3509 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003510 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003511 " has incorrect view" +
3512 " of set " + onosSetName + ":\n" +
3513 str( getResponses[ i ] ) )
3514 main.log.debug( "Expected: " + str( onosSet ) )
3515 main.log.debug( "Actual: " + str( current ) )
3516 getResults = main.FALSE
3517 else:
3518 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003519 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003520 " has repeat elements in" +
3521 " set " + onosSetName + ":\n" +
3522 str( getResponses[ i ] ) )
3523 getResults = main.FALSE
3524 elif getResponses[ i ] == main.ERROR:
3525 getResults = main.FALSE
3526 utilities.assert_equals( expect=main.TRUE,
3527 actual=getResults,
3528 onpass="Set elements are correct",
3529 onfail="Set elements are incorrect" )
3530
3531 main.step( "Distributed Set size" )
3532 sizeResponses = []
3533 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003534 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003535 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003536 name="setTestSize-" + str( i ),
3537 args=[ onosSetName ] )
3538 threads.append( t )
3539 t.start()
3540 for t in threads:
3541 t.join()
3542 sizeResponses.append( t.result )
3543
3544 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003545 for i in range( len( main.activeNodes ) ):
3546 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003547 if size != sizeResponses[ i ]:
3548 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003549 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003550 " expected a size of " + str( size ) +
3551 " for set " + onosSetName +
3552 " but got " + str( sizeResponses[ i ] ) )
3553 utilities.assert_equals( expect=main.TRUE,
3554 actual=sizeResults,
3555 onpass="Set sizes are correct",
3556 onfail="Set sizes are incorrect" )
3557
3558 main.step( "Distributed Set add()" )
3559 onosSet.add( addValue )
3560 addResponses = []
3561 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003562 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003563 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003564 name="setTestAdd-" + str( i ),
3565 args=[ onosSetName, addValue ] )
3566 threads.append( t )
3567 t.start()
3568 for t in threads:
3569 t.join()
3570 addResponses.append( t.result )
3571
3572 # main.TRUE = successfully changed the set
3573 # main.FALSE = action resulted in no change in set
3574 # main.ERROR - Some error in executing the function
3575 addResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003576 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003577 if addResponses[ i ] == main.TRUE:
3578 # All is well
3579 pass
3580 elif addResponses[ i ] == main.FALSE:
3581 # Already in set, probably fine
3582 pass
3583 elif addResponses[ i ] == main.ERROR:
3584 # Error in execution
3585 addResults = main.FALSE
3586 else:
3587 # unexpected result
3588 addResults = main.FALSE
3589 if addResults != main.TRUE:
3590 main.log.error( "Error executing set add" )
3591
3592 # Check if set is still correct
3593 size = len( onosSet )
3594 getResponses = []
3595 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003596 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003597 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003598 name="setTestGet-" + str( i ),
3599 args=[ onosSetName ] )
3600 threads.append( t )
3601 t.start()
3602 for t in threads:
3603 t.join()
3604 getResponses.append( t.result )
3605 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003606 for i in range( len( main.activeNodes ) ):
3607 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003608 if isinstance( getResponses[ i ], list):
3609 current = set( getResponses[ i ] )
3610 if len( current ) == len( getResponses[ i ] ):
3611 # no repeats
3612 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003613 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003614 " of set " + onosSetName + ":\n" +
3615 str( getResponses[ i ] ) )
3616 main.log.debug( "Expected: " + str( onosSet ) )
3617 main.log.debug( "Actual: " + str( current ) )
3618 getResults = main.FALSE
3619 else:
3620 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003621 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003622 " set " + onosSetName + ":\n" +
3623 str( getResponses[ i ] ) )
3624 getResults = main.FALSE
3625 elif getResponses[ i ] == main.ERROR:
3626 getResults = main.FALSE
3627 sizeResponses = []
3628 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003629 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003630 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003631 name="setTestSize-" + str( i ),
3632 args=[ onosSetName ] )
3633 threads.append( t )
3634 t.start()
3635 for t in threads:
3636 t.join()
3637 sizeResponses.append( t.result )
3638 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003639 for i in range( len( main.activeNodes ) ):
3640 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003641 if size != sizeResponses[ i ]:
3642 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003643 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003644 " expected a size of " + str( size ) +
3645 " for set " + onosSetName +
3646 " but got " + str( sizeResponses[ i ] ) )
3647 addResults = addResults and getResults and sizeResults
3648 utilities.assert_equals( expect=main.TRUE,
3649 actual=addResults,
3650 onpass="Set add correct",
3651 onfail="Set add was incorrect" )
3652
3653 main.step( "Distributed Set addAll()" )
3654 onosSet.update( addAllValue.split() )
3655 addResponses = []
3656 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003657 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003658 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003659 name="setTestAddAll-" + str( i ),
3660 args=[ onosSetName, addAllValue ] )
3661 threads.append( t )
3662 t.start()
3663 for t in threads:
3664 t.join()
3665 addResponses.append( t.result )
3666
3667 # main.TRUE = successfully changed the set
3668 # main.FALSE = action resulted in no change in set
3669 # main.ERROR - Some error in executing the function
3670 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003671 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003672 if addResponses[ i ] == main.TRUE:
3673 # All is well
3674 pass
3675 elif addResponses[ i ] == main.FALSE:
3676 # Already in set, probably fine
3677 pass
3678 elif addResponses[ i ] == main.ERROR:
3679 # Error in execution
3680 addAllResults = main.FALSE
3681 else:
3682 # unexpected result
3683 addAllResults = main.FALSE
3684 if addAllResults != main.TRUE:
3685 main.log.error( "Error executing set addAll" )
3686
3687 # Check if set is still correct
3688 size = len( onosSet )
3689 getResponses = []
3690 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003691 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003692 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003693 name="setTestGet-" + str( i ),
3694 args=[ onosSetName ] )
3695 threads.append( t )
3696 t.start()
3697 for t in threads:
3698 t.join()
3699 getResponses.append( t.result )
3700 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003701 for i in range( len( main.activeNodes ) ):
3702 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003703 if isinstance( getResponses[ i ], list):
3704 current = set( getResponses[ i ] )
3705 if len( current ) == len( getResponses[ i ] ):
3706 # no repeats
3707 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003708 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003709 " has incorrect view" +
3710 " of set " + onosSetName + ":\n" +
3711 str( getResponses[ i ] ) )
3712 main.log.debug( "Expected: " + str( onosSet ) )
3713 main.log.debug( "Actual: " + str( current ) )
3714 getResults = main.FALSE
3715 else:
3716 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003717 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003718 " has repeat elements in" +
3719 " set " + onosSetName + ":\n" +
3720 str( getResponses[ i ] ) )
3721 getResults = main.FALSE
3722 elif getResponses[ i ] == main.ERROR:
3723 getResults = main.FALSE
3724 sizeResponses = []
3725 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003726 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003727 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003728 name="setTestSize-" + str( i ),
3729 args=[ onosSetName ] )
3730 threads.append( t )
3731 t.start()
3732 for t in threads:
3733 t.join()
3734 sizeResponses.append( t.result )
3735 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003736 for i in range( len( main.activeNodes ) ):
3737 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003738 if size != sizeResponses[ i ]:
3739 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003740 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003741 " expected a size of " + str( size ) +
3742 " for set " + onosSetName +
3743 " but got " + str( sizeResponses[ i ] ) )
3744 addAllResults = addAllResults and getResults and sizeResults
3745 utilities.assert_equals( expect=main.TRUE,
3746 actual=addAllResults,
3747 onpass="Set addAll correct",
3748 onfail="Set addAll was incorrect" )
3749
3750 main.step( "Distributed Set contains()" )
3751 containsResponses = []
3752 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003753 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003754 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003755 name="setContains-" + str( i ),
3756 args=[ onosSetName ],
3757 kwargs={ "values": addValue } )
3758 threads.append( t )
3759 t.start()
3760 for t in threads:
3761 t.join()
3762 # NOTE: This is the tuple
3763 containsResponses.append( t.result )
3764
3765 containsResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003766 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003767 if containsResponses[ i ] == main.ERROR:
3768 containsResults = main.FALSE
3769 else:
3770 containsResults = containsResults and\
3771 containsResponses[ i ][ 1 ]
3772 utilities.assert_equals( expect=main.TRUE,
3773 actual=containsResults,
3774 onpass="Set contains is functional",
3775 onfail="Set contains failed" )
3776
3777 main.step( "Distributed Set containsAll()" )
3778 containsAllResponses = []
3779 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003780 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003781 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003782 name="setContainsAll-" + str( i ),
3783 args=[ onosSetName ],
3784 kwargs={ "values": addAllValue } )
3785 threads.append( t )
3786 t.start()
3787 for t in threads:
3788 t.join()
3789 # NOTE: This is the tuple
3790 containsAllResponses.append( t.result )
3791
3792 containsAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003793 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003794 if containsResponses[ i ] == main.ERROR:
3795 containsResults = main.FALSE
3796 else:
3797 containsResults = containsResults and\
3798 containsResponses[ i ][ 1 ]
3799 utilities.assert_equals( expect=main.TRUE,
3800 actual=containsAllResults,
3801 onpass="Set containsAll is functional",
3802 onfail="Set containsAll failed" )
3803
3804 main.step( "Distributed Set remove()" )
3805 onosSet.remove( addValue )
3806 removeResponses = []
3807 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003808 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003809 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003810 name="setTestRemove-" + str( i ),
3811 args=[ onosSetName, addValue ] )
3812 threads.append( t )
3813 t.start()
3814 for t in threads:
3815 t.join()
3816 removeResponses.append( t.result )
3817
3818 # main.TRUE = successfully changed the set
3819 # main.FALSE = action resulted in no change in set
3820 # main.ERROR - Some error in executing the function
3821 removeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003822 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 if removeResponses[ i ] == main.TRUE:
3824 # All is well
3825 pass
3826 elif removeResponses[ i ] == main.FALSE:
3827 # not in set, probably fine
3828 pass
3829 elif removeResponses[ i ] == main.ERROR:
3830 # Error in execution
3831 removeResults = main.FALSE
3832 else:
3833 # unexpected result
3834 removeResults = main.FALSE
3835 if removeResults != main.TRUE:
3836 main.log.error( "Error executing set remove" )
3837
3838 # Check if set is still correct
3839 size = len( onosSet )
3840 getResponses = []
3841 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003842 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003843 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003844 name="setTestGet-" + str( i ),
3845 args=[ onosSetName ] )
3846 threads.append( t )
3847 t.start()
3848 for t in threads:
3849 t.join()
3850 getResponses.append( t.result )
3851 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003852 for i in range( len( main.activeNodes ) ):
3853 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003854 if isinstance( getResponses[ i ], list):
3855 current = set( getResponses[ i ] )
3856 if len( current ) == len( getResponses[ i ] ):
3857 # no repeats
3858 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003859 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003860 " has incorrect view" +
3861 " of set " + onosSetName + ":\n" +
3862 str( getResponses[ i ] ) )
3863 main.log.debug( "Expected: " + str( onosSet ) )
3864 main.log.debug( "Actual: " + str( current ) )
3865 getResults = main.FALSE
3866 else:
3867 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003868 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003869 " has repeat elements in" +
3870 " set " + onosSetName + ":\n" +
3871 str( getResponses[ i ] ) )
3872 getResults = main.FALSE
3873 elif getResponses[ i ] == main.ERROR:
3874 getResults = main.FALSE
3875 sizeResponses = []
3876 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003877 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003878 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003879 name="setTestSize-" + str( i ),
3880 args=[ onosSetName ] )
3881 threads.append( t )
3882 t.start()
3883 for t in threads:
3884 t.join()
3885 sizeResponses.append( t.result )
3886 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003887 for i in range( len( main.activeNodes ) ):
3888 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003889 if size != sizeResponses[ i ]:
3890 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003891 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003892 " expected a size of " + str( size ) +
3893 " for set " + onosSetName +
3894 " but got " + str( sizeResponses[ i ] ) )
3895 removeResults = removeResults and getResults and sizeResults
3896 utilities.assert_equals( expect=main.TRUE,
3897 actual=removeResults,
3898 onpass="Set remove correct",
3899 onfail="Set remove was incorrect" )
3900
3901 main.step( "Distributed Set removeAll()" )
3902 onosSet.difference_update( addAllValue.split() )
3903 removeAllResponses = []
3904 threads = []
3905 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003906 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003907 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003908 name="setTestRemoveAll-" + str( i ),
3909 args=[ onosSetName, addAllValue ] )
3910 threads.append( t )
3911 t.start()
3912 for t in threads:
3913 t.join()
3914 removeAllResponses.append( t.result )
3915 except Exception, e:
3916 main.log.exception(e)
3917
3918 # main.TRUE = successfully changed the set
3919 # main.FALSE = action resulted in no change in set
3920 # main.ERROR - Some error in executing the function
3921 removeAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003922 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003923 if removeAllResponses[ i ] == main.TRUE:
3924 # All is well
3925 pass
3926 elif removeAllResponses[ i ] == main.FALSE:
3927 # not in set, probably fine
3928 pass
3929 elif removeAllResponses[ i ] == main.ERROR:
3930 # Error in execution
3931 removeAllResults = main.FALSE
3932 else:
3933 # unexpected result
3934 removeAllResults = main.FALSE
3935 if removeAllResults != main.TRUE:
3936 main.log.error( "Error executing set removeAll" )
3937
3938 # Check if set is still correct
3939 size = len( onosSet )
3940 getResponses = []
3941 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003942 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003943 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003944 name="setTestGet-" + str( i ),
3945 args=[ onosSetName ] )
3946 threads.append( t )
3947 t.start()
3948 for t in threads:
3949 t.join()
3950 getResponses.append( t.result )
3951 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003952 for i in range( len( main.activeNodes ) ):
3953 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003954 if isinstance( getResponses[ i ], list):
3955 current = set( getResponses[ i ] )
3956 if len( current ) == len( getResponses[ i ] ):
3957 # no repeats
3958 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003959 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003960 " has incorrect view" +
3961 " of set " + onosSetName + ":\n" +
3962 str( getResponses[ i ] ) )
3963 main.log.debug( "Expected: " + str( onosSet ) )
3964 main.log.debug( "Actual: " + str( current ) )
3965 getResults = main.FALSE
3966 else:
3967 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003968 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003969 " has repeat elements in" +
3970 " set " + onosSetName + ":\n" +
3971 str( getResponses[ i ] ) )
3972 getResults = main.FALSE
3973 elif getResponses[ i ] == main.ERROR:
3974 getResults = main.FALSE
3975 sizeResponses = []
3976 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003977 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003978 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003979 name="setTestSize-" + str( i ),
3980 args=[ onosSetName ] )
3981 threads.append( t )
3982 t.start()
3983 for t in threads:
3984 t.join()
3985 sizeResponses.append( t.result )
3986 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003987 for i in range( len( main.activeNodes ) ):
3988 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003989 if size != sizeResponses[ i ]:
3990 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003991 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003992 " expected a size of " + str( size ) +
3993 " for set " + onosSetName +
3994 " but got " + str( sizeResponses[ i ] ) )
3995 removeAllResults = removeAllResults and getResults and sizeResults
3996 utilities.assert_equals( expect=main.TRUE,
3997 actual=removeAllResults,
3998 onpass="Set removeAll correct",
3999 onfail="Set removeAll was incorrect" )
4000
4001 main.step( "Distributed Set addAll()" )
4002 onosSet.update( addAllValue.split() )
4003 addResponses = []
4004 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004005 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004006 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004007 name="setTestAddAll-" + str( i ),
4008 args=[ onosSetName, addAllValue ] )
4009 threads.append( t )
4010 t.start()
4011 for t in threads:
4012 t.join()
4013 addResponses.append( t.result )
4014
4015 # main.TRUE = successfully changed the set
4016 # main.FALSE = action resulted in no change in set
4017 # main.ERROR - Some error in executing the function
4018 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004019 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004020 if addResponses[ i ] == main.TRUE:
4021 # All is well
4022 pass
4023 elif addResponses[ i ] == main.FALSE:
4024 # Already in set, probably fine
4025 pass
4026 elif addResponses[ i ] == main.ERROR:
4027 # Error in execution
4028 addAllResults = main.FALSE
4029 else:
4030 # unexpected result
4031 addAllResults = main.FALSE
4032 if addAllResults != main.TRUE:
4033 main.log.error( "Error executing set addAll" )
4034
4035 # Check if set is still correct
4036 size = len( onosSet )
4037 getResponses = []
4038 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004039 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004040 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004041 name="setTestGet-" + str( i ),
4042 args=[ onosSetName ] )
4043 threads.append( t )
4044 t.start()
4045 for t in threads:
4046 t.join()
4047 getResponses.append( t.result )
4048 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004049 for i in range( len( main.activeNodes ) ):
4050 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004051 if isinstance( getResponses[ i ], list):
4052 current = set( getResponses[ i ] )
4053 if len( current ) == len( getResponses[ i ] ):
4054 # no repeats
4055 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004056 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004057 " has incorrect view" +
4058 " of set " + onosSetName + ":\n" +
4059 str( getResponses[ i ] ) )
4060 main.log.debug( "Expected: " + str( onosSet ) )
4061 main.log.debug( "Actual: " + str( current ) )
4062 getResults = main.FALSE
4063 else:
4064 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004065 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004066 " has repeat elements in" +
4067 " set " + onosSetName + ":\n" +
4068 str( getResponses[ i ] ) )
4069 getResults = main.FALSE
4070 elif getResponses[ i ] == main.ERROR:
4071 getResults = main.FALSE
4072 sizeResponses = []
4073 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004074 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004075 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004076 name="setTestSize-" + str( i ),
4077 args=[ onosSetName ] )
4078 threads.append( t )
4079 t.start()
4080 for t in threads:
4081 t.join()
4082 sizeResponses.append( t.result )
4083 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004084 for i in range( len( main.activeNodes ) ):
4085 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004086 if size != sizeResponses[ i ]:
4087 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004088 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004089 " expected a size of " + str( size ) +
4090 " for set " + onosSetName +
4091 " but got " + str( sizeResponses[ i ] ) )
4092 addAllResults = addAllResults and getResults and sizeResults
4093 utilities.assert_equals( expect=main.TRUE,
4094 actual=addAllResults,
4095 onpass="Set addAll correct",
4096 onfail="Set addAll was incorrect" )
4097
4098 main.step( "Distributed Set clear()" )
4099 onosSet.clear()
4100 clearResponses = []
4101 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004102 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004103 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004104 name="setTestClear-" + str( i ),
4105 args=[ onosSetName, " "], # Values doesn't matter
4106 kwargs={ "clear": True } )
4107 threads.append( t )
4108 t.start()
4109 for t in threads:
4110 t.join()
4111 clearResponses.append( t.result )
4112
4113 # main.TRUE = successfully changed the set
4114 # main.FALSE = action resulted in no change in set
4115 # main.ERROR - Some error in executing the function
4116 clearResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004117 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004118 if clearResponses[ i ] == main.TRUE:
4119 # All is well
4120 pass
4121 elif clearResponses[ i ] == main.FALSE:
4122 # Nothing set, probably fine
4123 pass
4124 elif clearResponses[ i ] == main.ERROR:
4125 # Error in execution
4126 clearResults = main.FALSE
4127 else:
4128 # unexpected result
4129 clearResults = main.FALSE
4130 if clearResults != main.TRUE:
4131 main.log.error( "Error executing set clear" )
4132
4133 # Check if set is still correct
4134 size = len( onosSet )
4135 getResponses = []
4136 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004137 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004138 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004139 name="setTestGet-" + str( i ),
4140 args=[ onosSetName ] )
4141 threads.append( t )
4142 t.start()
4143 for t in threads:
4144 t.join()
4145 getResponses.append( t.result )
4146 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004147 for i in range( len( main.activeNodes ) ):
4148 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004149 if isinstance( getResponses[ i ], list):
4150 current = set( getResponses[ i ] )
4151 if len( current ) == len( getResponses[ i ] ):
4152 # no repeats
4153 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004154 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004155 " has incorrect view" +
4156 " of set " + onosSetName + ":\n" +
4157 str( getResponses[ i ] ) )
4158 main.log.debug( "Expected: " + str( onosSet ) )
4159 main.log.debug( "Actual: " + str( current ) )
4160 getResults = main.FALSE
4161 else:
4162 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004163 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004164 " has repeat elements in" +
4165 " set " + onosSetName + ":\n" +
4166 str( getResponses[ i ] ) )
4167 getResults = main.FALSE
4168 elif getResponses[ i ] == main.ERROR:
4169 getResults = main.FALSE
4170 sizeResponses = []
4171 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004172 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004173 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004174 name="setTestSize-" + str( i ),
4175 args=[ onosSetName ] )
4176 threads.append( t )
4177 t.start()
4178 for t in threads:
4179 t.join()
4180 sizeResponses.append( t.result )
4181 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004182 for i in range( len( main.activeNodes ) ):
4183 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004184 if size != sizeResponses[ i ]:
4185 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004186 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004187 " expected a size of " + str( size ) +
4188 " for set " + onosSetName +
4189 " but got " + str( sizeResponses[ i ] ) )
4190 clearResults = clearResults and getResults and sizeResults
4191 utilities.assert_equals( expect=main.TRUE,
4192 actual=clearResults,
4193 onpass="Set clear correct",
4194 onfail="Set clear was incorrect" )
4195
4196 main.step( "Distributed Set addAll()" )
4197 onosSet.update( addAllValue.split() )
4198 addResponses = []
4199 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004200 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004201 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004202 name="setTestAddAll-" + str( i ),
4203 args=[ onosSetName, addAllValue ] )
4204 threads.append( t )
4205 t.start()
4206 for t in threads:
4207 t.join()
4208 addResponses.append( t.result )
4209
4210 # main.TRUE = successfully changed the set
4211 # main.FALSE = action resulted in no change in set
4212 # main.ERROR - Some error in executing the function
4213 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004214 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004215 if addResponses[ i ] == main.TRUE:
4216 # All is well
4217 pass
4218 elif addResponses[ i ] == main.FALSE:
4219 # Already in set, probably fine
4220 pass
4221 elif addResponses[ i ] == main.ERROR:
4222 # Error in execution
4223 addAllResults = main.FALSE
4224 else:
4225 # unexpected result
4226 addAllResults = main.FALSE
4227 if addAllResults != main.TRUE:
4228 main.log.error( "Error executing set addAll" )
4229
4230 # Check if set is still correct
4231 size = len( onosSet )
4232 getResponses = []
4233 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004234 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004235 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004236 name="setTestGet-" + str( i ),
4237 args=[ onosSetName ] )
4238 threads.append( t )
4239 t.start()
4240 for t in threads:
4241 t.join()
4242 getResponses.append( t.result )
4243 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004244 for i in range( len( main.activeNodes ) ):
4245 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004246 if isinstance( getResponses[ i ], list):
4247 current = set( getResponses[ i ] )
4248 if len( current ) == len( getResponses[ i ] ):
4249 # no repeats
4250 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004251 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004252 " has incorrect view" +
4253 " of set " + onosSetName + ":\n" +
4254 str( getResponses[ i ] ) )
4255 main.log.debug( "Expected: " + str( onosSet ) )
4256 main.log.debug( "Actual: " + str( current ) )
4257 getResults = main.FALSE
4258 else:
4259 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004260 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004261 " has repeat elements in" +
4262 " set " + onosSetName + ":\n" +
4263 str( getResponses[ i ] ) )
4264 getResults = main.FALSE
4265 elif getResponses[ i ] == main.ERROR:
4266 getResults = main.FALSE
4267 sizeResponses = []
4268 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004269 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004270 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004271 name="setTestSize-" + str( i ),
4272 args=[ onosSetName ] )
4273 threads.append( t )
4274 t.start()
4275 for t in threads:
4276 t.join()
4277 sizeResponses.append( t.result )
4278 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004279 for i in range( len( main.activeNodes ) ):
4280 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004281 if size != sizeResponses[ i ]:
4282 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004283 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004284 " expected a size of " + str( size ) +
4285 " for set " + onosSetName +
4286 " but got " + str( sizeResponses[ i ] ) )
4287 addAllResults = addAllResults and getResults and sizeResults
4288 utilities.assert_equals( expect=main.TRUE,
4289 actual=addAllResults,
4290 onpass="Set addAll correct",
4291 onfail="Set addAll was incorrect" )
4292
4293 main.step( "Distributed Set retain()" )
4294 onosSet.intersection_update( retainValue.split() )
4295 retainResponses = []
4296 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004297 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004298 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004299 name="setTestRetain-" + str( i ),
4300 args=[ onosSetName, retainValue ],
4301 kwargs={ "retain": True } )
4302 threads.append( t )
4303 t.start()
4304 for t in threads:
4305 t.join()
4306 retainResponses.append( t.result )
4307
4308 # main.TRUE = successfully changed the set
4309 # main.FALSE = action resulted in no change in set
4310 # main.ERROR - Some error in executing the function
4311 retainResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004312 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004313 if retainResponses[ i ] == main.TRUE:
4314 # All is well
4315 pass
4316 elif retainResponses[ i ] == main.FALSE:
4317 # Already in set, probably fine
4318 pass
4319 elif retainResponses[ i ] == main.ERROR:
4320 # Error in execution
4321 retainResults = main.FALSE
4322 else:
4323 # unexpected result
4324 retainResults = main.FALSE
4325 if retainResults != main.TRUE:
4326 main.log.error( "Error executing set retain" )
4327
4328 # Check if set is still correct
4329 size = len( onosSet )
4330 getResponses = []
4331 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004332 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004333 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004334 name="setTestGet-" + str( i ),
4335 args=[ onosSetName ] )
4336 threads.append( t )
4337 t.start()
4338 for t in threads:
4339 t.join()
4340 getResponses.append( t.result )
4341 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004342 for i in range( len( main.activeNodes ) ):
4343 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004344 if isinstance( getResponses[ i ], list):
4345 current = set( getResponses[ i ] )
4346 if len( current ) == len( getResponses[ i ] ):
4347 # no repeats
4348 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004349 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004350 " has incorrect view" +
4351 " of set " + onosSetName + ":\n" +
4352 str( getResponses[ i ] ) )
4353 main.log.debug( "Expected: " + str( onosSet ) )
4354 main.log.debug( "Actual: " + str( current ) )
4355 getResults = main.FALSE
4356 else:
4357 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004358 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004359 " has repeat elements in" +
4360 " set " + onosSetName + ":\n" +
4361 str( getResponses[ i ] ) )
4362 getResults = main.FALSE
4363 elif getResponses[ i ] == main.ERROR:
4364 getResults = main.FALSE
4365 sizeResponses = []
4366 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004367 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004368 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004369 name="setTestSize-" + str( i ),
4370 args=[ onosSetName ] )
4371 threads.append( t )
4372 t.start()
4373 for t in threads:
4374 t.join()
4375 sizeResponses.append( t.result )
4376 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004377 for i in range( len( main.activeNodes ) ):
4378 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004379 if size != sizeResponses[ i ]:
4380 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004381 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004382 str( size ) + " for set " + onosSetName +
4383 " but got " + str( sizeResponses[ i ] ) )
4384 retainResults = retainResults and getResults and sizeResults
4385 utilities.assert_equals( expect=main.TRUE,
4386 actual=retainResults,
4387 onpass="Set retain correct",
4388 onfail="Set retain was incorrect" )
4389
Jon Hall2a5002c2015-08-21 16:49:11 -07004390 # Transactional maps
4391 main.step( "Partitioned Transactional maps put" )
4392 tMapValue = "Testing"
4393 numKeys = 100
4394 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004395 node = main.activeNodes[0]
4396 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall2a5002c2015-08-21 16:49:11 -07004397 if len( putResponses ) == 100:
4398 for i in putResponses:
4399 if putResponses[ i ][ 'value' ] != tMapValue:
4400 putResult = False
4401 else:
4402 putResult = False
4403 if not putResult:
4404 main.log.debug( "Put response values: " + str( putResponses ) )
4405 utilities.assert_equals( expect=True,
4406 actual=putResult,
4407 onpass="Partitioned Transactional Map put successful",
4408 onfail="Partitioned Transactional Map put values are incorrect" )
4409
4410 main.step( "Partitioned Transactional maps get" )
4411 getCheck = True
4412 for n in range( 1, numKeys + 1 ):
4413 getResponses = []
4414 threads = []
4415 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004416 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004417 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4418 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004419 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004420 threads.append( t )
4421 t.start()
4422 for t in threads:
4423 t.join()
4424 getResponses.append( t.result )
4425 for node in getResponses:
4426 if node != tMapValue:
4427 valueCheck = False
4428 if not valueCheck:
4429 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4430 main.log.warn( getResponses )
4431 getCheck = getCheck and valueCheck
4432 utilities.assert_equals( expect=True,
4433 actual=getCheck,
4434 onpass="Partitioned Transactional Map get values were correct",
4435 onfail="Partitioned Transactional Map values incorrect" )
4436
4437 main.step( "In-memory Transactional maps put" )
4438 tMapValue = "Testing"
4439 numKeys = 100
4440 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004441 node = main.activeNodes[0]
4442 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue, inMemory=True )
Jon Hall2a5002c2015-08-21 16:49:11 -07004443 if len( putResponses ) == 100:
4444 for i in putResponses:
4445 if putResponses[ i ][ 'value' ] != tMapValue:
4446 putResult = False
4447 else:
4448 putResult = False
4449 if not putResult:
4450 main.log.debug( "Put response values: " + str( putResponses ) )
4451 utilities.assert_equals( expect=True,
4452 actual=putResult,
4453 onpass="In-Memory Transactional Map put successful",
4454 onfail="In-Memory Transactional Map put values are incorrect" )
4455
4456 main.step( "In-Memory Transactional maps get" )
4457 getCheck = True
4458 for n in range( 1, numKeys + 1 ):
4459 getResponses = []
4460 threads = []
4461 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004462 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004463 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4464 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004465 args=[ "Key" + str( n ) ],
Jon Hall2a5002c2015-08-21 16:49:11 -07004466 kwargs={ "inMemory": True } )
4467 threads.append( t )
4468 t.start()
4469 for t in threads:
4470 t.join()
4471 getResponses.append( t.result )
4472 for node in getResponses:
4473 if node != tMapValue:
4474 valueCheck = False
4475 if not valueCheck:
4476 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4477 main.log.warn( getResponses )
4478 getCheck = getCheck and valueCheck
4479 utilities.assert_equals( expect=True,
4480 actual=getCheck,
4481 onpass="In-Memory Transactional Map get values were correct",
4482 onfail="In-Memory Transactional Map values incorrect" )