blob: 45257135d0efa13bffe024106976e17c4be7adfa [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
Jon Hall657cdf62015-12-17 14:40:51 -08001684 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001685 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 Halld8f6de82015-12-17 17:04:34 -08002181 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002182 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002183 args=[ main.CLIs[i].hosts, [ None ] ],
2184 kwargs= { 'sleep': 5, 'attempts': 5,
2185 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002186 threads.append( t )
2187 t.start()
2188
2189 for t in threads:
2190 t.join()
2191 try:
2192 hosts.append( json.loads( t.result ) )
2193 except ( ValueError, TypeError ):
2194 main.log.exception( "Error parsing hosts results" )
2195 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002196 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002197 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002198 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002199 if hosts[ controller ]:
2200 for host in hosts[ controller ]:
2201 if host is None or host.get( 'ipAddresses', [] ) == []:
2202 main.log.error(
2203 "Error with host ipAddresses on controller" +
2204 controllerStr + ": " + str( host ) )
2205 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002206 ports = []
2207 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002208 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002209 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002210 name="ports-" + str( i ),
2211 args=[ ] )
2212 threads.append( t )
2213 t.start()
2214
2215 for t in threads:
2216 t.join()
2217 ports.append( t.result )
2218 links = []
2219 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002220 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002221 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002222 name="links-" + str( i ),
2223 args=[ ] )
2224 threads.append( t )
2225 t.start()
2226
2227 for t in threads:
2228 t.join()
2229 links.append( t.result )
2230 clusters = []
2231 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002232 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002233 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002234 name="clusters-" + str( i ),
2235 args=[ ] )
2236 threads.append( t )
2237 t.start()
2238
2239 for t in threads:
2240 t.join()
2241 clusters.append( t.result )
2242
2243 elapsed = time.time() - startTime
2244 cliTime = time.time() - cliStart
2245 print "Elapsed time: " + str( elapsed )
2246 print "CLI time: " + str( cliTime )
2247
2248 mnSwitches = main.Mininet1.getSwitches()
2249 mnLinks = main.Mininet1.getLinks()
2250 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002251 for controller in range( len( main.activeNodes ) ):
2252 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002253 if devices[ controller ] and ports[ controller ] and\
2254 "Error" not in devices[ controller ] and\
2255 "Error" not in ports[ controller ]:
2256
2257 currentDevicesResult = main.Mininet1.compareSwitches(
2258 mnSwitches,
2259 json.loads( devices[ controller ] ),
2260 json.loads( ports[ controller ] ) )
2261 else:
2262 currentDevicesResult = main.FALSE
2263 utilities.assert_equals( expect=main.TRUE,
2264 actual=currentDevicesResult,
2265 onpass="ONOS" + controllerStr +
2266 " Switches view is correct",
2267 onfail="ONOS" + controllerStr +
2268 " Switches view is incorrect" )
2269
2270 if links[ controller ] and "Error" not in links[ controller ]:
2271 currentLinksResult = main.Mininet1.compareLinks(
2272 mnSwitches, mnLinks,
2273 json.loads( links[ controller ] ) )
2274 else:
2275 currentLinksResult = main.FALSE
2276 utilities.assert_equals( expect=main.TRUE,
2277 actual=currentLinksResult,
2278 onpass="ONOS" + controllerStr +
2279 " links view is correct",
2280 onfail="ONOS" + controllerStr +
2281 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002282 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002283 currentHostsResult = main.Mininet1.compareHosts(
2284 mnHosts,
2285 hosts[ controller ] )
2286 else:
2287 currentHostsResult = main.FALSE
2288 utilities.assert_equals( expect=main.TRUE,
2289 actual=currentHostsResult,
2290 onpass="ONOS" + controllerStr +
2291 " hosts exist in Mininet",
2292 onfail="ONOS" + controllerStr +
2293 " hosts don't match Mininet" )
2294 # CHECKING HOST ATTACHMENT POINTS
2295 hostAttachment = True
2296 zeroHosts = False
2297 # FIXME: topo-HA/obelisk specific mappings:
2298 # key is mac and value is dpid
2299 mappings = {}
2300 for i in range( 1, 29 ): # hosts 1 through 28
2301 # set up correct variables:
2302 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2303 if i == 1:
2304 deviceId = "1000".zfill(16)
2305 elif i == 2:
2306 deviceId = "2000".zfill(16)
2307 elif i == 3:
2308 deviceId = "3000".zfill(16)
2309 elif i == 4:
2310 deviceId = "3004".zfill(16)
2311 elif i == 5:
2312 deviceId = "5000".zfill(16)
2313 elif i == 6:
2314 deviceId = "6000".zfill(16)
2315 elif i == 7:
2316 deviceId = "6007".zfill(16)
2317 elif i >= 8 and i <= 17:
2318 dpid = '3' + str( i ).zfill( 3 )
2319 deviceId = dpid.zfill(16)
2320 elif i >= 18 and i <= 27:
2321 dpid = '6' + str( i ).zfill( 3 )
2322 deviceId = dpid.zfill(16)
2323 elif i == 28:
2324 deviceId = "2800".zfill(16)
2325 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002326 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002327 if hosts[ controller ] == []:
2328 main.log.warn( "There are no hosts discovered" )
2329 zeroHosts = True
2330 else:
2331 for host in hosts[ controller ]:
2332 mac = None
2333 location = None
2334 device = None
2335 port = None
2336 try:
2337 mac = host.get( 'mac' )
2338 assert mac, "mac field could not be found for this host object"
2339
2340 location = host.get( 'location' )
2341 assert location, "location field could not be found for this host object"
2342
2343 # Trim the protocol identifier off deviceId
2344 device = str( location.get( 'elementId' ) ).split(':')[1]
2345 assert device, "elementId field could not be found for this host location object"
2346
2347 port = location.get( 'port' )
2348 assert port, "port field could not be found for this host location object"
2349
2350 # Now check if this matches where they should be
2351 if mac and device and port:
2352 if str( port ) != "1":
2353 main.log.error( "The attachment port is incorrect for " +
2354 "host " + str( mac ) +
2355 ". Expected: 1 Actual: " + str( port) )
2356 hostAttachment = False
2357 if device != mappings[ str( mac ) ]:
2358 main.log.error( "The attachment device is incorrect for " +
2359 "host " + str( mac ) +
2360 ". Expected: " + mappings[ str( mac ) ] +
2361 " Actual: " + device )
2362 hostAttachment = False
2363 else:
2364 hostAttachment = False
2365 except AssertionError:
2366 main.log.exception( "Json object not as expected" )
2367 main.log.error( repr( host ) )
2368 hostAttachment = False
2369 else:
2370 main.log.error( "No hosts json output or \"Error\"" +
2371 " in output. hosts = " +
2372 repr( hosts[ controller ] ) )
2373 if zeroHosts is False:
2374 hostAttachment = True
2375
2376 # END CHECKING HOST ATTACHMENT POINTS
2377 devicesResults = devicesResults and currentDevicesResult
2378 linksResults = linksResults and currentLinksResult
2379 hostsResults = hostsResults and currentHostsResult
2380 hostAttachmentResults = hostAttachmentResults and\
2381 hostAttachment
Jon Halle9b1fa32015-12-08 15:32:21 -08002382 topoResult = devicesResults and linksResults and\
2383 hostsResults and hostAttachmentResults
2384 utilities.assert_equals( expect=True,
2385 actual=topoResult,
2386 onpass="ONOS topology matches Mininet",
2387 onfail="ONOS topology don't match Mininet" )
2388 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002389
2390 # Compare json objects for hosts and dataplane clusters
2391
2392 # hosts
2393 main.step( "Hosts view is consistent across all ONOS nodes" )
2394 consistentHostsResult = main.TRUE
2395 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002396 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall657cdf62015-12-17 14:40:51 -08002397 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002398 if hosts[ controller ] == hosts[ 0 ]:
2399 continue
2400 else: # hosts not consistent
2401 main.log.error( "hosts from ONOS" + controllerStr +
2402 " is inconsistent with ONOS1" )
2403 main.log.warn( repr( hosts[ controller ] ) )
2404 consistentHostsResult = main.FALSE
2405
2406 else:
2407 main.log.error( "Error in getting ONOS hosts from ONOS" +
2408 controllerStr )
2409 consistentHostsResult = main.FALSE
2410 main.log.warn( "ONOS" + controllerStr +
2411 " hosts response: " +
2412 repr( hosts[ controller ] ) )
2413 utilities.assert_equals(
2414 expect=main.TRUE,
2415 actual=consistentHostsResult,
2416 onpass="Hosts view is consistent across all ONOS nodes",
2417 onfail="ONOS nodes have different views of hosts" )
2418
2419 main.step( "Hosts information is correct" )
2420 hostsResults = hostsResults and ipResult
2421 utilities.assert_equals(
2422 expect=main.TRUE,
2423 actual=hostsResults,
2424 onpass="Host information is correct",
2425 onfail="Host information is incorrect" )
2426
2427 main.step( "Host attachment points to the network" )
2428 utilities.assert_equals(
2429 expect=True,
2430 actual=hostAttachmentResults,
2431 onpass="Hosts are correctly attached to the network",
2432 onfail="ONOS did not correctly attach hosts to the network" )
2433
2434 # Strongly connected clusters of devices
2435 main.step( "Clusters view is consistent across all ONOS nodes" )
2436 consistentClustersResult = main.TRUE
2437 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002438 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002439 if "Error" not in clusters[ controller ]:
2440 if clusters[ controller ] == clusters[ 0 ]:
2441 continue
2442 else: # clusters not consistent
2443 main.log.error( "clusters from ONOS" +
2444 controllerStr +
2445 " is inconsistent with ONOS1" )
2446 consistentClustersResult = main.FALSE
2447
2448 else:
2449 main.log.error( "Error in getting dataplane clusters " +
2450 "from ONOS" + controllerStr )
2451 consistentClustersResult = main.FALSE
2452 main.log.warn( "ONOS" + controllerStr +
2453 " clusters response: " +
2454 repr( clusters[ controller ] ) )
2455 utilities.assert_equals(
2456 expect=main.TRUE,
2457 actual=consistentClustersResult,
2458 onpass="Clusters view is consistent across all ONOS nodes",
2459 onfail="ONOS nodes have different views of clusters" )
2460
2461 main.step( "There is only one SCC" )
2462 # there should always only be one cluster
2463 try:
2464 numClusters = len( json.loads( clusters[ 0 ] ) )
2465 except ( ValueError, TypeError ):
2466 main.log.exception( "Error parsing clusters[0]: " +
2467 repr( clusters[0] ) )
2468 clusterResults = main.FALSE
2469 if numClusters == 1:
2470 clusterResults = main.TRUE
2471 utilities.assert_equals(
2472 expect=1,
2473 actual=numClusters,
2474 onpass="ONOS shows 1 SCC",
2475 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2476
2477 topoResult = ( devicesResults and linksResults
2478 and hostsResults and consistentHostsResult
2479 and consistentClustersResult and clusterResults
2480 and ipResult and hostAttachmentResults )
2481
2482 topoResult = topoResult and int( count <= 2 )
2483 note = "note it takes about " + str( int( cliTime ) ) + \
2484 " seconds for the test to make all the cli calls to fetch " +\
2485 "the topology from each ONOS instance"
2486 main.log.info(
2487 "Very crass estimate for topology discovery/convergence( " +
2488 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2489 str( count ) + " tries" )
2490
2491 main.step( "Device information is correct" )
2492 utilities.assert_equals(
2493 expect=main.TRUE,
2494 actual=devicesResults,
2495 onpass="Device information is correct",
2496 onfail="Device information is incorrect" )
2497
2498 main.step( "Links are correct" )
2499 utilities.assert_equals(
2500 expect=main.TRUE,
2501 actual=linksResults,
2502 onpass="Link are correct",
2503 onfail="Links are incorrect" )
2504
2505 # FIXME: move this to an ONOS state case
2506 main.step( "Checking ONOS nodes" )
2507 nodesOutput = []
2508 nodeResults = main.TRUE
2509 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002510 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002511 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002512 name="nodes-" + str( i ),
2513 args=[ ] )
2514 threads.append( t )
2515 t.start()
2516
2517 for t in threads:
2518 t.join()
2519 nodesOutput.append( t.result )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002520 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002521 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002522 for i in nodesOutput:
2523 try:
2524 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002525 activeIps = []
2526 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002527 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002528 if node['state'] == 'ACTIVE':
2529 activeIps.append( node['ip'] )
2530 activeIps.sort()
2531 if ips == activeIps:
2532 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002533 except ( ValueError, TypeError ):
2534 main.log.error( "Error parsing nodes output" )
2535 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002536 currentResult = main.FALSE
2537 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002538 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2539 onpass="Nodes check successful",
2540 onfail="Nodes check NOT successful" )
2541
2542 def CASE9( self, main ):
2543 """
2544 Link s3-s28 down
2545 """
2546 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002547 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002548 assert main, "main not defined"
2549 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002550 assert main.CLIs, "main.CLIs not defined"
2551 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002552 # NOTE: You should probably run a topology check after this
2553
2554 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2555
2556 description = "Turn off a link to ensure that Link Discovery " +\
2557 "is working properly"
2558 main.case( description )
2559
2560 main.step( "Kill Link between s3 and s28" )
2561 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2562 main.log.info( "Waiting " + str( linkSleep ) +
2563 " seconds for link down to be discovered" )
2564 time.sleep( linkSleep )
2565 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2566 onpass="Link down successful",
2567 onfail="Failed to bring link down" )
2568 # TODO do some sort of check here
2569
2570 def CASE10( self, main ):
2571 """
2572 Link s3-s28 up
2573 """
2574 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002575 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002576 assert main, "main not defined"
2577 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002578 assert main.CLIs, "main.CLIs not defined"
2579 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002580 # NOTE: You should probably run a topology check after this
2581
2582 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2583
2584 description = "Restore a link to ensure that Link Discovery is " + \
2585 "working properly"
2586 main.case( description )
2587
2588 main.step( "Bring link between s3 and s28 back up" )
2589 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2590 main.log.info( "Waiting " + str( linkSleep ) +
2591 " seconds for link up to be discovered" )
2592 time.sleep( linkSleep )
2593 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2594 onpass="Link up successful",
2595 onfail="Failed to bring link up" )
2596 # TODO do some sort of check here
2597
2598 def CASE11( self, main ):
2599 """
2600 Switch Down
2601 """
2602 # NOTE: You should probably run a topology check after this
2603 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002604 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002605 assert main, "main not defined"
2606 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002607 assert main.CLIs, "main.CLIs not defined"
2608 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002609
2610 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2611
2612 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002613 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002614 main.case( description )
2615 switch = main.params[ 'kill' ][ 'switch' ]
2616 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2617
2618 # TODO: Make this switch parameterizable
2619 main.step( "Kill " + switch )
2620 main.log.info( "Deleting " + switch )
2621 main.Mininet1.delSwitch( switch )
2622 main.log.info( "Waiting " + str( switchSleep ) +
2623 " seconds for switch down to be discovered" )
2624 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002625 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002626 # Peek at the deleted switch
2627 main.log.warn( str( device ) )
2628 result = main.FALSE
2629 if device and device[ 'available' ] is False:
2630 result = main.TRUE
2631 utilities.assert_equals( expect=main.TRUE, actual=result,
2632 onpass="Kill switch successful",
2633 onfail="Failed to kill switch?" )
2634
2635 def CASE12( self, main ):
2636 """
2637 Switch Up
2638 """
2639 # NOTE: You should probably run a topology check after this
2640 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002641 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002642 assert main, "main not defined"
2643 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002644 assert main.CLIs, "main.CLIs not defined"
2645 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002646 assert ONOS1Port, "ONOS1Port not defined"
2647 assert ONOS2Port, "ONOS2Port not defined"
2648 assert ONOS3Port, "ONOS3Port not defined"
2649 assert ONOS4Port, "ONOS4Port not defined"
2650 assert ONOS5Port, "ONOS5Port not defined"
2651 assert ONOS6Port, "ONOS6Port not defined"
2652 assert ONOS7Port, "ONOS7Port not defined"
2653
2654 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2655 switch = main.params[ 'kill' ][ 'switch' ]
2656 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2657 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002658 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002659 description = "Adding a switch to ensure it is discovered correctly"
2660 main.case( description )
2661
2662 main.step( "Add back " + switch )
2663 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2664 for peer in links:
2665 main.Mininet1.addLink( switch, peer )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002666 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002667 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2668 main.log.info( "Waiting " + str( switchSleep ) +
2669 " seconds for switch up to be discovered" )
2670 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002671 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002672 # Peek at the deleted switch
2673 main.log.warn( str( device ) )
2674 result = main.FALSE
2675 if device and device[ 'available' ]:
2676 result = main.TRUE
2677 utilities.assert_equals( expect=main.TRUE, actual=result,
2678 onpass="add switch successful",
2679 onfail="Failed to add switch?" )
2680
2681 def CASE13( self, main ):
2682 """
2683 Clean up
2684 """
2685 import os
2686 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002687 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002688 assert main, "main not defined"
2689 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002690 assert main.CLIs, "main.CLIs not defined"
2691 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002692
2693 # printing colors to terminal
2694 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2695 'blue': '\033[94m', 'green': '\033[92m',
2696 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2697 main.case( "Test Cleanup" )
2698 main.step( "Killing tcpdumps" )
2699 main.Mininet2.stopTcpdump()
2700
2701 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002702 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002703 main.step( "Copying MN pcap and ONOS log files to test station" )
2704 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2705 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002706 # NOTE: MN Pcap file is being saved to logdir.
2707 # We scp this file as MN and TestON aren't necessarily the same vm
2708
2709 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002710 # TODO: Load these from params
2711 # NOTE: must end in /
2712 logFolder = "/opt/onos/log/"
2713 logFiles = [ "karaf.log", "karaf.log.1" ]
2714 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002715 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002716 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002717 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002718 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2719 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002720 # std*.log's
2721 # NOTE: must end in /
2722 logFolder = "/opt/onos/var/"
2723 logFiles = [ "stderr.log", "stdout.log" ]
2724 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002725 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002726 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002727 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002728 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2729 logFolder + f, dstName )
2730 else:
2731 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002732
2733 main.step( "Stopping Mininet" )
2734 mnResult = main.Mininet1.stopNet()
2735 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2736 onpass="Mininet stopped",
2737 onfail="MN cleanup NOT successful" )
2738
2739 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002740 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002741 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2742 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002743
2744 try:
2745 timerLog = open( main.logdir + "/Timers.csv", 'w')
2746 # Overwrite with empty line and close
2747 labels = "Gossip Intents, Restart"
2748 data = str( gossipTime ) + ", " + str( main.restartTime )
2749 timerLog.write( labels + "\n" + data )
2750 timerLog.close()
2751 except NameError, e:
2752 main.log.exception(e)
2753
2754 def CASE14( self, main ):
2755 """
2756 start election app on all onos nodes
2757 """
Jon Halle1a3b752015-07-22 13:02:46 -07002758 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002759 assert main, "main not defined"
2760 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002761 assert main.CLIs, "main.CLIs not defined"
2762 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002763
2764 main.case("Start Leadership Election app")
2765 main.step( "Install leadership election app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002766 onosCli = main.CLIs[ main.activeNodes[0] ]
2767 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002768 utilities.assert_equals(
2769 expect=main.TRUE,
2770 actual=appResult,
2771 onpass="Election app installed",
2772 onfail="Something went wrong with installing Leadership election" )
2773
2774 main.step( "Run for election on each node" )
2775 leaderResult = main.TRUE
2776 leaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002777 for i in main.activeNodes:
2778 main.CLIs[i].electionTestRun()
2779 for i in main.activeNodes:
2780 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002781 leader = cli.electionTestLeader()
2782 if leader is None or leader == main.FALSE:
2783 main.log.error( cli.name + ": Leader for the election app " +
2784 "should be an ONOS node, instead got '" +
2785 str( leader ) + "'" )
2786 leaderResult = main.FALSE
2787 leaders.append( leader )
2788 utilities.assert_equals(
2789 expect=main.TRUE,
2790 actual=leaderResult,
2791 onpass="Successfully ran for leadership",
2792 onfail="Failed to run for leadership" )
2793
2794 main.step( "Check that each node shows the same leader" )
2795 sameLeader = main.TRUE
2796 if len( set( leaders ) ) != 1:
2797 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002798 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002799 str( leaders ) )
2800 utilities.assert_equals(
2801 expect=main.TRUE,
2802 actual=sameLeader,
2803 onpass="Leadership is consistent for the election topic",
2804 onfail="Nodes have different leaders" )
2805
2806 def CASE15( self, main ):
2807 """
2808 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002809 15.1 Run election on each node
2810 15.2 Check that each node has the same leaders and candidates
2811 15.3 Find current leader and withdraw
2812 15.4 Check that a new node was elected leader
2813 15.5 Check that that new leader was the candidate of old leader
2814 15.6 Run for election on old leader
2815 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2816 15.8 Make sure that the old leader was added to the candidate list
2817
2818 old and new variable prefixes refer to data from before vs after
2819 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002820 """
2821 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002822 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002823 assert main, "main not defined"
2824 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002825 assert main.CLIs, "main.CLIs not defined"
2826 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002827
Jon Hall5cf14d52015-07-16 12:15:19 -07002828 description = "Check that Leadership Election is still functional"
2829 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002830 # NOTE: Need to re-run since being a canidate is not persistant
2831 # TODO: add check for "Command not found:" in the driver, this
2832 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002833
acsmars71adceb2015-08-31 15:09:26 -07002834 oldLeaders = [] # leaders by node before withdrawl from candidates
2835 newLeaders = [] # leaders by node after withdrawl from candidates
2836 oldAllCandidates = [] # list of lists of each nodes' candidates before
2837 newAllCandidates = [] # list of lists of each nodes' candidates after
2838 oldCandidates = [] # list of candidates from node 0 before withdrawl
2839 newCandidates = [] # list of candidates from node 0 after withdrawl
2840 oldLeader = '' # the old leader from oldLeaders, None if not same
2841 newLeader = '' # the new leaders fron newLoeaders, None if not same
2842 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2843 expectNoLeader = False # True when there is only one leader
2844 if main.numCtrls == 1:
2845 expectNoLeader = True
2846
2847 main.step( "Run for election on each node" )
2848 electionResult = main.TRUE
2849
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002850 for i in main.activeNodes: # run test election on each node
2851 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002852 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002853 utilities.assert_equals(
2854 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002855 actual=electionResult,
2856 onpass="All nodes successfully ran for leadership",
2857 onfail="At least one node failed to run for leadership" )
2858
acsmars3a72bde2015-09-02 14:16:22 -07002859 if electionResult == main.FALSE:
2860 main.log.error(
2861 "Skipping Test Case because Election Test App isn't loaded" )
2862 main.skipCase()
2863
acsmars71adceb2015-08-31 15:09:26 -07002864 main.step( "Check that each node shows the same leader and candidates" )
2865 sameResult = main.TRUE
2866 failMessage = "Nodes have different leaders"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002867 for i in main.activeNodes:
2868 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07002869 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2870 oldAllCandidates.append( node )
2871 oldLeaders.append( node[ 0 ] )
2872 oldCandidates = oldAllCandidates[ 0 ]
2873
2874 # Check that each node has the same leader. Defines oldLeader
2875 if len( set( oldLeaders ) ) != 1:
2876 sameResult = main.FALSE
2877 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2878 oldLeader = None
2879 else:
2880 oldLeader = oldLeaders[ 0 ]
2881
2882 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002883 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07002884 for candidates in oldAllCandidates:
2885 if set( candidates ) != set( oldCandidates ):
2886 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002887 candidateDiscrepancy = True
2888
2889 if candidateDiscrepancy:
2890 failMessage += " and candidates"
2891
acsmars71adceb2015-08-31 15:09:26 -07002892 utilities.assert_equals(
2893 expect=main.TRUE,
2894 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002895 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002896 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002897
2898 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002899 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002900 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002901 if oldLeader is None:
2902 main.log.error( "Leadership isn't consistent." )
2903 withdrawResult = main.FALSE
2904 # Get the CLI of the oldLeader
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002905 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002906 if oldLeader == main.nodes[ i ].ip_address:
2907 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002908 break
2909 else: # FOR/ELSE statement
2910 main.log.error( "Leader election, could not find current leader" )
2911 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002912 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002913 utilities.assert_equals(
2914 expect=main.TRUE,
2915 actual=withdrawResult,
2916 onpass="Node was withdrawn from election",
2917 onfail="Node was not withdrawn from election" )
2918
acsmars71adceb2015-08-31 15:09:26 -07002919 main.step( "Check that a new node was elected leader" )
2920
Jon Hall5cf14d52015-07-16 12:15:19 -07002921 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002922 newLeaderResult = main.TRUE
2923 failMessage = "Nodes have different leaders"
2924
2925 # Get new leaders and candidates
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002926 for i in main.activeNodes:
2927 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07002928 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2929 # elections might no have finished yet
2930 if node[ 0 ] == 'none' and not expectNoLeader:
2931 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2932 "sure elections are complete." )
2933 time.sleep(5)
2934 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2935 # election still isn't done or there is a problem
2936 if node[ 0 ] == 'none':
2937 main.log.error( "No leader was elected on at least 1 node" )
2938 newLeaderResult = main.FALSE
2939 newAllCandidates.append( node )
2940 newLeaders.append( node[ 0 ] )
2941 newCandidates = newAllCandidates[ 0 ]
2942
2943 # Check that each node has the same leader. Defines newLeader
2944 if len( set( newLeaders ) ) != 1:
2945 newLeaderResult = main.FALSE
2946 main.log.error( "Nodes have different leaders: " +
2947 str( newLeaders ) )
2948 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002949 else:
acsmars71adceb2015-08-31 15:09:26 -07002950 newLeader = newLeaders[ 0 ]
2951
2952 # Check that each node's candidate list is the same
2953 for candidates in newAllCandidates:
2954 if set( candidates ) != set( newCandidates ):
2955 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002956 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002957
2958 # Check that the new leader is not the older leader, which was withdrawn
2959 if newLeader == oldLeader:
2960 newLeaderResult = main.FALSE
2961 main.log.error( "All nodes still see old leader: " + oldLeader +
2962 " as the current leader" )
2963
Jon Hall5cf14d52015-07-16 12:15:19 -07002964 utilities.assert_equals(
2965 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002966 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002967 onpass="Leadership election passed",
2968 onfail="Something went wrong with Leadership election" )
2969
acsmars71adceb2015-08-31 15:09:26 -07002970 main.step( "Check that that new leader was the candidate of old leader")
2971 # candidates[ 2 ] should be come the top candidate after withdrawl
2972 correctCandidateResult = main.TRUE
2973 if expectNoLeader:
2974 if newLeader == 'none':
2975 main.log.info( "No leader expected. None found. Pass" )
2976 correctCandidateResult = main.TRUE
2977 else:
2978 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2979 correctCandidateResult = main.FALSE
2980 elif newLeader != oldCandidates[ 2 ]:
2981 correctCandidateResult = main.FALSE
2982 main.log.error( "Candidate " + newLeader + " was elected. " +
2983 oldCandidates[ 2 ] + " should have had priority." )
2984
2985 utilities.assert_equals(
2986 expect=main.TRUE,
2987 actual=correctCandidateResult,
2988 onpass="Correct Candidate Elected",
2989 onfail="Incorrect Candidate Elected" )
2990
Jon Hall5cf14d52015-07-16 12:15:19 -07002991 main.step( "Run for election on old leader( just so everyone " +
2992 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002993 if oldLeaderCLI is not None:
2994 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002995 else:
acsmars71adceb2015-08-31 15:09:26 -07002996 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002997 runResult = main.FALSE
2998 utilities.assert_equals(
2999 expect=main.TRUE,
3000 actual=runResult,
3001 onpass="App re-ran for election",
3002 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07003003 main.step(
3004 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003005 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07003006 positionResult = main.TRUE
3007 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3008
3009 # Reset and reuse the new candidate and leaders lists
3010 newAllCandidates = []
3011 newCandidates = []
3012 newLeaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003013 for i in main.activeNodes:
3014 cli = main.CLIs[i]
acsmars71adceb2015-08-31 15:09:26 -07003015 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3016 if oldLeader not in node: # election might no have finished yet
3017 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3018 "be sure elections are complete" )
3019 time.sleep(5)
3020 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3021 if oldLeader not in node: # election still isn't done, errors
3022 main.log.error(
3023 "Old leader was not elected on at least one node" )
3024 positionResult = main.FALSE
3025 newAllCandidates.append( node )
3026 newLeaders.append( node[ 0 ] )
3027 newCandidates = newAllCandidates[ 0 ]
3028
3029 # Check that each node has the same leader. Defines newLeader
3030 if len( set( newLeaders ) ) != 1:
3031 positionResult = main.FALSE
3032 main.log.error( "Nodes have different leaders: " +
3033 str( newLeaders ) )
3034 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003035 else:
acsmars71adceb2015-08-31 15:09:26 -07003036 newLeader = newLeaders[ 0 ]
3037
3038 # Check that each node's candidate list is the same
3039 for candidates in newAllCandidates:
3040 if set( candidates ) != set( newCandidates ):
3041 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003042 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003043
3044 # Check that the re-elected node is last on the candidate List
3045 if oldLeader != newCandidates[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003046 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
acsmars71adceb2015-08-31 15:09:26 -07003047 str( newCandidates ) )
3048 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003049
3050 utilities.assert_equals(
3051 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07003052 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003053 onpass="Old leader successfully re-ran for election",
3054 onfail="Something went wrong with Leadership election after " +
3055 "the old leader re-ran for election" )
3056
3057 def CASE16( self, main ):
3058 """
3059 Install Distributed Primitives app
3060 """
3061 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003062 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003063 assert main, "main not defined"
3064 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003065 assert main.CLIs, "main.CLIs not defined"
3066 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003067
3068 # Variables for the distributed primitives tests
3069 global pCounterName
3070 global iCounterName
3071 global pCounterValue
3072 global iCounterValue
3073 global onosSet
3074 global onosSetName
3075 pCounterName = "TestON-Partitions"
3076 iCounterName = "TestON-inMemory"
3077 pCounterValue = 0
3078 iCounterValue = 0
3079 onosSet = set([])
3080 onosSetName = "TestON-set"
3081
3082 description = "Install Primitives app"
3083 main.case( description )
3084 main.step( "Install Primitives app" )
3085 appName = "org.onosproject.distributedprimitives"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003086 node = main.activeNodes[0]
3087 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003088 utilities.assert_equals( expect=main.TRUE,
3089 actual=appResults,
3090 onpass="Primitives app activated",
3091 onfail="Primitives app not activated" )
3092 time.sleep( 5 ) # To allow all nodes to activate
3093
3094 def CASE17( self, main ):
3095 """
3096 Check for basic functionality with distributed primitives
3097 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003099 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003100 assert main, "main not defined"
3101 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003102 assert main.CLIs, "main.CLIs not defined"
3103 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003104 assert pCounterName, "pCounterName not defined"
3105 assert iCounterName, "iCounterName not defined"
3106 assert onosSetName, "onosSetName not defined"
3107 # NOTE: assert fails if value is 0/None/Empty/False
3108 try:
3109 pCounterValue
3110 except NameError:
3111 main.log.error( "pCounterValue not defined, setting to 0" )
3112 pCounterValue = 0
3113 try:
3114 iCounterValue
3115 except NameError:
3116 main.log.error( "iCounterValue not defined, setting to 0" )
3117 iCounterValue = 0
3118 try:
3119 onosSet
3120 except NameError:
3121 main.log.error( "onosSet not defined, setting to empty Set" )
3122 onosSet = set([])
3123 # Variables for the distributed primitives tests. These are local only
3124 addValue = "a"
3125 addAllValue = "a b c d e f"
3126 retainValue = "c d e f"
3127
3128 description = "Check for basic functionality with distributed " +\
3129 "primitives"
3130 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003131 main.caseExplanation = "Test the methods of the distributed " +\
3132 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003133 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003134 # Partitioned counters
3135 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003136 pCounters = []
3137 threads = []
3138 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003139 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003140 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3141 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003142 args=[ pCounterName ] )
3143 pCounterValue += 1
3144 addedPValues.append( pCounterValue )
3145 threads.append( t )
3146 t.start()
3147
3148 for t in threads:
3149 t.join()
3150 pCounters.append( t.result )
3151 # Check that counter incremented numController times
3152 pCounterResults = True
3153 for i in addedPValues:
3154 tmpResult = i in pCounters
3155 pCounterResults = pCounterResults and tmpResult
3156 if not tmpResult:
3157 main.log.error( str( i ) + " is not in partitioned "
3158 "counter incremented results" )
3159 utilities.assert_equals( expect=True,
3160 actual=pCounterResults,
3161 onpass="Default counter incremented",
3162 onfail="Error incrementing default" +
3163 " counter" )
3164
Jon Halle1a3b752015-07-22 13:02:46 -07003165 main.step( "Get then Increment a default counter on each node" )
3166 pCounters = []
3167 threads = []
3168 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003169 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003170 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3171 name="counterGetAndAdd-" + str( i ),
3172 args=[ pCounterName ] )
3173 addedPValues.append( pCounterValue )
3174 pCounterValue += 1
3175 threads.append( t )
3176 t.start()
3177
3178 for t in threads:
3179 t.join()
3180 pCounters.append( t.result )
3181 # Check that counter incremented numController times
3182 pCounterResults = True
3183 for i in addedPValues:
3184 tmpResult = i in pCounters
3185 pCounterResults = pCounterResults and tmpResult
3186 if not tmpResult:
3187 main.log.error( str( i ) + " is not in partitioned "
3188 "counter incremented results" )
3189 utilities.assert_equals( expect=True,
3190 actual=pCounterResults,
3191 onpass="Default counter incremented",
3192 onfail="Error incrementing default" +
3193 " counter" )
3194
3195 main.step( "Counters we added have the correct values" )
3196 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3197 utilities.assert_equals( expect=main.TRUE,
3198 actual=incrementCheck,
3199 onpass="Added counters are correct",
3200 onfail="Added counters are incorrect" )
3201
3202 main.step( "Add -8 to then get a default counter on each node" )
3203 pCounters = []
3204 threads = []
3205 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003206 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003207 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3208 name="counterIncrement-" + str( i ),
3209 args=[ pCounterName ],
3210 kwargs={ "delta": -8 } )
3211 pCounterValue += -8
3212 addedPValues.append( pCounterValue )
3213 threads.append( t )
3214 t.start()
3215
3216 for t in threads:
3217 t.join()
3218 pCounters.append( t.result )
3219 # Check that counter incremented numController times
3220 pCounterResults = True
3221 for i in addedPValues:
3222 tmpResult = i in pCounters
3223 pCounterResults = pCounterResults and tmpResult
3224 if not tmpResult:
3225 main.log.error( str( i ) + " is not in partitioned "
3226 "counter incremented results" )
3227 utilities.assert_equals( expect=True,
3228 actual=pCounterResults,
3229 onpass="Default counter incremented",
3230 onfail="Error incrementing default" +
3231 " counter" )
3232
3233 main.step( "Add 5 to then get a default counter on each node" )
3234 pCounters = []
3235 threads = []
3236 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003237 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003238 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3239 name="counterIncrement-" + str( i ),
3240 args=[ pCounterName ],
3241 kwargs={ "delta": 5 } )
3242 pCounterValue += 5
3243 addedPValues.append( pCounterValue )
3244 threads.append( t )
3245 t.start()
3246
3247 for t in threads:
3248 t.join()
3249 pCounters.append( t.result )
3250 # Check that counter incremented numController times
3251 pCounterResults = True
3252 for i in addedPValues:
3253 tmpResult = i in pCounters
3254 pCounterResults = pCounterResults and tmpResult
3255 if not tmpResult:
3256 main.log.error( str( i ) + " is not in partitioned "
3257 "counter incremented results" )
3258 utilities.assert_equals( expect=True,
3259 actual=pCounterResults,
3260 onpass="Default counter incremented",
3261 onfail="Error incrementing default" +
3262 " counter" )
3263
3264 main.step( "Get then add 5 to a default counter on each node" )
3265 pCounters = []
3266 threads = []
3267 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003268 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003269 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3270 name="counterIncrement-" + str( i ),
3271 args=[ pCounterName ],
3272 kwargs={ "delta": 5 } )
3273 addedPValues.append( pCounterValue )
3274 pCounterValue += 5
3275 threads.append( t )
3276 t.start()
3277
3278 for t in threads:
3279 t.join()
3280 pCounters.append( t.result )
3281 # Check that counter incremented numController times
3282 pCounterResults = True
3283 for i in addedPValues:
3284 tmpResult = i in pCounters
3285 pCounterResults = pCounterResults and tmpResult
3286 if not tmpResult:
3287 main.log.error( str( i ) + " is not in partitioned "
3288 "counter incremented results" )
3289 utilities.assert_equals( expect=True,
3290 actual=pCounterResults,
3291 onpass="Default counter incremented",
3292 onfail="Error incrementing default" +
3293 " counter" )
3294
3295 main.step( "Counters we added have the correct values" )
3296 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3297 utilities.assert_equals( expect=main.TRUE,
3298 actual=incrementCheck,
3299 onpass="Added counters are correct",
3300 onfail="Added counters are incorrect" )
3301
3302 # In-Memory counters
3303 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003304 iCounters = []
3305 addedIValues = []
3306 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003307 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003308 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003309 name="icounterIncrement-" + str( i ),
3310 args=[ iCounterName ],
3311 kwargs={ "inMemory": True } )
3312 iCounterValue += 1
3313 addedIValues.append( iCounterValue )
3314 threads.append( t )
3315 t.start()
3316
3317 for t in threads:
3318 t.join()
3319 iCounters.append( t.result )
3320 # Check that counter incremented numController times
3321 iCounterResults = True
3322 for i in addedIValues:
3323 tmpResult = i in iCounters
3324 iCounterResults = iCounterResults and tmpResult
3325 if not tmpResult:
3326 main.log.error( str( i ) + " is not in the in-memory "
3327 "counter incremented results" )
3328 utilities.assert_equals( expect=True,
3329 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003330 onpass="In-memory counter incremented",
3331 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003332 " counter" )
3333
Jon Halle1a3b752015-07-22 13:02:46 -07003334 main.step( "Get then Increment a in-memory counter on each node" )
3335 iCounters = []
3336 threads = []
3337 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003338 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003339 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3340 name="counterGetAndAdd-" + str( i ),
3341 args=[ iCounterName ],
3342 kwargs={ "inMemory": True } )
3343 addedIValues.append( iCounterValue )
3344 iCounterValue += 1
3345 threads.append( t )
3346 t.start()
3347
3348 for t in threads:
3349 t.join()
3350 iCounters.append( t.result )
3351 # Check that counter incremented numController times
3352 iCounterResults = True
3353 for i in addedIValues:
3354 tmpResult = i in iCounters
3355 iCounterResults = iCounterResults and tmpResult
3356 if not tmpResult:
3357 main.log.error( str( i ) + " is not in in-memory "
3358 "counter incremented results" )
3359 utilities.assert_equals( expect=True,
3360 actual=iCounterResults,
3361 onpass="In-memory counter incremented",
3362 onfail="Error incrementing in-memory" +
3363 " counter" )
3364
3365 main.step( "Counters we added have the correct values" )
3366 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3367 utilities.assert_equals( expect=main.TRUE,
3368 actual=incrementCheck,
3369 onpass="Added counters are correct",
3370 onfail="Added counters are incorrect" )
3371
3372 main.step( "Add -8 to then get a in-memory counter on each node" )
3373 iCounters = []
3374 threads = []
3375 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003376 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003377 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3378 name="counterIncrement-" + str( i ),
3379 args=[ iCounterName ],
3380 kwargs={ "delta": -8, "inMemory": True } )
3381 iCounterValue += -8
3382 addedIValues.append( iCounterValue )
3383 threads.append( t )
3384 t.start()
3385
3386 for t in threads:
3387 t.join()
3388 iCounters.append( t.result )
3389 # Check that counter incremented numController times
3390 iCounterResults = True
3391 for i in addedIValues:
3392 tmpResult = i in iCounters
3393 iCounterResults = iCounterResults and tmpResult
3394 if not tmpResult:
3395 main.log.error( str( i ) + " is not in in-memory "
3396 "counter incremented results" )
3397 utilities.assert_equals( expect=True,
3398 actual=pCounterResults,
3399 onpass="In-memory counter incremented",
3400 onfail="Error incrementing in-memory" +
3401 " counter" )
3402
3403 main.step( "Add 5 to then get a in-memory counter on each node" )
3404 iCounters = []
3405 threads = []
3406 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003407 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003408 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3409 name="counterIncrement-" + str( i ),
3410 args=[ iCounterName ],
3411 kwargs={ "delta": 5, "inMemory": True } )
3412 iCounterValue += 5
3413 addedIValues.append( iCounterValue )
3414 threads.append( t )
3415 t.start()
3416
3417 for t in threads:
3418 t.join()
3419 iCounters.append( t.result )
3420 # Check that counter incremented numController times
3421 iCounterResults = True
3422 for i in addedIValues:
3423 tmpResult = i in iCounters
3424 iCounterResults = iCounterResults and tmpResult
3425 if not tmpResult:
3426 main.log.error( str( i ) + " is not in in-memory "
3427 "counter incremented results" )
3428 utilities.assert_equals( expect=True,
3429 actual=pCounterResults,
3430 onpass="In-memory counter incremented",
3431 onfail="Error incrementing in-memory" +
3432 " counter" )
3433
3434 main.step( "Get then add 5 to a in-memory counter on each node" )
3435 iCounters = []
3436 threads = []
3437 addedIValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003438 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003439 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3440 name="counterIncrement-" + str( i ),
3441 args=[ iCounterName ],
3442 kwargs={ "delta": 5, "inMemory": True } )
3443 addedIValues.append( iCounterValue )
3444 iCounterValue += 5
3445 threads.append( t )
3446 t.start()
3447
3448 for t in threads:
3449 t.join()
3450 iCounters.append( t.result )
3451 # Check that counter incremented numController times
3452 iCounterResults = True
3453 for i in addedIValues:
3454 tmpResult = i in iCounters
3455 iCounterResults = iCounterResults and tmpResult
3456 if not tmpResult:
3457 main.log.error( str( i ) + " is not in in-memory "
3458 "counter incremented results" )
3459 utilities.assert_equals( expect=True,
3460 actual=iCounterResults,
3461 onpass="In-memory counter incremented",
3462 onfail="Error incrementing in-memory" +
3463 " counter" )
3464
3465 main.step( "Counters we added have the correct values" )
3466 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3467 utilities.assert_equals( expect=main.TRUE,
3468 actual=incrementCheck,
3469 onpass="Added counters are correct",
3470 onfail="Added counters are incorrect" )
3471
Jon Hall5cf14d52015-07-16 12:15:19 -07003472 main.step( "Check counters are consistant across nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07003473 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003474 utilities.assert_equals( expect=main.TRUE,
3475 actual=consistentCounterResults,
3476 onpass="ONOS counters are consistent " +
3477 "across nodes",
3478 onfail="ONOS Counters are inconsistent " +
3479 "across nodes" )
3480
3481 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003482 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3483 incrementCheck = incrementCheck and \
3484 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003485 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003486 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003487 onpass="Added counters are correct",
3488 onfail="Added counters are incorrect" )
3489 # DISTRIBUTED SETS
3490 main.step( "Distributed Set get" )
3491 size = len( onosSet )
3492 getResponses = []
3493 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003494 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003495 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003496 name="setTestGet-" + str( i ),
3497 args=[ onosSetName ] )
3498 threads.append( t )
3499 t.start()
3500 for t in threads:
3501 t.join()
3502 getResponses.append( t.result )
3503
3504 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003505 for i in range( len( main.activeNodes ) ):
3506 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003507 if isinstance( getResponses[ i ], list):
3508 current = set( getResponses[ i ] )
3509 if len( current ) == len( getResponses[ i ] ):
3510 # no repeats
3511 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003512 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003513 " has incorrect view" +
3514 " of set " + onosSetName + ":\n" +
3515 str( getResponses[ i ] ) )
3516 main.log.debug( "Expected: " + str( onosSet ) )
3517 main.log.debug( "Actual: " + str( current ) )
3518 getResults = main.FALSE
3519 else:
3520 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003521 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003522 " has repeat elements in" +
3523 " set " + onosSetName + ":\n" +
3524 str( getResponses[ i ] ) )
3525 getResults = main.FALSE
3526 elif getResponses[ i ] == main.ERROR:
3527 getResults = main.FALSE
3528 utilities.assert_equals( expect=main.TRUE,
3529 actual=getResults,
3530 onpass="Set elements are correct",
3531 onfail="Set elements are incorrect" )
3532
3533 main.step( "Distributed Set size" )
3534 sizeResponses = []
3535 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003536 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003537 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003538 name="setTestSize-" + str( i ),
3539 args=[ onosSetName ] )
3540 threads.append( t )
3541 t.start()
3542 for t in threads:
3543 t.join()
3544 sizeResponses.append( t.result )
3545
3546 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003547 for i in range( len( main.activeNodes ) ):
3548 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003549 if size != sizeResponses[ i ]:
3550 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003551 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003552 " expected a size of " + str( size ) +
3553 " for set " + onosSetName +
3554 " but got " + str( sizeResponses[ i ] ) )
3555 utilities.assert_equals( expect=main.TRUE,
3556 actual=sizeResults,
3557 onpass="Set sizes are correct",
3558 onfail="Set sizes are incorrect" )
3559
3560 main.step( "Distributed Set add()" )
3561 onosSet.add( addValue )
3562 addResponses = []
3563 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003564 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003565 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003566 name="setTestAdd-" + str( i ),
3567 args=[ onosSetName, addValue ] )
3568 threads.append( t )
3569 t.start()
3570 for t in threads:
3571 t.join()
3572 addResponses.append( t.result )
3573
3574 # main.TRUE = successfully changed the set
3575 # main.FALSE = action resulted in no change in set
3576 # main.ERROR - Some error in executing the function
3577 addResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003578 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003579 if addResponses[ i ] == main.TRUE:
3580 # All is well
3581 pass
3582 elif addResponses[ i ] == main.FALSE:
3583 # Already in set, probably fine
3584 pass
3585 elif addResponses[ i ] == main.ERROR:
3586 # Error in execution
3587 addResults = main.FALSE
3588 else:
3589 # unexpected result
3590 addResults = main.FALSE
3591 if addResults != main.TRUE:
3592 main.log.error( "Error executing set add" )
3593
3594 # Check if set is still correct
3595 size = len( onosSet )
3596 getResponses = []
3597 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003598 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003599 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003600 name="setTestGet-" + str( i ),
3601 args=[ onosSetName ] )
3602 threads.append( t )
3603 t.start()
3604 for t in threads:
3605 t.join()
3606 getResponses.append( t.result )
3607 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003608 for i in range( len( main.activeNodes ) ):
3609 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003610 if isinstance( getResponses[ i ], list):
3611 current = set( getResponses[ i ] )
3612 if len( current ) == len( getResponses[ i ] ):
3613 # no repeats
3614 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003615 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003616 " of set " + onosSetName + ":\n" +
3617 str( getResponses[ i ] ) )
3618 main.log.debug( "Expected: " + str( onosSet ) )
3619 main.log.debug( "Actual: " + str( current ) )
3620 getResults = main.FALSE
3621 else:
3622 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003623 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003624 " set " + onosSetName + ":\n" +
3625 str( getResponses[ i ] ) )
3626 getResults = main.FALSE
3627 elif getResponses[ i ] == main.ERROR:
3628 getResults = main.FALSE
3629 sizeResponses = []
3630 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003631 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003632 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003633 name="setTestSize-" + str( i ),
3634 args=[ onosSetName ] )
3635 threads.append( t )
3636 t.start()
3637 for t in threads:
3638 t.join()
3639 sizeResponses.append( t.result )
3640 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003641 for i in range( len( main.activeNodes ) ):
3642 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003643 if size != sizeResponses[ i ]:
3644 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003645 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003646 " expected a size of " + str( size ) +
3647 " for set " + onosSetName +
3648 " but got " + str( sizeResponses[ i ] ) )
3649 addResults = addResults and getResults and sizeResults
3650 utilities.assert_equals( expect=main.TRUE,
3651 actual=addResults,
3652 onpass="Set add correct",
3653 onfail="Set add was incorrect" )
3654
3655 main.step( "Distributed Set addAll()" )
3656 onosSet.update( addAllValue.split() )
3657 addResponses = []
3658 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003659 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003660 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003661 name="setTestAddAll-" + str( i ),
3662 args=[ onosSetName, addAllValue ] )
3663 threads.append( t )
3664 t.start()
3665 for t in threads:
3666 t.join()
3667 addResponses.append( t.result )
3668
3669 # main.TRUE = successfully changed the set
3670 # main.FALSE = action resulted in no change in set
3671 # main.ERROR - Some error in executing the function
3672 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003673 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003674 if addResponses[ i ] == main.TRUE:
3675 # All is well
3676 pass
3677 elif addResponses[ i ] == main.FALSE:
3678 # Already in set, probably fine
3679 pass
3680 elif addResponses[ i ] == main.ERROR:
3681 # Error in execution
3682 addAllResults = main.FALSE
3683 else:
3684 # unexpected result
3685 addAllResults = main.FALSE
3686 if addAllResults != main.TRUE:
3687 main.log.error( "Error executing set addAll" )
3688
3689 # Check if set is still correct
3690 size = len( onosSet )
3691 getResponses = []
3692 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003693 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003694 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003695 name="setTestGet-" + str( i ),
3696 args=[ onosSetName ] )
3697 threads.append( t )
3698 t.start()
3699 for t in threads:
3700 t.join()
3701 getResponses.append( t.result )
3702 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003703 for i in range( len( main.activeNodes ) ):
3704 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003705 if isinstance( getResponses[ i ], list):
3706 current = set( getResponses[ i ] )
3707 if len( current ) == len( getResponses[ i ] ):
3708 # no repeats
3709 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003710 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003711 " has incorrect view" +
3712 " of set " + onosSetName + ":\n" +
3713 str( getResponses[ i ] ) )
3714 main.log.debug( "Expected: " + str( onosSet ) )
3715 main.log.debug( "Actual: " + str( current ) )
3716 getResults = main.FALSE
3717 else:
3718 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003719 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003720 " has repeat elements in" +
3721 " set " + onosSetName + ":\n" +
3722 str( getResponses[ i ] ) )
3723 getResults = main.FALSE
3724 elif getResponses[ i ] == main.ERROR:
3725 getResults = main.FALSE
3726 sizeResponses = []
3727 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003728 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003729 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003730 name="setTestSize-" + str( i ),
3731 args=[ onosSetName ] )
3732 threads.append( t )
3733 t.start()
3734 for t in threads:
3735 t.join()
3736 sizeResponses.append( t.result )
3737 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003738 for i in range( len( main.activeNodes ) ):
3739 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003740 if size != sizeResponses[ i ]:
3741 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003742 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003743 " expected a size of " + str( size ) +
3744 " for set " + onosSetName +
3745 " but got " + str( sizeResponses[ i ] ) )
3746 addAllResults = addAllResults and getResults and sizeResults
3747 utilities.assert_equals( expect=main.TRUE,
3748 actual=addAllResults,
3749 onpass="Set addAll correct",
3750 onfail="Set addAll was incorrect" )
3751
3752 main.step( "Distributed Set contains()" )
3753 containsResponses = []
3754 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003755 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003756 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003757 name="setContains-" + str( i ),
3758 args=[ onosSetName ],
3759 kwargs={ "values": addValue } )
3760 threads.append( t )
3761 t.start()
3762 for t in threads:
3763 t.join()
3764 # NOTE: This is the tuple
3765 containsResponses.append( t.result )
3766
3767 containsResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003768 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003769 if containsResponses[ i ] == main.ERROR:
3770 containsResults = main.FALSE
3771 else:
3772 containsResults = containsResults and\
3773 containsResponses[ i ][ 1 ]
3774 utilities.assert_equals( expect=main.TRUE,
3775 actual=containsResults,
3776 onpass="Set contains is functional",
3777 onfail="Set contains failed" )
3778
3779 main.step( "Distributed Set containsAll()" )
3780 containsAllResponses = []
3781 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003782 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003783 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003784 name="setContainsAll-" + str( i ),
3785 args=[ onosSetName ],
3786 kwargs={ "values": addAllValue } )
3787 threads.append( t )
3788 t.start()
3789 for t in threads:
3790 t.join()
3791 # NOTE: This is the tuple
3792 containsAllResponses.append( t.result )
3793
3794 containsAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003795 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003796 if containsResponses[ i ] == main.ERROR:
3797 containsResults = main.FALSE
3798 else:
3799 containsResults = containsResults and\
3800 containsResponses[ i ][ 1 ]
3801 utilities.assert_equals( expect=main.TRUE,
3802 actual=containsAllResults,
3803 onpass="Set containsAll is functional",
3804 onfail="Set containsAll failed" )
3805
3806 main.step( "Distributed Set remove()" )
3807 onosSet.remove( addValue )
3808 removeResponses = []
3809 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003810 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003811 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003812 name="setTestRemove-" + str( i ),
3813 args=[ onosSetName, addValue ] )
3814 threads.append( t )
3815 t.start()
3816 for t in threads:
3817 t.join()
3818 removeResponses.append( t.result )
3819
3820 # main.TRUE = successfully changed the set
3821 # main.FALSE = action resulted in no change in set
3822 # main.ERROR - Some error in executing the function
3823 removeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003824 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003825 if removeResponses[ i ] == main.TRUE:
3826 # All is well
3827 pass
3828 elif removeResponses[ i ] == main.FALSE:
3829 # not in set, probably fine
3830 pass
3831 elif removeResponses[ i ] == main.ERROR:
3832 # Error in execution
3833 removeResults = main.FALSE
3834 else:
3835 # unexpected result
3836 removeResults = main.FALSE
3837 if removeResults != main.TRUE:
3838 main.log.error( "Error executing set remove" )
3839
3840 # Check if set is still correct
3841 size = len( onosSet )
3842 getResponses = []
3843 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003844 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003845 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003846 name="setTestGet-" + str( i ),
3847 args=[ onosSetName ] )
3848 threads.append( t )
3849 t.start()
3850 for t in threads:
3851 t.join()
3852 getResponses.append( t.result )
3853 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003854 for i in range( len( main.activeNodes ) ):
3855 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003856 if isinstance( getResponses[ i ], list):
3857 current = set( getResponses[ i ] )
3858 if len( current ) == len( getResponses[ i ] ):
3859 # no repeats
3860 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003861 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003862 " has incorrect view" +
3863 " of set " + onosSetName + ":\n" +
3864 str( getResponses[ i ] ) )
3865 main.log.debug( "Expected: " + str( onosSet ) )
3866 main.log.debug( "Actual: " + str( current ) )
3867 getResults = main.FALSE
3868 else:
3869 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003870 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003871 " has repeat elements in" +
3872 " set " + onosSetName + ":\n" +
3873 str( getResponses[ i ] ) )
3874 getResults = main.FALSE
3875 elif getResponses[ i ] == main.ERROR:
3876 getResults = main.FALSE
3877 sizeResponses = []
3878 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003879 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003880 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003881 name="setTestSize-" + str( i ),
3882 args=[ onosSetName ] )
3883 threads.append( t )
3884 t.start()
3885 for t in threads:
3886 t.join()
3887 sizeResponses.append( t.result )
3888 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003889 for i in range( len( main.activeNodes ) ):
3890 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003891 if size != sizeResponses[ i ]:
3892 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003893 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003894 " expected a size of " + str( size ) +
3895 " for set " + onosSetName +
3896 " but got " + str( sizeResponses[ i ] ) )
3897 removeResults = removeResults and getResults and sizeResults
3898 utilities.assert_equals( expect=main.TRUE,
3899 actual=removeResults,
3900 onpass="Set remove correct",
3901 onfail="Set remove was incorrect" )
3902
3903 main.step( "Distributed Set removeAll()" )
3904 onosSet.difference_update( addAllValue.split() )
3905 removeAllResponses = []
3906 threads = []
3907 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003908 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003909 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003910 name="setTestRemoveAll-" + str( i ),
3911 args=[ onosSetName, addAllValue ] )
3912 threads.append( t )
3913 t.start()
3914 for t in threads:
3915 t.join()
3916 removeAllResponses.append( t.result )
3917 except Exception, e:
3918 main.log.exception(e)
3919
3920 # main.TRUE = successfully changed the set
3921 # main.FALSE = action resulted in no change in set
3922 # main.ERROR - Some error in executing the function
3923 removeAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003924 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003925 if removeAllResponses[ i ] == main.TRUE:
3926 # All is well
3927 pass
3928 elif removeAllResponses[ i ] == main.FALSE:
3929 # not in set, probably fine
3930 pass
3931 elif removeAllResponses[ i ] == main.ERROR:
3932 # Error in execution
3933 removeAllResults = main.FALSE
3934 else:
3935 # unexpected result
3936 removeAllResults = main.FALSE
3937 if removeAllResults != main.TRUE:
3938 main.log.error( "Error executing set removeAll" )
3939
3940 # Check if set is still correct
3941 size = len( onosSet )
3942 getResponses = []
3943 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003944 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003945 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003946 name="setTestGet-" + str( i ),
3947 args=[ onosSetName ] )
3948 threads.append( t )
3949 t.start()
3950 for t in threads:
3951 t.join()
3952 getResponses.append( t.result )
3953 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003954 for i in range( len( main.activeNodes ) ):
3955 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003956 if isinstance( getResponses[ i ], list):
3957 current = set( getResponses[ i ] )
3958 if len( current ) == len( getResponses[ i ] ):
3959 # no repeats
3960 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003961 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003962 " has incorrect view" +
3963 " of set " + onosSetName + ":\n" +
3964 str( getResponses[ i ] ) )
3965 main.log.debug( "Expected: " + str( onosSet ) )
3966 main.log.debug( "Actual: " + str( current ) )
3967 getResults = main.FALSE
3968 else:
3969 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003970 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003971 " has repeat elements in" +
3972 " set " + onosSetName + ":\n" +
3973 str( getResponses[ i ] ) )
3974 getResults = main.FALSE
3975 elif getResponses[ i ] == main.ERROR:
3976 getResults = main.FALSE
3977 sizeResponses = []
3978 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003979 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003980 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003981 name="setTestSize-" + str( i ),
3982 args=[ onosSetName ] )
3983 threads.append( t )
3984 t.start()
3985 for t in threads:
3986 t.join()
3987 sizeResponses.append( t.result )
3988 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003989 for i in range( len( main.activeNodes ) ):
3990 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003991 if size != sizeResponses[ i ]:
3992 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003993 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003994 " expected a size of " + str( size ) +
3995 " for set " + onosSetName +
3996 " but got " + str( sizeResponses[ i ] ) )
3997 removeAllResults = removeAllResults and getResults and sizeResults
3998 utilities.assert_equals( expect=main.TRUE,
3999 actual=removeAllResults,
4000 onpass="Set removeAll correct",
4001 onfail="Set removeAll was incorrect" )
4002
4003 main.step( "Distributed Set addAll()" )
4004 onosSet.update( addAllValue.split() )
4005 addResponses = []
4006 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004007 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004008 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004009 name="setTestAddAll-" + str( i ),
4010 args=[ onosSetName, addAllValue ] )
4011 threads.append( t )
4012 t.start()
4013 for t in threads:
4014 t.join()
4015 addResponses.append( t.result )
4016
4017 # main.TRUE = successfully changed the set
4018 # main.FALSE = action resulted in no change in set
4019 # main.ERROR - Some error in executing the function
4020 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004021 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004022 if addResponses[ i ] == main.TRUE:
4023 # All is well
4024 pass
4025 elif addResponses[ i ] == main.FALSE:
4026 # Already in set, probably fine
4027 pass
4028 elif addResponses[ i ] == main.ERROR:
4029 # Error in execution
4030 addAllResults = main.FALSE
4031 else:
4032 # unexpected result
4033 addAllResults = main.FALSE
4034 if addAllResults != main.TRUE:
4035 main.log.error( "Error executing set addAll" )
4036
4037 # Check if set is still correct
4038 size = len( onosSet )
4039 getResponses = []
4040 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004041 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004042 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004043 name="setTestGet-" + str( i ),
4044 args=[ onosSetName ] )
4045 threads.append( t )
4046 t.start()
4047 for t in threads:
4048 t.join()
4049 getResponses.append( t.result )
4050 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004051 for i in range( len( main.activeNodes ) ):
4052 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004053 if isinstance( getResponses[ i ], list):
4054 current = set( getResponses[ i ] )
4055 if len( current ) == len( getResponses[ i ] ):
4056 # no repeats
4057 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004058 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004059 " has incorrect view" +
4060 " of set " + onosSetName + ":\n" +
4061 str( getResponses[ i ] ) )
4062 main.log.debug( "Expected: " + str( onosSet ) )
4063 main.log.debug( "Actual: " + str( current ) )
4064 getResults = main.FALSE
4065 else:
4066 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004067 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004068 " has repeat elements in" +
4069 " set " + onosSetName + ":\n" +
4070 str( getResponses[ i ] ) )
4071 getResults = main.FALSE
4072 elif getResponses[ i ] == main.ERROR:
4073 getResults = main.FALSE
4074 sizeResponses = []
4075 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004076 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004077 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004078 name="setTestSize-" + str( i ),
4079 args=[ onosSetName ] )
4080 threads.append( t )
4081 t.start()
4082 for t in threads:
4083 t.join()
4084 sizeResponses.append( t.result )
4085 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004086 for i in range( len( main.activeNodes ) ):
4087 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004088 if size != sizeResponses[ i ]:
4089 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004090 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004091 " expected a size of " + str( size ) +
4092 " for set " + onosSetName +
4093 " but got " + str( sizeResponses[ i ] ) )
4094 addAllResults = addAllResults and getResults and sizeResults
4095 utilities.assert_equals( expect=main.TRUE,
4096 actual=addAllResults,
4097 onpass="Set addAll correct",
4098 onfail="Set addAll was incorrect" )
4099
4100 main.step( "Distributed Set clear()" )
4101 onosSet.clear()
4102 clearResponses = []
4103 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004104 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004105 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004106 name="setTestClear-" + str( i ),
4107 args=[ onosSetName, " "], # Values doesn't matter
4108 kwargs={ "clear": True } )
4109 threads.append( t )
4110 t.start()
4111 for t in threads:
4112 t.join()
4113 clearResponses.append( t.result )
4114
4115 # main.TRUE = successfully changed the set
4116 # main.FALSE = action resulted in no change in set
4117 # main.ERROR - Some error in executing the function
4118 clearResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004119 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004120 if clearResponses[ i ] == main.TRUE:
4121 # All is well
4122 pass
4123 elif clearResponses[ i ] == main.FALSE:
4124 # Nothing set, probably fine
4125 pass
4126 elif clearResponses[ i ] == main.ERROR:
4127 # Error in execution
4128 clearResults = main.FALSE
4129 else:
4130 # unexpected result
4131 clearResults = main.FALSE
4132 if clearResults != main.TRUE:
4133 main.log.error( "Error executing set clear" )
4134
4135 # Check if set is still correct
4136 size = len( onosSet )
4137 getResponses = []
4138 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004139 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004140 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004141 name="setTestGet-" + str( i ),
4142 args=[ onosSetName ] )
4143 threads.append( t )
4144 t.start()
4145 for t in threads:
4146 t.join()
4147 getResponses.append( t.result )
4148 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004149 for i in range( len( main.activeNodes ) ):
4150 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004151 if isinstance( getResponses[ i ], list):
4152 current = set( getResponses[ i ] )
4153 if len( current ) == len( getResponses[ i ] ):
4154 # no repeats
4155 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004156 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004157 " has incorrect view" +
4158 " of set " + onosSetName + ":\n" +
4159 str( getResponses[ i ] ) )
4160 main.log.debug( "Expected: " + str( onosSet ) )
4161 main.log.debug( "Actual: " + str( current ) )
4162 getResults = main.FALSE
4163 else:
4164 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004165 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004166 " has repeat elements in" +
4167 " set " + onosSetName + ":\n" +
4168 str( getResponses[ i ] ) )
4169 getResults = main.FALSE
4170 elif getResponses[ i ] == main.ERROR:
4171 getResults = main.FALSE
4172 sizeResponses = []
4173 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004174 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004175 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004176 name="setTestSize-" + str( i ),
4177 args=[ onosSetName ] )
4178 threads.append( t )
4179 t.start()
4180 for t in threads:
4181 t.join()
4182 sizeResponses.append( t.result )
4183 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004184 for i in range( len( main.activeNodes ) ):
4185 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004186 if size != sizeResponses[ i ]:
4187 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004188 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004189 " expected a size of " + str( size ) +
4190 " for set " + onosSetName +
4191 " but got " + str( sizeResponses[ i ] ) )
4192 clearResults = clearResults and getResults and sizeResults
4193 utilities.assert_equals( expect=main.TRUE,
4194 actual=clearResults,
4195 onpass="Set clear correct",
4196 onfail="Set clear was incorrect" )
4197
4198 main.step( "Distributed Set addAll()" )
4199 onosSet.update( addAllValue.split() )
4200 addResponses = []
4201 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004202 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004203 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004204 name="setTestAddAll-" + str( i ),
4205 args=[ onosSetName, addAllValue ] )
4206 threads.append( t )
4207 t.start()
4208 for t in threads:
4209 t.join()
4210 addResponses.append( t.result )
4211
4212 # main.TRUE = successfully changed the set
4213 # main.FALSE = action resulted in no change in set
4214 # main.ERROR - Some error in executing the function
4215 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004216 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004217 if addResponses[ i ] == main.TRUE:
4218 # All is well
4219 pass
4220 elif addResponses[ i ] == main.FALSE:
4221 # Already in set, probably fine
4222 pass
4223 elif addResponses[ i ] == main.ERROR:
4224 # Error in execution
4225 addAllResults = main.FALSE
4226 else:
4227 # unexpected result
4228 addAllResults = main.FALSE
4229 if addAllResults != main.TRUE:
4230 main.log.error( "Error executing set addAll" )
4231
4232 # Check if set is still correct
4233 size = len( onosSet )
4234 getResponses = []
4235 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004236 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004237 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004238 name="setTestGet-" + str( i ),
4239 args=[ onosSetName ] )
4240 threads.append( t )
4241 t.start()
4242 for t in threads:
4243 t.join()
4244 getResponses.append( t.result )
4245 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004246 for i in range( len( main.activeNodes ) ):
4247 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004248 if isinstance( getResponses[ i ], list):
4249 current = set( getResponses[ i ] )
4250 if len( current ) == len( getResponses[ i ] ):
4251 # no repeats
4252 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004253 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004254 " has incorrect view" +
4255 " of set " + onosSetName + ":\n" +
4256 str( getResponses[ i ] ) )
4257 main.log.debug( "Expected: " + str( onosSet ) )
4258 main.log.debug( "Actual: " + str( current ) )
4259 getResults = main.FALSE
4260 else:
4261 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004262 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004263 " has repeat elements in" +
4264 " set " + onosSetName + ":\n" +
4265 str( getResponses[ i ] ) )
4266 getResults = main.FALSE
4267 elif getResponses[ i ] == main.ERROR:
4268 getResults = main.FALSE
4269 sizeResponses = []
4270 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004271 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004272 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004273 name="setTestSize-" + str( i ),
4274 args=[ onosSetName ] )
4275 threads.append( t )
4276 t.start()
4277 for t in threads:
4278 t.join()
4279 sizeResponses.append( t.result )
4280 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004281 for i in range( len( main.activeNodes ) ):
4282 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004283 if size != sizeResponses[ i ]:
4284 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004285 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004286 " expected a size of " + str( size ) +
4287 " for set " + onosSetName +
4288 " but got " + str( sizeResponses[ i ] ) )
4289 addAllResults = addAllResults and getResults and sizeResults
4290 utilities.assert_equals( expect=main.TRUE,
4291 actual=addAllResults,
4292 onpass="Set addAll correct",
4293 onfail="Set addAll was incorrect" )
4294
4295 main.step( "Distributed Set retain()" )
4296 onosSet.intersection_update( retainValue.split() )
4297 retainResponses = []
4298 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004299 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004300 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004301 name="setTestRetain-" + str( i ),
4302 args=[ onosSetName, retainValue ],
4303 kwargs={ "retain": True } )
4304 threads.append( t )
4305 t.start()
4306 for t in threads:
4307 t.join()
4308 retainResponses.append( t.result )
4309
4310 # main.TRUE = successfully changed the set
4311 # main.FALSE = action resulted in no change in set
4312 # main.ERROR - Some error in executing the function
4313 retainResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004314 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004315 if retainResponses[ i ] == main.TRUE:
4316 # All is well
4317 pass
4318 elif retainResponses[ i ] == main.FALSE:
4319 # Already in set, probably fine
4320 pass
4321 elif retainResponses[ i ] == main.ERROR:
4322 # Error in execution
4323 retainResults = main.FALSE
4324 else:
4325 # unexpected result
4326 retainResults = main.FALSE
4327 if retainResults != main.TRUE:
4328 main.log.error( "Error executing set retain" )
4329
4330 # Check if set is still correct
4331 size = len( onosSet )
4332 getResponses = []
4333 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004334 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004335 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004336 name="setTestGet-" + str( i ),
4337 args=[ onosSetName ] )
4338 threads.append( t )
4339 t.start()
4340 for t in threads:
4341 t.join()
4342 getResponses.append( t.result )
4343 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004344 for i in range( len( main.activeNodes ) ):
4345 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004346 if isinstance( getResponses[ i ], list):
4347 current = set( getResponses[ i ] )
4348 if len( current ) == len( getResponses[ i ] ):
4349 # no repeats
4350 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004351 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004352 " has incorrect view" +
4353 " of set " + onosSetName + ":\n" +
4354 str( getResponses[ i ] ) )
4355 main.log.debug( "Expected: " + str( onosSet ) )
4356 main.log.debug( "Actual: " + str( current ) )
4357 getResults = main.FALSE
4358 else:
4359 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004360 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004361 " has repeat elements in" +
4362 " set " + onosSetName + ":\n" +
4363 str( getResponses[ i ] ) )
4364 getResults = main.FALSE
4365 elif getResponses[ i ] == main.ERROR:
4366 getResults = main.FALSE
4367 sizeResponses = []
4368 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004369 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004370 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004371 name="setTestSize-" + str( i ),
4372 args=[ onosSetName ] )
4373 threads.append( t )
4374 t.start()
4375 for t in threads:
4376 t.join()
4377 sizeResponses.append( t.result )
4378 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004379 for i in range( len( main.activeNodes ) ):
4380 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004381 if size != sizeResponses[ i ]:
4382 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004383 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004384 str( size ) + " for set " + onosSetName +
4385 " but got " + str( sizeResponses[ i ] ) )
4386 retainResults = retainResults and getResults and sizeResults
4387 utilities.assert_equals( expect=main.TRUE,
4388 actual=retainResults,
4389 onpass="Set retain correct",
4390 onfail="Set retain was incorrect" )
4391
Jon Hall2a5002c2015-08-21 16:49:11 -07004392 # Transactional maps
4393 main.step( "Partitioned Transactional maps put" )
4394 tMapValue = "Testing"
4395 numKeys = 100
4396 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004397 node = main.activeNodes[0]
4398 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall2a5002c2015-08-21 16:49:11 -07004399 if len( putResponses ) == 100:
4400 for i in putResponses:
4401 if putResponses[ i ][ 'value' ] != tMapValue:
4402 putResult = False
4403 else:
4404 putResult = False
4405 if not putResult:
4406 main.log.debug( "Put response values: " + str( putResponses ) )
4407 utilities.assert_equals( expect=True,
4408 actual=putResult,
4409 onpass="Partitioned Transactional Map put successful",
4410 onfail="Partitioned Transactional Map put values are incorrect" )
4411
4412 main.step( "Partitioned Transactional maps get" )
4413 getCheck = True
4414 for n in range( 1, numKeys + 1 ):
4415 getResponses = []
4416 threads = []
4417 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004418 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004419 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4420 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004421 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004422 threads.append( t )
4423 t.start()
4424 for t in threads:
4425 t.join()
4426 getResponses.append( t.result )
4427 for node in getResponses:
4428 if node != tMapValue:
4429 valueCheck = False
4430 if not valueCheck:
4431 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4432 main.log.warn( getResponses )
4433 getCheck = getCheck and valueCheck
4434 utilities.assert_equals( expect=True,
4435 actual=getCheck,
4436 onpass="Partitioned Transactional Map get values were correct",
4437 onfail="Partitioned Transactional Map values incorrect" )
4438
4439 main.step( "In-memory Transactional maps put" )
4440 tMapValue = "Testing"
4441 numKeys = 100
4442 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004443 node = main.activeNodes[0]
4444 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue, inMemory=True )
Jon Hall2a5002c2015-08-21 16:49:11 -07004445 if len( putResponses ) == 100:
4446 for i in putResponses:
4447 if putResponses[ i ][ 'value' ] != tMapValue:
4448 putResult = False
4449 else:
4450 putResult = False
4451 if not putResult:
4452 main.log.debug( "Put response values: " + str( putResponses ) )
4453 utilities.assert_equals( expect=True,
4454 actual=putResult,
4455 onpass="In-Memory Transactional Map put successful",
4456 onfail="In-Memory Transactional Map put values are incorrect" )
4457
4458 main.step( "In-Memory Transactional maps get" )
4459 getCheck = True
4460 for n in range( 1, numKeys + 1 ):
4461 getResponses = []
4462 threads = []
4463 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004464 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004465 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4466 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004467 args=[ "Key" + str( n ) ],
Jon Hall2a5002c2015-08-21 16:49:11 -07004468 kwargs={ "inMemory": True } )
4469 threads.append( t )
4470 t.start()
4471 for t in threads:
4472 t.join()
4473 getResponses.append( t.result )
4474 for node in getResponses:
4475 if node != tMapValue:
4476 valueCheck = False
4477 if not valueCheck:
4478 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4479 main.log.warn( getResponses )
4480 getCheck = getCheck and valueCheck
4481 utilities.assert_equals( expect=True,
4482 actual=getCheck,
4483 onpass="In-Memory Transactional Map get values were correct",
4484 onfail="In-Memory Transactional Map values incorrect" )