blob: f58073fd4ace0115042d941fa8ac3cede0392a54 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if the HA test setup is
3 working correctly. There are no failures so this test should
4 have a 100% pass rate
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
8CASE2: Assign devices to controllers
9CASE21: Assign mastership to controllers
10CASE3: Assign intents
11CASE4: Ping across added host intents
12CASE5: Reading state of ONOS
13CASE6: The Failure case. Since this is the Sanity test, we do nothing.
14CASE7: Check state after control plane failure
15CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
21CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
23CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
25"""
26
27
28class HAsanity:
29
30 def __init__( self ):
31 self.default = ''
32
33 def CASE1( self, main ):
34 """
35 CASE1 is to compile ONOS and push it to the test machines
36
37 Startup sequence:
38 cell <name>
39 onos-verify-cell
40 NOTE: temporary - onos-remove-raft-logs
41 onos-uninstall
42 start mininet
43 git pull
44 mvn clean install
45 onos-package
46 onos-install -f
47 onos-wait-for-start
48 start cli sessions
49 start tcpdump
50 """
Jon Halle1a3b752015-07-22 13:02:46 -070051 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080052 import time
Jon Hall5cf14d52015-07-16 12:15:19 -070053 main.log.info( "ONOS HA Sanity test - initialization" )
54 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070055 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070056 "installing ONOS, starting Mininet and ONOS" +\
57 "cli sessions."
58 # TODO: save all the timers and output them for plotting
59
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -070071 # TODO: refactor how to get onos port, maybe put into component tag?
Jon Halle1a3b752015-07-22 13:02:46 -070072 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070073 global ONOS1Port
74 global ONOS2Port
75 global ONOS3Port
76 global ONOS4Port
77 global ONOS5Port
78 global ONOS6Port
79 global ONOS7Port
80
81 # FIXME: just get controller port from params?
82 # TODO: do we really need all these?
83 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
84 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
85 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
86 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
87 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
88 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
89 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
90
Jon Halle1a3b752015-07-22 13:02:46 -070091 try:
92 fileName = "Counters"
93 path = main.params[ 'imports' ][ 'path' ]
94 main.Counters = imp.load_source( fileName,
95 path + fileName + ".py" )
96 except Exception as e:
97 main.log.exception( e )
98 main.cleanup()
99 main.exit()
100
101 main.CLIs = []
102 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700103 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700104 for i in range( 1, main.numCtrls + 1 ):
105 try:
106 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
107 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
108 ipList.append( main.nodes[ -1 ].ip_address )
109 except AttributeError:
110 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700111
112 main.step( "Create cell file" )
113 cellAppString = main.params[ 'ENV' ][ 'appString' ]
114 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
115 main.Mininet1.ip_address,
116 cellAppString, ipList )
117 main.step( "Applying cell variable to environment" )
118 cellResult = main.ONOSbench.setCell( cellName )
119 verifyResult = main.ONOSbench.verifyCell()
120
121 # FIXME:this is short term fix
122 main.log.info( "Removing raft logs" )
123 main.ONOSbench.onosRemoveRaftLogs()
124
125 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700126 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700127 main.ONOSbench.onosUninstall( node.ip_address )
128
129 # Make sure ONOS is DEAD
130 main.log.info( "Killing any ONOS processes" )
131 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700132 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700133 killed = main.ONOSbench.onosKill( node.ip_address )
134 killResults = killResults and killed
135
136 cleanInstallResult = main.TRUE
137 gitPullResult = main.TRUE
138
139 main.step( "Starting Mininet" )
140 # scp topo file to mininet
141 # TODO: move to params?
142 topoName = "obelisk.py"
143 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700144 main.ONOSbench.scp( main.Mininet1,
145 filePath + topoName,
146 main.Mininet1.home,
147 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700148 mnResult = main.Mininet1.startNet( )
149 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
150 onpass="Mininet Started",
151 onfail="Error starting Mininet" )
152
153 main.step( "Git checkout and pull " + gitBranch )
154 if PULLCODE:
155 main.ONOSbench.gitCheckout( gitBranch )
156 gitPullResult = main.ONOSbench.gitPull()
157 # values of 1 or 3 are good
158 utilities.assert_lesser( expect=0, actual=gitPullResult,
159 onpass="Git pull successful",
160 onfail="Git pull failed" )
161 main.ONOSbench.getVersion( report=True )
162
163 main.step( "Using mvn clean install" )
164 cleanInstallResult = main.TRUE
165 if PULLCODE and gitPullResult == main.TRUE:
166 cleanInstallResult = main.ONOSbench.cleanInstall()
167 else:
168 main.log.warn( "Did not pull new code so skipping mvn " +
169 "clean install" )
170 utilities.assert_equals( expect=main.TRUE,
171 actual=cleanInstallResult,
172 onpass="MCI successful",
173 onfail="MCI failed" )
174 # GRAPHS
175 # NOTE: important params here:
176 # job = name of Jenkins job
177 # Plot Name = Plot-HA, only can be used if multiple plots
178 # index = The number of the graph under plot name
179 job = "HAsanity"
180 plotName = "Plot-HA"
Jon Hallff566d52016-01-15 14:45:36 -0800181 index = "1"
Jon Hall5cf14d52015-07-16 12:15:19 -0700182 graphs = '<ac:structured-macro ac:name="html">\n'
183 graphs += '<ac:plain-text-body><![CDATA[\n'
184 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800185 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700186 '&width=500&height=300"' +\
187 'noborder="0" width="500" height="300" scrolling="yes" ' +\
188 'seamless="seamless"></iframe>\n'
189 graphs += ']]></ac:plain-text-body>\n'
190 graphs += '</ac:structured-macro>\n'
191 main.log.wiki(graphs)
192
193 main.step( "Creating ONOS package" )
194 packageResult = main.ONOSbench.onosPackage()
195 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
196 onpass="ONOS package successful",
197 onfail="ONOS package failed" )
198
199 main.step( "Installing ONOS package" )
200 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700201 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700202 tmpResult = main.ONOSbench.onosInstall( options="-f",
203 node=node.ip_address )
204 onosInstallResult = onosInstallResult and tmpResult
205 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
206 onpass="ONOS install successful",
207 onfail="ONOS install failed" )
208
209 main.step( "Checking if ONOS is up yet" )
210 for i in range( 2 ):
211 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700212 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700213 started = main.ONOSbench.isup( node.ip_address )
214 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800215 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700216 onosIsupResult = onosIsupResult and started
217 if onosIsupResult == main.TRUE:
218 break
219 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
220 onpass="ONOS startup successful",
221 onfail="ONOS startup failed" )
222
223 main.log.step( "Starting ONOS CLI sessions" )
224 cliResults = main.TRUE
225 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700226 for i in range( main.numCtrls ):
227 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700228 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700229 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700230 threads.append( t )
231 t.start()
232
233 for t in threads:
234 t.join()
235 cliResults = cliResults and t.result
236 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
237 onpass="ONOS cli startup successful",
238 onfail="ONOS cli startup failed" )
239
240 if main.params[ 'tcpdump' ].lower() == "true":
241 main.step( "Start Packet Capture MN" )
242 main.Mininet2.startTcpdump(
243 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
244 + "-MN.pcap",
245 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
246 port=main.params[ 'MNtcpdump' ][ 'port' ] )
247
248 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800249 time.sleep(60)
Jon Hall5cf14d52015-07-16 12:15:19 -0700250 appCheck = main.TRUE
251 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700252 for i in range( main.numCtrls ):
253 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700254 name="appToIDCheck-" + str( i ),
255 args=[] )
256 threads.append( t )
257 t.start()
258
259 for t in threads:
260 t.join()
261 appCheck = appCheck and t.result
262 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700263 main.log.warn( main.CLIs[0].apps() )
264 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700265 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
266 onpass="App Ids seem to be correct",
267 onfail="Something is wrong with app Ids" )
268
269 if cliResults == main.FALSE:
270 main.log.error( "Failed to start ONOS, stopping test" )
271 main.cleanup()
272 main.exit()
273
274 def CASE2( self, main ):
275 """
276 Assign devices to controllers
277 """
278 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700279 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700280 assert main, "main not defined"
281 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700282 assert main.CLIs, "main.CLIs not defined"
283 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700284 assert ONOS1Port, "ONOS1Port not defined"
285 assert ONOS2Port, "ONOS2Port not defined"
286 assert ONOS3Port, "ONOS3Port not defined"
287 assert ONOS4Port, "ONOS4Port not defined"
288 assert ONOS5Port, "ONOS5Port not defined"
289 assert ONOS6Port, "ONOS6Port not defined"
290 assert ONOS7Port, "ONOS7Port not defined"
291
292 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700293 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700294 "and check that an ONOS node becomes the " +\
295 "master of the device."
296 main.step( "Assign switches to controllers" )
297
298 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700299 for i in range( main.numCtrls ):
300 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700301 swList = []
302 for i in range( 1, 29 ):
303 swList.append( "s" + str( i ) )
304 main.Mininet1.assignSwController( sw=swList, ip=ipList )
305
306 mastershipCheck = main.TRUE
307 for i in range( 1, 29 ):
308 response = main.Mininet1.getSwController( "s" + str( i ) )
309 try:
310 main.log.info( str( response ) )
311 except Exception:
312 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700313 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700314 if re.search( "tcp:" + node.ip_address, response ):
315 mastershipCheck = mastershipCheck and main.TRUE
316 else:
317 main.log.error( "Error, node " + node.ip_address + " is " +
318 "not in the list of controllers s" +
319 str( i ) + " is connecting to." )
320 mastershipCheck = main.FALSE
321 utilities.assert_equals(
322 expect=main.TRUE,
323 actual=mastershipCheck,
324 onpass="Switch mastership assigned correctly",
325 onfail="Switches not assigned correctly to controllers" )
326
327 def CASE21( self, main ):
328 """
329 Assign mastership to controllers
330 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700331 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700332 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700333 assert main, "main not defined"
334 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700335 assert main.CLIs, "main.CLIs not defined"
336 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700337 assert ONOS1Port, "ONOS1Port not defined"
338 assert ONOS2Port, "ONOS2Port not defined"
339 assert ONOS3Port, "ONOS3Port not defined"
340 assert ONOS4Port, "ONOS4Port not defined"
341 assert ONOS5Port, "ONOS5Port not defined"
342 assert ONOS6Port, "ONOS6Port not defined"
343 assert ONOS7Port, "ONOS7Port not defined"
344
345 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700346 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700347 "device. Then manually assign" +\
348 " mastership to specific ONOS nodes using" +\
349 " 'device-role'"
350 main.step( "Assign mastership of switches to specific controllers" )
351 # Manually assign mastership to the controller we want
352 roleCall = main.TRUE
353
354 ipList = [ ]
355 deviceList = []
356 try:
357 # Assign mastership to specific controllers. This assignment was
358 # determined for a 7 node cluser, but will work with any sized
359 # cluster
360 for i in range( 1, 29 ): # switches 1 through 28
361 # set up correct variables:
362 if i == 1:
363 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700364 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700365 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
366 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700367 c = 1 % main.numCtrls
368 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700369 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
370 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700371 c = 1 % main.numCtrls
372 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700373 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
374 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700375 c = 3 % main.numCtrls
376 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700377 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
378 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700379 c = 2 % main.numCtrls
380 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700381 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
382 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700383 c = 2 % main.numCtrls
384 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700385 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
386 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700387 c = 5 % main.numCtrls
388 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700389 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
390 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700391 c = 4 % main.numCtrls
392 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700393 dpid = '3' + str( i ).zfill( 3 )
394 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
395 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700396 c = 6 % main.numCtrls
397 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700398 dpid = '6' + str( i ).zfill( 3 )
399 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
400 elif i == 28:
401 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700402 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700403 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
404 else:
405 main.log.error( "You didn't write an else statement for " +
406 "switch s" + str( i ) )
407 roleCall = main.FALSE
408 # Assign switch
409 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
410 # TODO: make this controller dynamic
411 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
412 ip )
413 ipList.append( ip )
414 deviceList.append( deviceId )
415 except ( AttributeError, AssertionError ):
416 main.log.exception( "Something is wrong with ONOS device view" )
417 main.log.info( main.ONOScli1.devices() )
418 utilities.assert_equals(
419 expect=main.TRUE,
420 actual=roleCall,
421 onpass="Re-assigned switch mastership to designated controller",
422 onfail="Something wrong with deviceRole calls" )
423
424 main.step( "Check mastership was correctly assigned" )
425 roleCheck = main.TRUE
426 # NOTE: This is due to the fact that device mastership change is not
427 # atomic and is actually a multi step process
428 time.sleep( 5 )
429 for i in range( len( ipList ) ):
430 ip = ipList[i]
431 deviceId = deviceList[i]
432 # Check assignment
433 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
434 if ip in master:
435 roleCheck = roleCheck and main.TRUE
436 else:
437 roleCheck = roleCheck and main.FALSE
438 main.log.error( "Error, controller " + ip + " is not" +
439 " master " + "of device " +
440 str( deviceId ) + ". Master is " +
441 repr( master ) + "." )
442 utilities.assert_equals(
443 expect=main.TRUE,
444 actual=roleCheck,
445 onpass="Switches were successfully reassigned to designated " +
446 "controller",
447 onfail="Switches were not successfully reassigned" )
448
449 def CASE3( self, main ):
450 """
451 Assign intents
452 """
453 import time
454 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700455 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700456 assert main, "main not defined"
457 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700458 assert main.CLIs, "main.CLIs not defined"
459 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700460 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700461 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700462 "assign predetermined host-to-host intents." +\
463 " After installation, check that the intent" +\
464 " is distributed to all nodes and the state" +\
465 " is INSTALLED"
466
467 # install onos-app-fwd
468 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700469 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700470 utilities.assert_equals( expect=main.TRUE, actual=installResults,
471 onpass="Install fwd successful",
472 onfail="Install fwd failed" )
473
474 main.step( "Check app ids" )
475 appCheck = main.TRUE
476 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700477 for i in range( main.numCtrls ):
478 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700479 name="appToIDCheck-" + str( i ),
480 args=[] )
481 threads.append( t )
482 t.start()
483
484 for t in threads:
485 t.join()
486 appCheck = appCheck and t.result
487 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700488 main.log.warn( main.CLIs[0].apps() )
489 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700490 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
491 onpass="App Ids seem to be correct",
492 onfail="Something is wrong with app Ids" )
493
494 main.step( "Discovering Hosts( Via pingall for now )" )
495 # FIXME: Once we have a host discovery mechanism, use that instead
496 # REACTIVE FWD test
497 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700498 passMsg = "Reactive Pingall test passed"
499 time1 = time.time()
500 pingResult = main.Mininet1.pingall()
501 time2 = time.time()
502 if not pingResult:
503 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700504 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700505 passMsg += " on the second try"
506 utilities.assert_equals(
507 expect=main.TRUE,
508 actual=pingResult,
509 onpass= passMsg,
510 onfail="Reactive Pingall failed, " +
511 "one or more ping pairs failed" )
512 main.log.info( "Time for pingall: %2f seconds" %
513 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700514 # timeout for fwd flows
515 time.sleep( 11 )
516 # uninstall onos-app-fwd
517 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700518 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700519 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
520 onpass="Uninstall fwd successful",
521 onfail="Uninstall fwd failed" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700522
523 main.step( "Check app ids" )
524 threads = []
525 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700526 for i in range( main.numCtrls ):
527 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700528 name="appToIDCheck-" + str( i ),
529 args=[] )
530 threads.append( t )
531 t.start()
532
533 for t in threads:
534 t.join()
535 appCheck2 = appCheck2 and t.result
536 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700537 main.log.warn( main.CLIs[0].apps() )
538 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700539 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
540 onpass="App Ids seem to be correct",
541 onfail="Something is wrong with app Ids" )
542
543 main.step( "Add host intents via cli" )
544 intentIds = []
545 # TODO: move the host numbers to params
546 # Maybe look at all the paths we ping?
547 intentAddResult = True
548 hostResult = main.TRUE
549 for i in range( 8, 18 ):
550 main.log.info( "Adding host intent between h" + str( i ) +
551 " and h" + str( i + 10 ) )
552 host1 = "00:00:00:00:00:" + \
553 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
554 host2 = "00:00:00:00:00:" + \
555 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
556 # NOTE: getHost can return None
557 host1Dict = main.ONOScli1.getHost( host1 )
558 host2Dict = main.ONOScli1.getHost( host2 )
559 host1Id = None
560 host2Id = None
561 if host1Dict and host2Dict:
562 host1Id = host1Dict.get( 'id', None )
563 host2Id = host2Dict.get( 'id', None )
564 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700565 nodeNum = ( i % main.numCtrls )
566 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700567 if tmpId:
568 main.log.info( "Added intent with id: " + tmpId )
569 intentIds.append( tmpId )
570 else:
571 main.log.error( "addHostIntent returned: " +
572 repr( tmpId ) )
573 else:
574 main.log.error( "Error, getHost() failed for h" + str( i ) +
575 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700576 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700577 main.log.warn( "Hosts output: " )
578 try:
579 main.log.warn( json.dumps( json.loads( hosts ),
580 sort_keys=True,
581 indent=4,
582 separators=( ',', ': ' ) ) )
583 except ( ValueError, TypeError ):
584 main.log.warn( repr( hosts ) )
585 hostResult = main.FALSE
586 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
587 onpass="Found a host id for each host",
588 onfail="Error looking up host ids" )
589
590 intentStart = time.time()
591 onosIds = main.ONOScli1.getAllIntentsId()
592 main.log.info( "Submitted intents: " + str( intentIds ) )
593 main.log.info( "Intents in ONOS: " + str( onosIds ) )
594 for intent in intentIds:
595 if intent in onosIds:
596 pass # intent submitted is in onos
597 else:
598 intentAddResult = False
599 if intentAddResult:
600 intentStop = time.time()
601 else:
602 intentStop = None
603 # Print the intent states
604 intents = main.ONOScli1.intents()
605 intentStates = []
606 installedCheck = True
607 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
608 count = 0
609 try:
610 for intent in json.loads( intents ):
611 state = intent.get( 'state', None )
612 if "INSTALLED" not in state:
613 installedCheck = False
614 intentId = intent.get( 'id', None )
615 intentStates.append( ( intentId, state ) )
616 except ( ValueError, TypeError ):
617 main.log.exception( "Error parsing intents" )
618 # add submitted intents not in the store
619 tmplist = [ i for i, s in intentStates ]
620 missingIntents = False
621 for i in intentIds:
622 if i not in tmplist:
623 intentStates.append( ( i, " - " ) )
624 missingIntents = True
625 intentStates.sort()
626 for i, s in intentStates:
627 count += 1
628 main.log.info( "%-6s%-15s%-15s" %
629 ( str( count ), str( i ), str( s ) ) )
630 leaders = main.ONOScli1.leaders()
631 try:
632 missing = False
633 if leaders:
634 parsedLeaders = json.loads( leaders )
635 main.log.warn( json.dumps( parsedLeaders,
636 sort_keys=True,
637 indent=4,
638 separators=( ',', ': ' ) ) )
639 # check for all intent partitions
640 topics = []
641 for i in range( 14 ):
642 topics.append( "intent-partition-" + str( i ) )
643 main.log.debug( topics )
644 ONOStopics = [ j['topic'] for j in parsedLeaders ]
645 for topic in topics:
646 if topic not in ONOStopics:
647 main.log.error( "Error: " + topic +
648 " not in leaders" )
649 missing = True
650 else:
651 main.log.error( "leaders() returned None" )
652 except ( ValueError, TypeError ):
653 main.log.exception( "Error parsing leaders" )
654 main.log.error( repr( leaders ) )
655 # Check all nodes
656 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700657 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700658 response = node.leaders( jsonFormat=False)
659 main.log.warn( str( node.name ) + " leaders output: \n" +
660 str( response ) )
661
662 partitions = main.ONOScli1.partitions()
663 try:
664 if partitions :
665 parsedPartitions = json.loads( partitions )
666 main.log.warn( json.dumps( parsedPartitions,
667 sort_keys=True,
668 indent=4,
669 separators=( ',', ': ' ) ) )
670 # TODO check for a leader in all paritions
671 # TODO check for consistency among nodes
672 else:
673 main.log.error( "partitions() returned None" )
674 except ( ValueError, TypeError ):
675 main.log.exception( "Error parsing partitions" )
676 main.log.error( repr( partitions ) )
677 pendingMap = main.ONOScli1.pendingMap()
678 try:
679 if pendingMap :
680 parsedPending = json.loads( pendingMap )
681 main.log.warn( json.dumps( parsedPending,
682 sort_keys=True,
683 indent=4,
684 separators=( ',', ': ' ) ) )
685 # TODO check something here?
686 else:
687 main.log.error( "pendingMap() returned None" )
688 except ( ValueError, TypeError ):
689 main.log.exception( "Error parsing pending map" )
690 main.log.error( repr( pendingMap ) )
691
692 intentAddResult = bool( intentAddResult and not missingIntents and
693 installedCheck )
694 if not intentAddResult:
695 main.log.error( "Error in pushing host intents to ONOS" )
696
697 main.step( "Intent Anti-Entropy dispersion" )
698 for i in range(100):
699 correct = True
700 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700701 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700702 onosIds = []
703 ids = cli.getAllIntentsId()
704 onosIds.append( ids )
705 main.log.debug( "Intents in " + cli.name + ": " +
706 str( sorted( onosIds ) ) )
707 if sorted( ids ) != sorted( intentIds ):
708 main.log.warn( "Set of intent IDs doesn't match" )
709 correct = False
710 break
711 else:
712 intents = json.loads( cli.intents() )
713 for intent in intents:
714 if intent[ 'state' ] != "INSTALLED":
715 main.log.warn( "Intent " + intent[ 'id' ] +
716 " is " + intent[ 'state' ] )
717 correct = False
718 break
719 if correct:
720 break
721 else:
722 time.sleep(1)
723 if not intentStop:
724 intentStop = time.time()
725 global gossipTime
726 gossipTime = intentStop - intentStart
727 main.log.info( "It took about " + str( gossipTime ) +
728 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700729 gossipPeriod = int( main.params['timers']['gossip'] )
730 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700731 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700732 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700733 onpass="ECM anti-entropy for intents worked within " +
734 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700735 onfail="Intent ECM anti-entropy took too long. " +
736 "Expected time:{}, Actual time:{}".format( maxGossipTime,
737 gossipTime ) )
738 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700739 intentAddResult = True
740
741 if not intentAddResult or "key" in pendingMap:
742 import time
743 installedCheck = True
744 main.log.info( "Sleeping 60 seconds to see if intents are found" )
745 time.sleep( 60 )
746 onosIds = main.ONOScli1.getAllIntentsId()
747 main.log.info( "Submitted intents: " + str( intentIds ) )
748 main.log.info( "Intents in ONOS: " + str( onosIds ) )
749 # Print the intent states
750 intents = main.ONOScli1.intents()
751 intentStates = []
752 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
753 count = 0
754 try:
755 for intent in json.loads( intents ):
756 # Iter through intents of a node
757 state = intent.get( 'state', None )
758 if "INSTALLED" not in state:
759 installedCheck = False
760 intentId = intent.get( 'id', None )
761 intentStates.append( ( intentId, state ) )
762 except ( ValueError, TypeError ):
763 main.log.exception( "Error parsing intents" )
764 # add submitted intents not in the store
765 tmplist = [ i for i, s in intentStates ]
766 for i in intentIds:
767 if i not in tmplist:
768 intentStates.append( ( i, " - " ) )
769 intentStates.sort()
770 for i, s in intentStates:
771 count += 1
772 main.log.info( "%-6s%-15s%-15s" %
773 ( str( count ), str( i ), str( s ) ) )
774 leaders = main.ONOScli1.leaders()
775 try:
776 missing = False
777 if leaders:
778 parsedLeaders = json.loads( leaders )
779 main.log.warn( json.dumps( parsedLeaders,
780 sort_keys=True,
781 indent=4,
782 separators=( ',', ': ' ) ) )
783 # check for all intent partitions
784 # check for election
785 topics = []
786 for i in range( 14 ):
787 topics.append( "intent-partition-" + str( i ) )
788 # FIXME: this should only be after we start the app
789 topics.append( "org.onosproject.election" )
790 main.log.debug( topics )
791 ONOStopics = [ j['topic'] for j in parsedLeaders ]
792 for topic in topics:
793 if topic not in ONOStopics:
794 main.log.error( "Error: " + topic +
795 " not in leaders" )
796 missing = True
797 else:
798 main.log.error( "leaders() returned None" )
799 except ( ValueError, TypeError ):
800 main.log.exception( "Error parsing leaders" )
801 main.log.error( repr( leaders ) )
802 # Check all nodes
803 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700804 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700805 response = node.leaders( jsonFormat=False)
806 main.log.warn( str( node.name ) + " leaders output: \n" +
807 str( response ) )
808
809 partitions = main.ONOScli1.partitions()
810 try:
811 if partitions :
812 parsedPartitions = json.loads( partitions )
813 main.log.warn( json.dumps( parsedPartitions,
814 sort_keys=True,
815 indent=4,
816 separators=( ',', ': ' ) ) )
817 # TODO check for a leader in all paritions
818 # TODO check for consistency among nodes
819 else:
820 main.log.error( "partitions() returned None" )
821 except ( ValueError, TypeError ):
822 main.log.exception( "Error parsing partitions" )
823 main.log.error( repr( partitions ) )
824 pendingMap = main.ONOScli1.pendingMap()
825 try:
826 if pendingMap :
827 parsedPending = json.loads( pendingMap )
828 main.log.warn( json.dumps( parsedPending,
829 sort_keys=True,
830 indent=4,
831 separators=( ',', ': ' ) ) )
832 # TODO check something here?
833 else:
834 main.log.error( "pendingMap() returned None" )
835 except ( ValueError, TypeError ):
836 main.log.exception( "Error parsing pending map" )
837 main.log.error( repr( pendingMap ) )
838
839 def CASE4( self, main ):
840 """
841 Ping across added host intents
842 """
843 import json
844 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700845 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700846 assert main, "main not defined"
847 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700848 assert main.CLIs, "main.CLIs not defined"
849 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700850 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700851 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700852 "functionality and check the state of " +\
853 "the intent"
854 main.step( "Ping across added host intents" )
855 PingResult = main.TRUE
856 for i in range( 8, 18 ):
857 ping = main.Mininet1.pingHost( src="h" + str( i ),
858 target="h" + str( i + 10 ) )
859 PingResult = PingResult and ping
860 if ping == main.FALSE:
861 main.log.warn( "Ping failed between h" + str( i ) +
862 " and h" + str( i + 10 ) )
863 elif ping == main.TRUE:
864 main.log.info( "Ping test passed!" )
865 # Don't set PingResult or you'd override failures
866 if PingResult == main.FALSE:
867 main.log.error(
868 "Intents have not been installed correctly, pings failed." )
869 # TODO: pretty print
870 main.log.warn( "ONOS1 intents: " )
871 try:
872 tmpIntents = main.ONOScli1.intents()
873 main.log.warn( json.dumps( json.loads( tmpIntents ),
874 sort_keys=True,
875 indent=4,
876 separators=( ',', ': ' ) ) )
877 except ( ValueError, TypeError ):
878 main.log.warn( repr( tmpIntents ) )
879 utilities.assert_equals(
880 expect=main.TRUE,
881 actual=PingResult,
882 onpass="Intents have been installed correctly and pings work",
883 onfail="Intents have not been installed correctly, pings failed." )
884
885 main.step( "Check Intent state" )
886 installedCheck = False
887 loopCount = 0
888 while not installedCheck and loopCount < 40:
889 installedCheck = True
890 # Print the intent states
891 intents = main.ONOScli1.intents()
892 intentStates = []
893 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
894 count = 0
895 # Iter through intents of a node
896 try:
897 for intent in json.loads( intents ):
898 state = intent.get( 'state', None )
899 if "INSTALLED" not in state:
900 installedCheck = False
901 intentId = intent.get( 'id', None )
902 intentStates.append( ( intentId, state ) )
903 except ( ValueError, TypeError ):
904 main.log.exception( "Error parsing intents." )
905 # Print states
906 intentStates.sort()
907 for i, s in intentStates:
908 count += 1
909 main.log.info( "%-6s%-15s%-15s" %
910 ( str( count ), str( i ), str( s ) ) )
911 if not installedCheck:
912 time.sleep( 1 )
913 loopCount += 1
914 utilities.assert_equals( expect=True, actual=installedCheck,
915 onpass="Intents are all INSTALLED",
916 onfail="Intents are not all in " +
917 "INSTALLED state" )
918
919 main.step( "Check leadership of topics" )
920 leaders = main.ONOScli1.leaders()
921 topicCheck = main.TRUE
922 try:
923 if leaders:
924 parsedLeaders = json.loads( leaders )
925 main.log.warn( json.dumps( parsedLeaders,
926 sort_keys=True,
927 indent=4,
928 separators=( ',', ': ' ) ) )
929 # check for all intent partitions
930 # check for election
931 # TODO: Look at Devices as topics now that it uses this system
932 topics = []
933 for i in range( 14 ):
934 topics.append( "intent-partition-" + str( i ) )
935 # FIXME: this should only be after we start the app
936 # FIXME: topics.append( "org.onosproject.election" )
937 # Print leaders output
938 main.log.debug( topics )
939 ONOStopics = [ j['topic'] for j in parsedLeaders ]
940 for topic in topics:
941 if topic not in ONOStopics:
942 main.log.error( "Error: " + topic +
943 " not in leaders" )
944 topicCheck = main.FALSE
945 else:
946 main.log.error( "leaders() returned None" )
947 topicCheck = main.FALSE
948 except ( ValueError, TypeError ):
949 topicCheck = main.FALSE
950 main.log.exception( "Error parsing leaders" )
951 main.log.error( repr( leaders ) )
952 # TODO: Check for a leader of these topics
953 # Check all nodes
954 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700955 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700956 response = node.leaders( jsonFormat=False)
957 main.log.warn( str( node.name ) + " leaders output: \n" +
958 str( response ) )
959
960 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
961 onpass="intent Partitions is in leaders",
962 onfail="Some topics were lost " )
963 # Print partitions
964 partitions = main.ONOScli1.partitions()
965 try:
966 if partitions :
967 parsedPartitions = json.loads( partitions )
968 main.log.warn( json.dumps( parsedPartitions,
969 sort_keys=True,
970 indent=4,
971 separators=( ',', ': ' ) ) )
972 # TODO check for a leader in all paritions
973 # TODO check for consistency among nodes
974 else:
975 main.log.error( "partitions() returned None" )
976 except ( ValueError, TypeError ):
977 main.log.exception( "Error parsing partitions" )
978 main.log.error( repr( partitions ) )
979 # Print Pending Map
980 pendingMap = main.ONOScli1.pendingMap()
981 try:
982 if pendingMap :
983 parsedPending = json.loads( pendingMap )
984 main.log.warn( json.dumps( parsedPending,
985 sort_keys=True,
986 indent=4,
987 separators=( ',', ': ' ) ) )
988 # TODO check something here?
989 else:
990 main.log.error( "pendingMap() returned None" )
991 except ( ValueError, TypeError ):
992 main.log.exception( "Error parsing pending map" )
993 main.log.error( repr( pendingMap ) )
994
995 if not installedCheck:
996 main.log.info( "Waiting 60 seconds to see if the state of " +
997 "intents change" )
998 time.sleep( 60 )
999 # Print the intent states
1000 intents = main.ONOScli1.intents()
1001 intentStates = []
1002 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1003 count = 0
1004 # Iter through intents of a node
1005 try:
1006 for intent in json.loads( intents ):
1007 state = intent.get( 'state', None )
1008 if "INSTALLED" not in state:
1009 installedCheck = False
1010 intentId = intent.get( 'id', None )
1011 intentStates.append( ( intentId, state ) )
1012 except ( ValueError, TypeError ):
1013 main.log.exception( "Error parsing intents." )
1014 intentStates.sort()
1015 for i, s in intentStates:
1016 count += 1
1017 main.log.info( "%-6s%-15s%-15s" %
1018 ( str( count ), str( i ), str( s ) ) )
1019 leaders = main.ONOScli1.leaders()
1020 try:
1021 missing = False
1022 if leaders:
1023 parsedLeaders = json.loads( leaders )
1024 main.log.warn( json.dumps( parsedLeaders,
1025 sort_keys=True,
1026 indent=4,
1027 separators=( ',', ': ' ) ) )
1028 # check for all intent partitions
1029 # check for election
1030 topics = []
1031 for i in range( 14 ):
1032 topics.append( "intent-partition-" + str( i ) )
1033 # FIXME: this should only be after we start the app
1034 topics.append( "org.onosproject.election" )
1035 main.log.debug( topics )
1036 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1037 for topic in topics:
1038 if topic not in ONOStopics:
1039 main.log.error( "Error: " + topic +
1040 " not in leaders" )
1041 missing = True
1042 else:
1043 main.log.error( "leaders() returned None" )
1044 except ( ValueError, TypeError ):
1045 main.log.exception( "Error parsing leaders" )
1046 main.log.error( repr( leaders ) )
1047 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001048 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001049 response = node.leaders( jsonFormat=False)
1050 main.log.warn( str( node.name ) + " leaders output: \n" +
1051 str( response ) )
1052
1053 partitions = main.ONOScli1.partitions()
1054 try:
1055 if partitions :
1056 parsedPartitions = json.loads( partitions )
1057 main.log.warn( json.dumps( parsedPartitions,
1058 sort_keys=True,
1059 indent=4,
1060 separators=( ',', ': ' ) ) )
1061 # TODO check for a leader in all paritions
1062 # TODO check for consistency among nodes
1063 else:
1064 main.log.error( "partitions() returned None" )
1065 except ( ValueError, TypeError ):
1066 main.log.exception( "Error parsing partitions" )
1067 main.log.error( repr( partitions ) )
1068 pendingMap = main.ONOScli1.pendingMap()
1069 try:
1070 if pendingMap :
1071 parsedPending = json.loads( pendingMap )
1072 main.log.warn( json.dumps( parsedPending,
1073 sort_keys=True,
1074 indent=4,
1075 separators=( ',', ': ' ) ) )
1076 # TODO check something here?
1077 else:
1078 main.log.error( "pendingMap() returned None" )
1079 except ( ValueError, TypeError ):
1080 main.log.exception( "Error parsing pending map" )
1081 main.log.error( repr( pendingMap ) )
1082 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001083 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001084 main.step( "Wait a minute then ping again" )
1085 # the wait is above
1086 PingResult = main.TRUE
1087 for i in range( 8, 18 ):
1088 ping = main.Mininet1.pingHost( src="h" + str( i ),
1089 target="h" + str( i + 10 ) )
1090 PingResult = PingResult and ping
1091 if ping == main.FALSE:
1092 main.log.warn( "Ping failed between h" + str( i ) +
1093 " and h" + str( i + 10 ) )
1094 elif ping == main.TRUE:
1095 main.log.info( "Ping test passed!" )
1096 # Don't set PingResult or you'd override failures
1097 if PingResult == main.FALSE:
1098 main.log.error(
1099 "Intents have not been installed correctly, pings failed." )
1100 # TODO: pretty print
1101 main.log.warn( "ONOS1 intents: " )
1102 try:
1103 tmpIntents = main.ONOScli1.intents()
1104 main.log.warn( json.dumps( json.loads( tmpIntents ),
1105 sort_keys=True,
1106 indent=4,
1107 separators=( ',', ': ' ) ) )
1108 except ( ValueError, TypeError ):
1109 main.log.warn( repr( tmpIntents ) )
1110 utilities.assert_equals(
1111 expect=main.TRUE,
1112 actual=PingResult,
1113 onpass="Intents have been installed correctly and pings work",
1114 onfail="Intents have not been installed correctly, pings failed." )
1115
1116 def CASE5( self, main ):
1117 """
1118 Reading state of ONOS
1119 """
1120 import json
1121 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001122 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001123 assert main, "main not defined"
1124 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001125 assert main.CLIs, "main.CLIs not defined"
1126 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001127
1128 main.case( "Setting up and gathering data for current state" )
1129 # The general idea for this test case is to pull the state of
1130 # ( intents,flows, topology,... ) from each ONOS node
1131 # We can then compare them with each other and also with past states
1132
1133 main.step( "Check that each switch has a master" )
1134 global mastershipState
1135 mastershipState = '[]'
1136
1137 # Assert that each device has a master
1138 rolesNotNull = main.TRUE
1139 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001140 for i in range( main.numCtrls ):
1141 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001142 name="rolesNotNull-" + str( i ),
1143 args=[] )
1144 threads.append( t )
1145 t.start()
1146
1147 for t in threads:
1148 t.join()
1149 rolesNotNull = rolesNotNull and t.result
1150 utilities.assert_equals(
1151 expect=main.TRUE,
1152 actual=rolesNotNull,
1153 onpass="Each device has a master",
1154 onfail="Some devices don't have a master assigned" )
1155
1156 main.step( "Get the Mastership of each switch from each controller" )
1157 ONOSMastership = []
1158 mastershipCheck = main.FALSE
1159 consistentMastership = True
1160 rolesResults = True
1161 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001162 for i in range( main.numCtrls ):
1163 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001164 name="roles-" + str( i ),
1165 args=[] )
1166 threads.append( t )
1167 t.start()
1168
1169 for t in threads:
1170 t.join()
1171 ONOSMastership.append( t.result )
1172
Jon Halle1a3b752015-07-22 13:02:46 -07001173 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001174 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1175 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1176 " roles" )
1177 main.log.warn(
1178 "ONOS" + str( i + 1 ) + " mastership response: " +
1179 repr( ONOSMastership[i] ) )
1180 rolesResults = False
1181 utilities.assert_equals(
1182 expect=True,
1183 actual=rolesResults,
1184 onpass="No error in reading roles output",
1185 onfail="Error in reading roles from ONOS" )
1186
1187 main.step( "Check for consistency in roles from each controller" )
1188 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1189 main.log.info(
1190 "Switch roles are consistent across all ONOS nodes" )
1191 else:
1192 consistentMastership = False
1193 utilities.assert_equals(
1194 expect=True,
1195 actual=consistentMastership,
1196 onpass="Switch roles are consistent across all ONOS nodes",
1197 onfail="ONOS nodes have different views of switch roles" )
1198
1199 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001200 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001201 try:
1202 main.log.warn(
1203 "ONOS" + str( i + 1 ) + " roles: ",
1204 json.dumps(
1205 json.loads( ONOSMastership[ i ] ),
1206 sort_keys=True,
1207 indent=4,
1208 separators=( ',', ': ' ) ) )
1209 except ( ValueError, TypeError ):
1210 main.log.warn( repr( ONOSMastership[ i ] ) )
1211 elif rolesResults and consistentMastership:
1212 mastershipCheck = main.TRUE
1213 mastershipState = ONOSMastership[ 0 ]
1214
1215 main.step( "Get the intents from each controller" )
1216 global intentState
1217 intentState = []
1218 ONOSIntents = []
1219 intentCheck = main.FALSE
1220 consistentIntents = True
1221 intentsResults = True
1222 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001223 for i in range( main.numCtrls ):
1224 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001225 name="intents-" + str( i ),
1226 args=[],
1227 kwargs={ 'jsonFormat': True } )
1228 threads.append( t )
1229 t.start()
1230
1231 for t in threads:
1232 t.join()
1233 ONOSIntents.append( t.result )
1234
Jon Halle1a3b752015-07-22 13:02:46 -07001235 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001236 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1237 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1238 " intents" )
1239 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1240 repr( ONOSIntents[ i ] ) )
1241 intentsResults = False
1242 utilities.assert_equals(
1243 expect=True,
1244 actual=intentsResults,
1245 onpass="No error in reading intents output",
1246 onfail="Error in reading intents from ONOS" )
1247
1248 main.step( "Check for consistency in Intents from each controller" )
1249 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1250 main.log.info( "Intents are consistent across all ONOS " +
1251 "nodes" )
1252 else:
1253 consistentIntents = False
1254 main.log.error( "Intents not consistent" )
1255 utilities.assert_equals(
1256 expect=True,
1257 actual=consistentIntents,
1258 onpass="Intents are consistent across all ONOS nodes",
1259 onfail="ONOS nodes have different views of intents" )
1260
1261 if intentsResults:
1262 # Try to make it easy to figure out what is happening
1263 #
1264 # Intent ONOS1 ONOS2 ...
1265 # 0x01 INSTALLED INSTALLING
1266 # ... ... ...
1267 # ... ... ...
1268 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001269 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001270 title += " " * 10 + "ONOS" + str( n + 1 )
1271 main.log.warn( title )
Jon Halle1a3b752015-07-22 13:02:46 -07001272 # get all intent keys in the cluster
Jon Hall5cf14d52015-07-16 12:15:19 -07001273 keys = []
1274 try:
1275 # Get the set of all intent keys
1276 for nodeStr in ONOSIntents:
1277 node = json.loads( nodeStr )
1278 for intent in node:
1279 keys.append( intent.get( 'id' ) )
1280 keys = set( keys )
1281 # For each intent key, print the state on each node
1282 for key in keys:
1283 row = "%-13s" % key
1284 for nodeStr in ONOSIntents:
1285 node = json.loads( nodeStr )
1286 for intent in node:
1287 if intent.get( 'id', "Error" ) == key:
1288 row += "%-15s" % intent.get( 'state' )
1289 main.log.warn( row )
1290 # End of intent state table
1291 except ValueError as e:
1292 main.log.exception( e )
1293 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
1294
1295 if intentsResults and not consistentIntents:
1296 # print the json objects
1297 n = len(ONOSIntents)
1298 main.log.debug( "ONOS" + str( n ) + " intents: " )
1299 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1300 sort_keys=True,
1301 indent=4,
1302 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001303 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001304 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1305 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1306 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1307 sort_keys=True,
1308 indent=4,
1309 separators=( ',', ': ' ) ) )
1310 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001311 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001312 str( n ) + " intents" )
1313 elif intentsResults and consistentIntents:
1314 intentCheck = main.TRUE
1315 intentState = ONOSIntents[ 0 ]
1316
1317 main.step( "Get the flows from each controller" )
1318 global flowState
1319 flowState = []
1320 ONOSFlows = []
1321 ONOSFlowsJson = []
1322 flowCheck = main.FALSE
1323 consistentFlows = True
1324 flowsResults = True
1325 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001326 for i in range( main.numCtrls ):
1327 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001328 name="flows-" + str( i ),
1329 args=[],
1330 kwargs={ 'jsonFormat': True } )
1331 threads.append( t )
1332 t.start()
1333
1334 # NOTE: Flows command can take some time to run
1335 time.sleep(30)
1336 for t in threads:
1337 t.join()
1338 result = t.result
1339 ONOSFlows.append( result )
1340
Jon Halle1a3b752015-07-22 13:02:46 -07001341 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001342 num = str( i + 1 )
1343 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1344 main.log.error( "Error in getting ONOS" + num + " flows" )
1345 main.log.warn( "ONOS" + num + " flows response: " +
1346 repr( ONOSFlows[ i ] ) )
1347 flowsResults = False
1348 ONOSFlowsJson.append( None )
1349 else:
1350 try:
1351 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1352 except ( ValueError, TypeError ):
1353 # FIXME: change this to log.error?
1354 main.log.exception( "Error in parsing ONOS" + num +
1355 " response as json." )
1356 main.log.error( repr( ONOSFlows[ i ] ) )
1357 ONOSFlowsJson.append( None )
1358 flowsResults = False
1359 utilities.assert_equals(
1360 expect=True,
1361 actual=flowsResults,
1362 onpass="No error in reading flows output",
1363 onfail="Error in reading flows from ONOS" )
1364
1365 main.step( "Check for consistency in Flows from each controller" )
1366 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1367 if all( tmp ):
1368 main.log.info( "Flow count is consistent across all ONOS nodes" )
1369 else:
1370 consistentFlows = False
1371 utilities.assert_equals(
1372 expect=True,
1373 actual=consistentFlows,
1374 onpass="The flow count is consistent across all ONOS nodes",
1375 onfail="ONOS nodes have different flow counts" )
1376
1377 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001378 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001379 try:
1380 main.log.warn(
1381 "ONOS" + str( i + 1 ) + " flows: " +
1382 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1383 indent=4, separators=( ',', ': ' ) ) )
1384 except ( ValueError, TypeError ):
1385 main.log.warn(
1386 "ONOS" + str( i + 1 ) + " flows: " +
1387 repr( ONOSFlows[ i ] ) )
1388 elif flowsResults and consistentFlows:
1389 flowCheck = main.TRUE
1390 flowState = ONOSFlows[ 0 ]
1391
1392 main.step( "Get the OF Table entries" )
1393 global flows
1394 flows = []
1395 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001396 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001397 if flowCheck == main.FALSE:
1398 for table in flows:
1399 main.log.warn( table )
GlennRC68467eb2015-11-16 18:01:01 -08001400
Jon Hall5cf14d52015-07-16 12:15:19 -07001401 # TODO: Compare switch flow tables with ONOS flow tables
1402
1403 main.step( "Start continuous pings" )
1404 main.Mininet2.pingLong(
1405 src=main.params[ 'PING' ][ 'source1' ],
1406 target=main.params[ 'PING' ][ 'target1' ],
1407 pingTime=500 )
1408 main.Mininet2.pingLong(
1409 src=main.params[ 'PING' ][ 'source2' ],
1410 target=main.params[ 'PING' ][ 'target2' ],
1411 pingTime=500 )
1412 main.Mininet2.pingLong(
1413 src=main.params[ 'PING' ][ 'source3' ],
1414 target=main.params[ 'PING' ][ 'target3' ],
1415 pingTime=500 )
1416 main.Mininet2.pingLong(
1417 src=main.params[ 'PING' ][ 'source4' ],
1418 target=main.params[ 'PING' ][ 'target4' ],
1419 pingTime=500 )
1420 main.Mininet2.pingLong(
1421 src=main.params[ 'PING' ][ 'source5' ],
1422 target=main.params[ 'PING' ][ 'target5' ],
1423 pingTime=500 )
1424 main.Mininet2.pingLong(
1425 src=main.params[ 'PING' ][ 'source6' ],
1426 target=main.params[ 'PING' ][ 'target6' ],
1427 pingTime=500 )
1428 main.Mininet2.pingLong(
1429 src=main.params[ 'PING' ][ 'source7' ],
1430 target=main.params[ 'PING' ][ 'target7' ],
1431 pingTime=500 )
1432 main.Mininet2.pingLong(
1433 src=main.params[ 'PING' ][ 'source8' ],
1434 target=main.params[ 'PING' ][ 'target8' ],
1435 pingTime=500 )
1436 main.Mininet2.pingLong(
1437 src=main.params[ 'PING' ][ 'source9' ],
1438 target=main.params[ 'PING' ][ 'target9' ],
1439 pingTime=500 )
1440 main.Mininet2.pingLong(
1441 src=main.params[ 'PING' ][ 'source10' ],
1442 target=main.params[ 'PING' ][ 'target10' ],
1443 pingTime=500 )
1444
1445 main.step( "Collecting topology information from ONOS" )
1446 devices = []
1447 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001448 for i in range( main.numCtrls ):
1449 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001450 name="devices-" + str( i ),
1451 args=[ ] )
1452 threads.append( t )
1453 t.start()
1454
1455 for t in threads:
1456 t.join()
1457 devices.append( t.result )
1458 hosts = []
1459 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001460 for i in range( main.numCtrls ):
1461 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001462 name="hosts-" + str( i ),
1463 args=[ ] )
1464 threads.append( t )
1465 t.start()
1466
1467 for t in threads:
1468 t.join()
1469 try:
1470 hosts.append( json.loads( t.result ) )
1471 except ( ValueError, TypeError ):
1472 # FIXME: better handling of this, print which node
1473 # Maybe use thread name?
1474 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001475 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001476 hosts.append( None )
1477
1478 ports = []
1479 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001480 for i in range( main.numCtrls ):
1481 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001482 name="ports-" + str( i ),
1483 args=[ ] )
1484 threads.append( t )
1485 t.start()
1486
1487 for t in threads:
1488 t.join()
1489 ports.append( t.result )
1490 links = []
1491 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001492 for i in range( main.numCtrls ):
1493 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001494 name="links-" + str( i ),
1495 args=[ ] )
1496 threads.append( t )
1497 t.start()
1498
1499 for t in threads:
1500 t.join()
1501 links.append( t.result )
1502 clusters = []
1503 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001504 for i in range( main.numCtrls ):
1505 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001506 name="clusters-" + str( i ),
1507 args=[ ] )
1508 threads.append( t )
1509 t.start()
1510
1511 for t in threads:
1512 t.join()
1513 clusters.append( t.result )
1514 # Compare json objects for hosts and dataplane clusters
1515
1516 # hosts
1517 main.step( "Host view is consistent across ONOS nodes" )
1518 consistentHostsResult = main.TRUE
1519 for controller in range( len( hosts ) ):
1520 controllerStr = str( controller + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001521 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001522 if hosts[ controller ] == hosts[ 0 ]:
1523 continue
1524 else: # hosts not consistent
1525 main.log.error( "hosts from ONOS" +
1526 controllerStr +
1527 " is inconsistent with ONOS1" )
1528 main.log.warn( repr( hosts[ controller ] ) )
1529 consistentHostsResult = main.FALSE
1530
1531 else:
1532 main.log.error( "Error in getting ONOS hosts from ONOS" +
1533 controllerStr )
1534 consistentHostsResult = main.FALSE
1535 main.log.warn( "ONOS" + controllerStr +
1536 " hosts response: " +
1537 repr( hosts[ controller ] ) )
1538 utilities.assert_equals(
1539 expect=main.TRUE,
1540 actual=consistentHostsResult,
1541 onpass="Hosts view is consistent across all ONOS nodes",
1542 onfail="ONOS nodes have different views of hosts" )
1543
1544 main.step( "Each host has an IP address" )
1545 ipResult = main.TRUE
1546 for controller in range( 0, len( hosts ) ):
1547 controllerStr = str( controller + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001548 if hosts[ controller ]:
1549 for host in hosts[ controller ]:
1550 if not host.get( 'ipAddresses', [ ] ):
1551 main.log.error( "Error with host ips on controller" +
1552 controllerStr + ": " + str( host ) )
1553 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001554 utilities.assert_equals(
1555 expect=main.TRUE,
1556 actual=ipResult,
1557 onpass="The ips of the hosts aren't empty",
1558 onfail="The ip of at least one host is missing" )
1559
1560 # Strongly connected clusters of devices
1561 main.step( "Cluster view is consistent across ONOS nodes" )
1562 consistentClustersResult = main.TRUE
1563 for controller in range( len( clusters ) ):
1564 controllerStr = str( controller + 1 )
1565 if "Error" not in clusters[ controller ]:
1566 if clusters[ controller ] == clusters[ 0 ]:
1567 continue
1568 else: # clusters not consistent
1569 main.log.error( "clusters from ONOS" + controllerStr +
1570 " is inconsistent with ONOS1" )
1571 consistentClustersResult = main.FALSE
1572
1573 else:
1574 main.log.error( "Error in getting dataplane clusters " +
1575 "from ONOS" + controllerStr )
1576 consistentClustersResult = main.FALSE
1577 main.log.warn( "ONOS" + controllerStr +
1578 " clusters response: " +
1579 repr( clusters[ controller ] ) )
1580 utilities.assert_equals(
1581 expect=main.TRUE,
1582 actual=consistentClustersResult,
1583 onpass="Clusters view is consistent across all ONOS nodes",
1584 onfail="ONOS nodes have different views of clusters" )
1585 # there should always only be one cluster
1586 main.step( "Cluster view correct across ONOS nodes" )
1587 try:
1588 numClusters = len( json.loads( clusters[ 0 ] ) )
1589 except ( ValueError, TypeError ):
1590 main.log.exception( "Error parsing clusters[0]: " +
1591 repr( clusters[ 0 ] ) )
1592 clusterResults = main.FALSE
1593 if numClusters == 1:
1594 clusterResults = main.TRUE
1595 utilities.assert_equals(
1596 expect=1,
1597 actual=numClusters,
1598 onpass="ONOS shows 1 SCC",
1599 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1600
1601 main.step( "Comparing ONOS topology to MN" )
1602 devicesResults = main.TRUE
1603 linksResults = main.TRUE
1604 hostsResults = main.TRUE
1605 mnSwitches = main.Mininet1.getSwitches()
1606 mnLinks = main.Mininet1.getLinks()
1607 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001608 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001609 controllerStr = str( controller + 1 )
1610 if devices[ controller ] and ports[ controller ] and\
1611 "Error" not in devices[ controller ] and\
1612 "Error" not in ports[ controller ]:
1613
1614 currentDevicesResult = main.Mininet1.compareSwitches(
1615 mnSwitches,
1616 json.loads( devices[ controller ] ),
1617 json.loads( ports[ controller ] ) )
1618 else:
1619 currentDevicesResult = main.FALSE
1620 utilities.assert_equals( expect=main.TRUE,
1621 actual=currentDevicesResult,
1622 onpass="ONOS" + controllerStr +
1623 " Switches view is correct",
1624 onfail="ONOS" + controllerStr +
1625 " Switches view is incorrect" )
1626 if links[ controller ] and "Error" not in links[ controller ]:
1627 currentLinksResult = main.Mininet1.compareLinks(
1628 mnSwitches, mnLinks,
1629 json.loads( links[ controller ] ) )
1630 else:
1631 currentLinksResult = main.FALSE
1632 utilities.assert_equals( expect=main.TRUE,
1633 actual=currentLinksResult,
1634 onpass="ONOS" + controllerStr +
1635 " links view is correct",
1636 onfail="ONOS" + controllerStr +
1637 " links view is incorrect" )
1638
Jon Hall657cdf62015-12-17 14:40:51 -08001639 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001640 currentHostsResult = main.Mininet1.compareHosts(
1641 mnHosts,
1642 hosts[ controller ] )
1643 else:
1644 currentHostsResult = main.FALSE
1645 utilities.assert_equals( expect=main.TRUE,
1646 actual=currentHostsResult,
1647 onpass="ONOS" + controllerStr +
1648 " hosts exist in Mininet",
1649 onfail="ONOS" + controllerStr +
1650 " hosts don't match Mininet" )
1651
1652 devicesResults = devicesResults and currentDevicesResult
1653 linksResults = linksResults and currentLinksResult
1654 hostsResults = hostsResults and currentHostsResult
1655
1656 main.step( "Device information is correct" )
1657 utilities.assert_equals(
1658 expect=main.TRUE,
1659 actual=devicesResults,
1660 onpass="Device information is correct",
1661 onfail="Device information is incorrect" )
1662
1663 main.step( "Links are correct" )
1664 utilities.assert_equals(
1665 expect=main.TRUE,
1666 actual=linksResults,
1667 onpass="Link are correct",
1668 onfail="Links are incorrect" )
1669
1670 main.step( "Hosts are correct" )
1671 utilities.assert_equals(
1672 expect=main.TRUE,
1673 actual=hostsResults,
1674 onpass="Hosts are correct",
1675 onfail="Hosts are incorrect" )
1676
1677 def CASE6( self, main ):
1678 """
1679 The Failure case. Since this is the Sanity test, we do nothing.
1680 """
1681 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001682 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001683 assert main, "main not defined"
1684 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001685 assert main.CLIs, "main.CLIs not defined"
1686 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001687 main.case( "Wait 60 seconds instead of inducing a failure" )
1688 time.sleep( 60 )
1689 utilities.assert_equals(
1690 expect=main.TRUE,
1691 actual=main.TRUE,
1692 onpass="Sleeping 60 seconds",
1693 onfail="Something is terribly wrong with my math" )
1694
1695 def CASE7( self, main ):
1696 """
1697 Check state after ONOS failure
1698 """
1699 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001700 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001701 assert main, "main not defined"
1702 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001703 assert main.CLIs, "main.CLIs not defined"
1704 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001705 main.case( "Running ONOS Constant State Tests" )
1706
1707 main.step( "Check that each switch has a master" )
1708 # Assert that each device has a master
1709 rolesNotNull = main.TRUE
1710 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001711 for i in range( main.numCtrls ):
1712 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001713 name="rolesNotNull-" + str( i ),
1714 args=[ ] )
1715 threads.append( t )
1716 t.start()
1717
1718 for t in threads:
1719 t.join()
1720 rolesNotNull = rolesNotNull and t.result
1721 utilities.assert_equals(
1722 expect=main.TRUE,
1723 actual=rolesNotNull,
1724 onpass="Each device has a master",
1725 onfail="Some devices don't have a master assigned" )
1726
1727 main.step( "Read device roles from ONOS" )
1728 ONOSMastership = []
1729 mastershipCheck = main.FALSE
1730 consistentMastership = True
1731 rolesResults = True
1732 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001733 for i in range( main.numCtrls ):
1734 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001735 name="roles-" + str( i ),
1736 args=[] )
1737 threads.append( t )
1738 t.start()
1739
1740 for t in threads:
1741 t.join()
1742 ONOSMastership.append( t.result )
1743
Jon Halle1a3b752015-07-22 13:02:46 -07001744 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001745 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1746 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1747 " roles" )
1748 main.log.warn(
1749 "ONOS" + str( i + 1 ) + " mastership response: " +
1750 repr( ONOSMastership[i] ) )
1751 rolesResults = False
1752 utilities.assert_equals(
1753 expect=True,
1754 actual=rolesResults,
1755 onpass="No error in reading roles output",
1756 onfail="Error in reading roles from ONOS" )
1757
1758 main.step( "Check for consistency in roles from each controller" )
1759 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1760 main.log.info(
1761 "Switch roles are consistent across all ONOS nodes" )
1762 else:
1763 consistentMastership = False
1764 utilities.assert_equals(
1765 expect=True,
1766 actual=consistentMastership,
1767 onpass="Switch roles are consistent across all ONOS nodes",
1768 onfail="ONOS nodes have different views of switch roles" )
1769
1770 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001771 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001772 main.log.warn(
1773 "ONOS" + str( i + 1 ) + " roles: ",
1774 json.dumps(
1775 json.loads( ONOSMastership[ i ] ),
1776 sort_keys=True,
1777 indent=4,
1778 separators=( ',', ': ' ) ) )
1779 elif rolesResults and not consistentMastership:
1780 mastershipCheck = main.TRUE
1781
1782 description2 = "Compare switch roles from before failure"
1783 main.step( description2 )
1784 try:
1785 currentJson = json.loads( ONOSMastership[0] )
1786 oldJson = json.loads( mastershipState )
1787 except ( ValueError, TypeError ):
1788 main.log.exception( "Something is wrong with parsing " +
1789 "ONOSMastership[0] or mastershipState" )
1790 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1791 main.log.error( "mastershipState" + repr( mastershipState ) )
1792 main.cleanup()
1793 main.exit()
1794 mastershipCheck = main.TRUE
1795 for i in range( 1, 29 ):
1796 switchDPID = str(
1797 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1798 current = [ switch[ 'master' ] for switch in currentJson
1799 if switchDPID in switch[ 'id' ] ]
1800 old = [ switch[ 'master' ] for switch in oldJson
1801 if switchDPID in switch[ 'id' ] ]
1802 if current == old:
1803 mastershipCheck = mastershipCheck and main.TRUE
1804 else:
1805 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1806 mastershipCheck = main.FALSE
1807 utilities.assert_equals(
1808 expect=main.TRUE,
1809 actual=mastershipCheck,
1810 onpass="Mastership of Switches was not changed",
1811 onfail="Mastership of some switches changed" )
1812 mastershipCheck = mastershipCheck and consistentMastership
1813
1814 main.step( "Get the intents and compare across all nodes" )
1815 ONOSIntents = []
1816 intentCheck = main.FALSE
1817 consistentIntents = True
1818 intentsResults = True
1819 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001820 for i in range( main.numCtrls ):
1821 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001822 name="intents-" + str( i ),
1823 args=[],
1824 kwargs={ 'jsonFormat': True } )
1825 threads.append( t )
1826 t.start()
1827
1828 for t in threads:
1829 t.join()
1830 ONOSIntents.append( t.result )
1831
Jon Halle1a3b752015-07-22 13:02:46 -07001832 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001833 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1834 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1835 " intents" )
1836 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1837 repr( ONOSIntents[ i ] ) )
1838 intentsResults = False
1839 utilities.assert_equals(
1840 expect=True,
1841 actual=intentsResults,
1842 onpass="No error in reading intents output",
1843 onfail="Error in reading intents from ONOS" )
1844
1845 main.step( "Check for consistency in Intents from each controller" )
1846 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1847 main.log.info( "Intents are consistent across all ONOS " +
1848 "nodes" )
1849 else:
1850 consistentIntents = False
1851
1852 # Try to make it easy to figure out what is happening
1853 #
1854 # Intent ONOS1 ONOS2 ...
1855 # 0x01 INSTALLED INSTALLING
1856 # ... ... ...
1857 # ... ... ...
1858 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001859 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001860 title += " " * 10 + "ONOS" + str( n + 1 )
1861 main.log.warn( title )
1862 # get all intent keys in the cluster
1863 keys = []
1864 for nodeStr in ONOSIntents:
1865 node = json.loads( nodeStr )
1866 for intent in node:
1867 keys.append( intent.get( 'id' ) )
1868 keys = set( keys )
1869 for key in keys:
1870 row = "%-13s" % key
1871 for nodeStr in ONOSIntents:
1872 node = json.loads( nodeStr )
1873 for intent in node:
1874 if intent.get( 'id' ) == key:
1875 row += "%-15s" % intent.get( 'state' )
1876 main.log.warn( row )
1877 # End table view
1878
1879 utilities.assert_equals(
1880 expect=True,
1881 actual=consistentIntents,
1882 onpass="Intents are consistent across all ONOS nodes",
1883 onfail="ONOS nodes have different views of intents" )
1884 intentStates = []
1885 for node in ONOSIntents: # Iter through ONOS nodes
1886 nodeStates = []
1887 # Iter through intents of a node
1888 try:
1889 for intent in json.loads( node ):
1890 nodeStates.append( intent[ 'state' ] )
1891 except ( ValueError, TypeError ):
1892 main.log.exception( "Error in parsing intents" )
1893 main.log.error( repr( node ) )
1894 intentStates.append( nodeStates )
1895 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1896 main.log.info( dict( out ) )
1897
1898 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07001899 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001900 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1901 main.log.warn( json.dumps(
1902 json.loads( ONOSIntents[ i ] ),
1903 sort_keys=True,
1904 indent=4,
1905 separators=( ',', ': ' ) ) )
1906 elif intentsResults and consistentIntents:
1907 intentCheck = main.TRUE
1908
1909 # NOTE: Store has no durability, so intents are lost across system
1910 # restarts
1911 main.step( "Compare current intents with intents before the failure" )
1912 # NOTE: this requires case 5 to pass for intentState to be set.
1913 # maybe we should stop the test if that fails?
1914 sameIntents = main.FALSE
1915 if intentState and intentState == ONOSIntents[ 0 ]:
1916 sameIntents = main.TRUE
1917 main.log.info( "Intents are consistent with before failure" )
1918 # TODO: possibly the states have changed? we may need to figure out
1919 # what the acceptable states are
1920 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1921 sameIntents = main.TRUE
1922 try:
1923 before = json.loads( intentState )
1924 after = json.loads( ONOSIntents[ 0 ] )
1925 for intent in before:
1926 if intent not in after:
1927 sameIntents = main.FALSE
1928 main.log.debug( "Intent is not currently in ONOS " +
1929 "(at least in the same form):" )
1930 main.log.debug( json.dumps( intent ) )
1931 except ( ValueError, TypeError ):
1932 main.log.exception( "Exception printing intents" )
1933 main.log.debug( repr( ONOSIntents[0] ) )
1934 main.log.debug( repr( intentState ) )
1935 if sameIntents == main.FALSE:
1936 try:
1937 main.log.debug( "ONOS intents before: " )
1938 main.log.debug( json.dumps( json.loads( intentState ),
1939 sort_keys=True, indent=4,
1940 separators=( ',', ': ' ) ) )
1941 main.log.debug( "Current ONOS intents: " )
1942 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1943 sort_keys=True, indent=4,
1944 separators=( ',', ': ' ) ) )
1945 except ( ValueError, TypeError ):
1946 main.log.exception( "Exception printing intents" )
1947 main.log.debug( repr( ONOSIntents[0] ) )
1948 main.log.debug( repr( intentState ) )
1949 utilities.assert_equals(
1950 expect=main.TRUE,
1951 actual=sameIntents,
1952 onpass="Intents are consistent with before failure",
1953 onfail="The Intents changed during failure" )
1954 intentCheck = intentCheck and sameIntents
1955
1956 main.step( "Get the OF Table entries and compare to before " +
1957 "component failure" )
1958 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07001959 for i in range( 28 ):
1960 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001961 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1962 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07001963 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001964 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
1965
Jon Hall5cf14d52015-07-16 12:15:19 -07001966 utilities.assert_equals(
1967 expect=main.TRUE,
1968 actual=FlowTables,
1969 onpass="No changes were found in the flow tables",
1970 onfail="Changes were found in the flow tables" )
1971
1972 main.Mininet2.pingLongKill()
1973 '''
1974 main.step( "Check the continuous pings to ensure that no packets " +
1975 "were dropped during component failure" )
1976 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1977 main.params[ 'TESTONIP' ] )
1978 LossInPings = main.FALSE
1979 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1980 for i in range( 8, 18 ):
1981 main.log.info(
1982 "Checking for a loss in pings along flow from s" +
1983 str( i ) )
1984 LossInPings = main.Mininet2.checkForLoss(
1985 "/tmp/ping.h" +
1986 str( i ) ) or LossInPings
1987 if LossInPings == main.TRUE:
1988 main.log.info( "Loss in ping detected" )
1989 elif LossInPings == main.ERROR:
1990 main.log.info( "There are multiple mininet process running" )
1991 elif LossInPings == main.FALSE:
1992 main.log.info( "No Loss in the pings" )
1993 main.log.info( "No loss of dataplane connectivity" )
1994 utilities.assert_equals(
1995 expect=main.FALSE,
1996 actual=LossInPings,
1997 onpass="No Loss of connectivity",
1998 onfail="Loss of dataplane connectivity detected" )
1999 '''
2000
2001 main.step( "Leadership Election is still functional" )
2002 # Test of LeadershipElection
2003 # NOTE: this only works for the sanity test. In case of failures,
2004 # leader will likely change
Jon Halle1a3b752015-07-22 13:02:46 -07002005 leader = main.nodes[ 0 ].ip_address
Jon Hall5cf14d52015-07-16 12:15:19 -07002006 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002007 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002008 leaderN = cli.electionTestLeader()
2009 # verify leader is ONOS1
2010 if leaderN == leader:
2011 # all is well
2012 # NOTE: In failure scenario, this could be a new node, maybe
2013 # check != ONOS1
2014 pass
2015 elif leaderN == main.FALSE:
2016 # error in response
2017 main.log.error( "Something is wrong with " +
2018 "electionTestLeader function, check the" +
2019 " error logs" )
2020 leaderResult = main.FALSE
2021 elif leader != leaderN:
2022 leaderResult = main.FALSE
2023 main.log.error( cli.name + " sees " + str( leaderN ) +
2024 " as the leader of the election app. " +
2025 "Leader should be " + str( leader ) )
2026 utilities.assert_equals(
2027 expect=main.TRUE,
2028 actual=leaderResult,
2029 onpass="Leadership election passed",
2030 onfail="Something went wrong with Leadership election" )
2031
2032 def CASE8( self, main ):
2033 """
2034 Compare topo
2035 """
2036 import json
2037 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002038 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002039 assert main, "main not defined"
2040 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002041 assert main.CLIs, "main.CLIs not defined"
2042 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002043
2044 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002045 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002046 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002047 topoResult = main.FALSE
2048 elapsed = 0
2049 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002050 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002051 startTime = time.time()
2052 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002053 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002054 devicesResults = main.TRUE
2055 linksResults = main.TRUE
2056 hostsResults = main.TRUE
2057 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002058 count += 1
2059 cliStart = time.time()
2060 devices = []
2061 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002062 for i in range( main.numCtrls ):
2063 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002064 name="devices-" + str( i ),
2065 args=[ ] )
2066 threads.append( t )
2067 t.start()
2068
2069 for t in threads:
2070 t.join()
2071 devices.append( t.result )
2072 hosts = []
2073 ipResult = main.TRUE
2074 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002075 for i in range( main.numCtrls ):
Jon Halld8f6de82015-12-17 17:04:34 -08002076 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002077 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002078 args=[ main.CLIs[i].hosts, [ None ] ],
2079 kwargs= { 'sleep': 5, 'attempts': 5,
2080 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002081 threads.append( t )
2082 t.start()
2083
2084 for t in threads:
2085 t.join()
2086 try:
2087 hosts.append( json.loads( t.result ) )
2088 except ( ValueError, TypeError ):
2089 main.log.exception( "Error parsing hosts results" )
2090 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002091 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002092 for controller in range( 0, len( hosts ) ):
2093 controllerStr = str( controller + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002094 if hosts[ controller ]:
2095 for host in hosts[ controller ]:
2096 if host is None or host.get( 'ipAddresses', [] ) == []:
2097 main.log.error(
2098 "Error with host ipAddresses on controller" +
2099 controllerStr + ": " + str( host ) )
2100 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002101 ports = []
2102 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002103 for i in range( main.numCtrls ):
2104 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002105 name="ports-" + str( i ),
2106 args=[ ] )
2107 threads.append( t )
2108 t.start()
2109
2110 for t in threads:
2111 t.join()
2112 ports.append( t.result )
2113 links = []
2114 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002115 for i in range( main.numCtrls ):
2116 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002117 name="links-" + str( i ),
2118 args=[ ] )
2119 threads.append( t )
2120 t.start()
2121
2122 for t in threads:
2123 t.join()
2124 links.append( t.result )
2125 clusters = []
2126 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002127 for i in range( main.numCtrls ):
2128 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002129 name="clusters-" + str( i ),
2130 args=[ ] )
2131 threads.append( t )
2132 t.start()
2133
2134 for t in threads:
2135 t.join()
2136 clusters.append( t.result )
2137
2138 elapsed = time.time() - startTime
2139 cliTime = time.time() - cliStart
2140 print "Elapsed time: " + str( elapsed )
2141 print "CLI time: " + str( cliTime )
2142
2143 mnSwitches = main.Mininet1.getSwitches()
2144 mnLinks = main.Mininet1.getLinks()
2145 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002146 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002147 controllerStr = str( controller + 1 )
2148 if devices[ controller ] and ports[ controller ] and\
2149 "Error" not in devices[ controller ] and\
2150 "Error" not in ports[ controller ]:
2151
Jon Hallc6793552016-01-19 14:18:37 -08002152 try:
2153 currentDevicesResult = main.Mininet1.compareSwitches(
2154 mnSwitches,
2155 json.loads( devices[ controller ] ),
2156 json.loads( ports[ controller ] ) )
2157 except ( TypeError, ValueError ) as e:
2158 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2159 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002160 else:
2161 currentDevicesResult = main.FALSE
2162 utilities.assert_equals( expect=main.TRUE,
2163 actual=currentDevicesResult,
2164 onpass="ONOS" + controllerStr +
2165 " Switches view is correct",
2166 onfail="ONOS" + controllerStr +
2167 " Switches view is incorrect" )
2168
2169 if links[ controller ] and "Error" not in links[ controller ]:
2170 currentLinksResult = main.Mininet1.compareLinks(
2171 mnSwitches, mnLinks,
2172 json.loads( links[ controller ] ) )
2173 else:
2174 currentLinksResult = main.FALSE
2175 utilities.assert_equals( expect=main.TRUE,
2176 actual=currentLinksResult,
2177 onpass="ONOS" + controllerStr +
2178 " links view is correct",
2179 onfail="ONOS" + controllerStr +
2180 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002181 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002182 currentHostsResult = main.Mininet1.compareHosts(
2183 mnHosts,
2184 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002185 elif hosts[ controller ] == []:
2186 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002187 else:
2188 currentHostsResult = main.FALSE
2189 utilities.assert_equals( expect=main.TRUE,
2190 actual=currentHostsResult,
2191 onpass="ONOS" + controllerStr +
2192 " hosts exist in Mininet",
2193 onfail="ONOS" + controllerStr +
2194 " hosts don't match Mininet" )
2195 # CHECKING HOST ATTACHMENT POINTS
2196 hostAttachment = True
2197 zeroHosts = False
2198 # FIXME: topo-HA/obelisk specific mappings:
2199 # key is mac and value is dpid
2200 mappings = {}
2201 for i in range( 1, 29 ): # hosts 1 through 28
2202 # set up correct variables:
2203 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2204 if i == 1:
2205 deviceId = "1000".zfill(16)
2206 elif i == 2:
2207 deviceId = "2000".zfill(16)
2208 elif i == 3:
2209 deviceId = "3000".zfill(16)
2210 elif i == 4:
2211 deviceId = "3004".zfill(16)
2212 elif i == 5:
2213 deviceId = "5000".zfill(16)
2214 elif i == 6:
2215 deviceId = "6000".zfill(16)
2216 elif i == 7:
2217 deviceId = "6007".zfill(16)
2218 elif i >= 8 and i <= 17:
2219 dpid = '3' + str( i ).zfill( 3 )
2220 deviceId = dpid.zfill(16)
2221 elif i >= 18 and i <= 27:
2222 dpid = '6' + str( i ).zfill( 3 )
2223 deviceId = dpid.zfill(16)
2224 elif i == 28:
2225 deviceId = "2800".zfill(16)
2226 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002227 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002228 if hosts[ controller ] == []:
2229 main.log.warn( "There are no hosts discovered" )
2230 zeroHosts = True
2231 else:
2232 for host in hosts[ controller ]:
2233 mac = None
2234 location = None
2235 device = None
2236 port = None
2237 try:
2238 mac = host.get( 'mac' )
2239 assert mac, "mac field could not be found for this host object"
2240
2241 location = host.get( 'location' )
2242 assert location, "location field could not be found for this host object"
2243
2244 # Trim the protocol identifier off deviceId
2245 device = str( location.get( 'elementId' ) ).split(':')[1]
2246 assert device, "elementId field could not be found for this host location object"
2247
2248 port = location.get( 'port' )
2249 assert port, "port field could not be found for this host location object"
2250
2251 # Now check if this matches where they should be
2252 if mac and device and port:
2253 if str( port ) != "1":
2254 main.log.error( "The attachment port is incorrect for " +
2255 "host " + str( mac ) +
2256 ". Expected: 1 Actual: " + str( port) )
2257 hostAttachment = False
2258 if device != mappings[ str( mac ) ]:
2259 main.log.error( "The attachment device is incorrect for " +
2260 "host " + str( mac ) +
2261 ". Expected: " + mappings[ str( mac ) ] +
2262 " Actual: " + device )
2263 hostAttachment = False
2264 else:
2265 hostAttachment = False
2266 except AssertionError:
2267 main.log.exception( "Json object not as expected" )
2268 main.log.error( repr( host ) )
2269 hostAttachment = False
2270 else:
2271 main.log.error( "No hosts json output or \"Error\"" +
2272 " in output. hosts = " +
2273 repr( hosts[ controller ] ) )
2274 if zeroHosts is False:
2275 hostAttachment = True
2276
2277 # END CHECKING HOST ATTACHMENT POINTS
2278 devicesResults = devicesResults and currentDevicesResult
2279 linksResults = linksResults and currentLinksResult
2280 hostsResults = hostsResults and currentHostsResult
2281 hostAttachmentResults = hostAttachmentResults and\
2282 hostAttachment
2283 topoResult = ( devicesResults and linksResults
2284 and hostsResults and ipResult and
2285 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002286 utilities.assert_equals( expect=True,
2287 actual=topoResult,
2288 onpass="ONOS topology matches Mininet",
2289 onfail="ONOS topology don't match Mininet" )
2290 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002291
2292 # Compare json objects for hosts and dataplane clusters
2293
2294 # hosts
2295 main.step( "Hosts view is consistent across all ONOS nodes" )
2296 consistentHostsResult = main.TRUE
2297 for controller in range( len( hosts ) ):
2298 controllerStr = str( controller + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002299 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002300 if hosts[ controller ] == hosts[ 0 ]:
2301 continue
2302 else: # hosts not consistent
2303 main.log.error( "hosts from ONOS" + controllerStr +
2304 " is inconsistent with ONOS1" )
2305 main.log.warn( repr( hosts[ controller ] ) )
2306 consistentHostsResult = main.FALSE
2307
2308 else:
2309 main.log.error( "Error in getting ONOS hosts from ONOS" +
2310 controllerStr )
2311 consistentHostsResult = main.FALSE
2312 main.log.warn( "ONOS" + controllerStr +
2313 " hosts response: " +
2314 repr( hosts[ controller ] ) )
2315 utilities.assert_equals(
2316 expect=main.TRUE,
2317 actual=consistentHostsResult,
2318 onpass="Hosts view is consistent across all ONOS nodes",
2319 onfail="ONOS nodes have different views of hosts" )
2320
2321 main.step( "Hosts information is correct" )
2322 hostsResults = hostsResults and ipResult
2323 utilities.assert_equals(
2324 expect=main.TRUE,
2325 actual=hostsResults,
2326 onpass="Host information is correct",
2327 onfail="Host information is incorrect" )
2328
2329 main.step( "Host attachment points to the network" )
2330 utilities.assert_equals(
2331 expect=True,
2332 actual=hostAttachmentResults,
2333 onpass="Hosts are correctly attached to the network",
2334 onfail="ONOS did not correctly attach hosts to the network" )
2335
2336 # Strongly connected clusters of devices
2337 main.step( "Clusters view is consistent across all ONOS nodes" )
2338 consistentClustersResult = main.TRUE
2339 for controller in range( len( clusters ) ):
2340 controllerStr = str( controller + 1 )
2341 if "Error" not in clusters[ controller ]:
2342 if clusters[ controller ] == clusters[ 0 ]:
2343 continue
2344 else: # clusters not consistent
2345 main.log.error( "clusters from ONOS" +
2346 controllerStr +
2347 " is inconsistent with ONOS1" )
2348 consistentClustersResult = main.FALSE
2349
2350 else:
2351 main.log.error( "Error in getting dataplane clusters " +
2352 "from ONOS" + controllerStr )
2353 consistentClustersResult = main.FALSE
2354 main.log.warn( "ONOS" + controllerStr +
2355 " clusters response: " +
2356 repr( clusters[ controller ] ) )
2357 utilities.assert_equals(
2358 expect=main.TRUE,
2359 actual=consistentClustersResult,
2360 onpass="Clusters view is consistent across all ONOS nodes",
2361 onfail="ONOS nodes have different views of clusters" )
2362
2363 main.step( "There is only one SCC" )
2364 # there should always only be one cluster
2365 try:
2366 numClusters = len( json.loads( clusters[ 0 ] ) )
2367 except ( ValueError, TypeError ):
2368 main.log.exception( "Error parsing clusters[0]: " +
2369 repr( clusters[0] ) )
2370 clusterResults = main.FALSE
2371 if numClusters == 1:
2372 clusterResults = main.TRUE
2373 utilities.assert_equals(
2374 expect=1,
2375 actual=numClusters,
2376 onpass="ONOS shows 1 SCC",
2377 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2378
2379 topoResult = ( devicesResults and linksResults
2380 and hostsResults and consistentHostsResult
2381 and consistentClustersResult and clusterResults
2382 and ipResult and hostAttachmentResults )
2383
2384 topoResult = topoResult and int( count <= 2 )
2385 note = "note it takes about " + str( int( cliTime ) ) + \
2386 " seconds for the test to make all the cli calls to fetch " +\
2387 "the topology from each ONOS instance"
2388 main.log.info(
2389 "Very crass estimate for topology discovery/convergence( " +
2390 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2391 str( count ) + " tries" )
2392
2393 main.step( "Device information is correct" )
2394 utilities.assert_equals(
2395 expect=main.TRUE,
2396 actual=devicesResults,
2397 onpass="Device information is correct",
2398 onfail="Device information is incorrect" )
2399
2400 main.step( "Links are correct" )
2401 utilities.assert_equals(
2402 expect=main.TRUE,
2403 actual=linksResults,
2404 onpass="Link are correct",
2405 onfail="Links are incorrect" )
2406
2407 main.step( "Hosts are correct" )
2408 utilities.assert_equals(
2409 expect=main.TRUE,
2410 actual=hostsResults,
2411 onpass="Hosts are correct",
2412 onfail="Hosts are incorrect" )
2413
2414 # FIXME: move this to an ONOS state case
2415 main.step( "Checking ONOS nodes" )
2416 nodesOutput = []
2417 nodeResults = main.TRUE
2418 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002419 for i in range( main.numCtrls ):
2420 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002421 name="nodes-" + str( i ),
2422 args=[ ] )
2423 threads.append( t )
2424 t.start()
2425
2426 for t in threads:
2427 t.join()
2428 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002429 ips = [ node.ip_address for node in main.nodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002430 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002431 for i in nodesOutput:
2432 try:
2433 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002434 activeIps = []
2435 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002436 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002437 if node['state'] == 'ACTIVE':
2438 activeIps.append( node['ip'] )
2439 activeIps.sort()
2440 if ips == activeIps:
2441 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002442 except ( ValueError, TypeError ):
2443 main.log.error( "Error parsing nodes output" )
2444 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002445 currentResult = main.FALSE
2446 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002447 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2448 onpass="Nodes check successful",
2449 onfail="Nodes check NOT successful" )
2450
2451 def CASE9( self, main ):
2452 """
2453 Link s3-s28 down
2454 """
2455 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002456 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002457 assert main, "main not defined"
2458 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002459 assert main.CLIs, "main.CLIs not defined"
2460 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002461 # NOTE: You should probably run a topology check after this
2462
2463 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2464
2465 description = "Turn off a link to ensure that Link Discovery " +\
2466 "is working properly"
2467 main.case( description )
2468
2469 main.step( "Kill Link between s3 and s28" )
2470 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2471 main.log.info( "Waiting " + str( linkSleep ) +
2472 " seconds for link down to be discovered" )
2473 time.sleep( linkSleep )
2474 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2475 onpass="Link down successful",
2476 onfail="Failed to bring link down" )
2477 # TODO do some sort of check here
2478
2479 def CASE10( self, main ):
2480 """
2481 Link s3-s28 up
2482 """
2483 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002484 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002485 assert main, "main not defined"
2486 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002487 assert main.CLIs, "main.CLIs not defined"
2488 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002489 # NOTE: You should probably run a topology check after this
2490
2491 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2492
2493 description = "Restore a link to ensure that Link Discovery is " + \
2494 "working properly"
2495 main.case( description )
2496
2497 main.step( "Bring link between s3 and s28 back up" )
2498 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2499 main.log.info( "Waiting " + str( linkSleep ) +
2500 " seconds for link up to be discovered" )
2501 time.sleep( linkSleep )
2502 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2503 onpass="Link up successful",
2504 onfail="Failed to bring link up" )
2505 # TODO do some sort of check here
2506
2507 def CASE11( self, main ):
2508 """
2509 Switch Down
2510 """
2511 # NOTE: You should probably run a topology check after this
2512 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002513 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002514 assert main, "main not defined"
2515 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002516 assert main.CLIs, "main.CLIs not defined"
2517 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002518
2519 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2520
2521 description = "Killing a switch to ensure it is discovered correctly"
2522 main.case( description )
2523 switch = main.params[ 'kill' ][ 'switch' ]
2524 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2525
2526 # TODO: Make this switch parameterizable
2527 main.step( "Kill " + switch )
2528 main.log.info( "Deleting " + switch )
2529 main.Mininet1.delSwitch( switch )
2530 main.log.info( "Waiting " + str( switchSleep ) +
2531 " seconds for switch down to be discovered" )
2532 time.sleep( switchSleep )
2533 device = main.ONOScli1.getDevice( dpid=switchDPID )
2534 # Peek at the deleted switch
2535 main.log.warn( str( device ) )
2536 result = main.FALSE
2537 if device and device[ 'available' ] is False:
2538 result = main.TRUE
2539 utilities.assert_equals( expect=main.TRUE, actual=result,
2540 onpass="Kill switch successful",
2541 onfail="Failed to kill switch?" )
2542
2543 def CASE12( self, main ):
2544 """
2545 Switch Up
2546 """
2547 # NOTE: You should probably run a topology check after this
2548 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002549 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002550 assert main, "main not defined"
2551 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002552 assert main.CLIs, "main.CLIs not defined"
2553 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002554 assert ONOS1Port, "ONOS1Port not defined"
2555 assert ONOS2Port, "ONOS2Port not defined"
2556 assert ONOS3Port, "ONOS3Port not defined"
2557 assert ONOS4Port, "ONOS4Port not defined"
2558 assert ONOS5Port, "ONOS5Port not defined"
2559 assert ONOS6Port, "ONOS6Port not defined"
2560 assert ONOS7Port, "ONOS7Port not defined"
2561
2562 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2563 switch = main.params[ 'kill' ][ 'switch' ]
2564 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2565 links = main.params[ 'kill' ][ 'links' ].split()
2566 description = "Adding a switch to ensure it is discovered correctly"
2567 main.case( description )
2568
2569 main.step( "Add back " + switch )
2570 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2571 for peer in links:
2572 main.Mininet1.addLink( switch, peer )
2573 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002574 for i in range( main.numCtrls ):
2575 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002576 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2577 main.log.info( "Waiting " + str( switchSleep ) +
2578 " seconds for switch up to be discovered" )
2579 time.sleep( switchSleep )
2580 device = main.ONOScli1.getDevice( dpid=switchDPID )
2581 # Peek at the deleted switch
2582 main.log.warn( str( device ) )
2583 result = main.FALSE
2584 if device and device[ 'available' ]:
2585 result = main.TRUE
2586 utilities.assert_equals( expect=main.TRUE, actual=result,
2587 onpass="add switch successful",
2588 onfail="Failed to add switch?" )
2589
2590 def CASE13( self, main ):
2591 """
2592 Clean up
2593 """
2594 import os
2595 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002596 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002597 assert main, "main not defined"
2598 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002599 assert main.CLIs, "main.CLIs not defined"
2600 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002601
2602 # printing colors to terminal
2603 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2604 'blue': '\033[94m', 'green': '\033[92m',
2605 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2606 main.case( "Test Cleanup" )
2607 main.step( "Killing tcpdumps" )
2608 main.Mininet2.stopTcpdump()
2609
2610 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002611 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002612 main.step( "Copying MN pcap and ONOS log files to test station" )
2613 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2614 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002615 # NOTE: MN Pcap file is being saved to logdir.
2616 # We scp this file as MN and TestON aren't necessarily the same vm
2617
2618 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002619 # TODO: Load these from params
2620 # NOTE: must end in /
2621 logFolder = "/opt/onos/log/"
2622 logFiles = [ "karaf.log", "karaf.log.1" ]
2623 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002624 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002625 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002626 dstName = main.logdir + "/" + node.name + "-" + f
2627 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2628 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002629 # std*.log's
2630 # NOTE: must end in /
2631 logFolder = "/opt/onos/var/"
2632 logFiles = [ "stderr.log", "stdout.log" ]
2633 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002634 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002635 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002636 dstName = main.logdir + "/" + node.name + "-" + f
2637 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2638 logFolder + f, dstName )
2639 else:
2640 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002641
2642 main.step( "Stopping Mininet" )
2643 mnResult = main.Mininet1.stopNet()
2644 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2645 onpass="Mininet stopped",
2646 onfail="MN cleanup NOT successful" )
2647
2648 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002649 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002650 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2651 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002652
2653 try:
2654 timerLog = open( main.logdir + "/Timers.csv", 'w')
2655 # Overwrite with empty line and close
2656 labels = "Gossip Intents"
2657 data = str( gossipTime )
2658 timerLog.write( labels + "\n" + data )
2659 timerLog.close()
2660 except NameError, e:
2661 main.log.exception(e)
2662
2663 def CASE14( self, main ):
2664 """
2665 start election app on all onos nodes
2666 """
Jon Halle1a3b752015-07-22 13:02:46 -07002667 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002668 assert main, "main not defined"
2669 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002670 assert main.CLIs, "main.CLIs not defined"
2671 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002672
2673 main.case("Start Leadership Election app")
2674 main.step( "Install leadership election app" )
2675 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2676 utilities.assert_equals(
2677 expect=main.TRUE,
2678 actual=appResult,
2679 onpass="Election app installed",
2680 onfail="Something went wrong with installing Leadership election" )
2681
2682 main.step( "Run for election on each node" )
2683 leaderResult = main.TRUE
2684 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002685 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002686 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002687 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002688 leader = cli.electionTestLeader()
2689 if leader is None or leader == main.FALSE:
2690 main.log.error( cli.name + ": Leader for the election app " +
2691 "should be an ONOS node, instead got '" +
2692 str( leader ) + "'" )
2693 leaderResult = main.FALSE
2694 leaders.append( leader )
2695 utilities.assert_equals(
2696 expect=main.TRUE,
2697 actual=leaderResult,
2698 onpass="Successfully ran for leadership",
2699 onfail="Failed to run for leadership" )
2700
2701 main.step( "Check that each node shows the same leader" )
2702 sameLeader = main.TRUE
2703 if len( set( leaders ) ) != 1:
2704 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002705 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002706 str( leaders ) )
2707 utilities.assert_equals(
2708 expect=main.TRUE,
2709 actual=sameLeader,
2710 onpass="Leadership is consistent for the election topic",
2711 onfail="Nodes have different leaders" )
2712
2713 def CASE15( self, main ):
2714 """
2715 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002716 15.1 Run election on each node
2717 15.2 Check that each node has the same leaders and candidates
2718 15.3 Find current leader and withdraw
2719 15.4 Check that a new node was elected leader
2720 15.5 Check that that new leader was the candidate of old leader
2721 15.6 Run for election on old leader
2722 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2723 15.8 Make sure that the old leader was added to the candidate list
2724
2725 old and new variable prefixes refer to data from before vs after
2726 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002727 """
2728 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002729 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002730 assert main, "main not defined"
2731 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002732 assert main.CLIs, "main.CLIs not defined"
2733 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002734
acsmars3a72bde2015-09-02 14:16:22 -07002735 description = "Check that Leadership Election App is still functional"
Jon Hall5cf14d52015-07-16 12:15:19 -07002736 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07002737 # NOTE: Need to re-run since being a canidate is not persistant
2738 # TODO: add check for "Command not found:" in the driver, this
2739 # means the election test app isn't loaded
Jon Hall5cf14d52015-07-16 12:15:19 -07002740
acsmars71adceb2015-08-31 15:09:26 -07002741 oldLeaders = [] # leaders by node before withdrawl from candidates
2742 newLeaders = [] # leaders by node after withdrawl from candidates
2743 oldAllCandidates = [] # list of lists of each nodes' candidates before
2744 newAllCandidates = [] # list of lists of each nodes' candidates after
2745 oldCandidates = [] # list of candidates from node 0 before withdrawl
2746 newCandidates = [] # list of candidates from node 0 after withdrawl
2747 oldLeader = '' # the old leader from oldLeaders, None if not same
2748 newLeader = '' # the new leaders fron newLoeaders, None if not same
2749 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2750 expectNoLeader = False # True when there is only one leader
2751 if main.numCtrls == 1:
2752 expectNoLeader = True
2753
2754 main.step( "Run for election on each node" )
2755 electionResult = main.TRUE
2756
2757 for cli in main.CLIs: # run test election on each node
2758 if cli.electionTestRun() == main.FALSE:
2759 electionResult = main.FALSE
2760
Jon Hall5cf14d52015-07-16 12:15:19 -07002761 utilities.assert_equals(
2762 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002763 actual=electionResult,
2764 onpass="All nodes successfully ran for leadership",
2765 onfail="At least one node failed to run for leadership" )
2766
acsmars3a72bde2015-09-02 14:16:22 -07002767 if electionResult == main.FALSE:
2768 main.log.error(
2769 "Skipping Test Case because Election Test isn't loaded" )
2770 main.skipCase()
2771
acsmars71adceb2015-08-31 15:09:26 -07002772 main.step( "Check that each node shows the same leader and candidates" )
2773 sameResult = main.TRUE
2774 failMessage = "Nodes have different leaders"
2775 for cli in main.CLIs:
2776 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2777 oldAllCandidates.append( node )
2778 oldLeaders.append( node[ 0 ] )
2779 oldCandidates = oldAllCandidates[ 0 ]
2780
2781 # Check that each node has the same leader. Defines oldLeader
2782 if len( set( oldLeaders ) ) != 1:
2783 sameResult = main.FALSE
2784 main.log.error( "More than one leader present:" + str( oldLeaders ) )
2785 oldLeader = None
2786 else:
2787 oldLeader = oldLeaders[ 0 ]
2788
2789 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002790 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07002791 for candidates in oldAllCandidates:
2792 if set( candidates ) != set( oldCandidates ):
2793 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002794 candidateDiscrepancy = True
2795
2796 if candidateDiscrepancy:
2797 failMessage += " and candidates"
acsmars71adceb2015-08-31 15:09:26 -07002798
2799 utilities.assert_equals(
2800 expect=main.TRUE,
2801 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002802 onpass="Leadership is consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002803 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002804
2805 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002806 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002807 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002808 if oldLeader is None:
2809 main.log.error( "Leadership isn't consistent." )
2810 withdrawResult = main.FALSE
2811 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002812 for i in range( len( main.CLIs ) ):
acsmars71adceb2015-08-31 15:09:26 -07002813 if oldLeader == main.nodes[ i ].ip_address:
2814 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002815 break
2816 else: # FOR/ELSE statement
2817 main.log.error( "Leader election, could not find current leader" )
2818 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002819 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002820 utilities.assert_equals(
2821 expect=main.TRUE,
2822 actual=withdrawResult,
2823 onpass="Node was withdrawn from election",
2824 onfail="Node was not withdrawn from election" )
2825
acsmars71adceb2015-08-31 15:09:26 -07002826 main.step( "Check that a new node was elected leader" )
2827
Jon Hall5cf14d52015-07-16 12:15:19 -07002828 # FIXME: use threads
acsmars71adceb2015-08-31 15:09:26 -07002829 newLeaderResult = main.TRUE
2830 failMessage = "Nodes have different leaders"
2831
2832 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002833 for cli in main.CLIs:
acsmars71adceb2015-08-31 15:09:26 -07002834 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2835 # elections might no have finished yet
2836 if node[ 0 ] == 'none' and not expectNoLeader:
2837 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2838 "sure elections are complete." )
2839 time.sleep(5)
2840 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2841 # election still isn't done or there is a problem
2842 if node[ 0 ] == 'none':
2843 main.log.error( "No leader was elected on at least 1 node" )
2844 newLeaderResult = main.FALSE
2845 newAllCandidates.append( node )
2846 newLeaders.append( node[ 0 ] )
2847 newCandidates = newAllCandidates[ 0 ]
2848
2849 # Check that each node has the same leader. Defines newLeader
2850 if len( set( newLeaders ) ) != 1:
2851 newLeaderResult = main.FALSE
2852 main.log.error( "Nodes have different leaders: " +
2853 str( newLeaders ) )
2854 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 else:
acsmars71adceb2015-08-31 15:09:26 -07002856 newLeader = newLeaders[ 0 ]
2857
2858 # Check that each node's candidate list is the same
2859 for candidates in newAllCandidates:
2860 if set( candidates ) != set( newCandidates ):
2861 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002862 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002863
2864 # Check that the new leader is not the older leader, which was withdrawn
2865 if newLeader == oldLeader:
2866 newLeaderResult = main.FALSE
2867 main.log.error( "All nodes still see old leader: " + oldLeader +
2868 " as the current leader" )
2869
Jon Hall5cf14d52015-07-16 12:15:19 -07002870 utilities.assert_equals(
2871 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002872 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002873 onpass="Leadership election passed",
2874 onfail="Something went wrong with Leadership election" )
2875
acsmars71adceb2015-08-31 15:09:26 -07002876 main.step( "Check that that new leader was the candidate of old leader")
2877 # candidates[ 2 ] should be come the top candidate after withdrawl
2878 correctCandidateResult = main.TRUE
2879 if expectNoLeader:
2880 if newLeader == 'none':
2881 main.log.info( "No leader expected. None found. Pass" )
2882 correctCandidateResult = main.TRUE
2883 else:
2884 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2885 correctCandidateResult = main.FALSE
2886 elif newLeader != oldCandidates[ 2 ]:
2887 correctCandidateResult = main.FALSE
2888 main.log.error( "Candidate " + newLeader + " was elected. " +
2889 oldCandidates[ 2 ] + " should have had priority." )
2890
2891 utilities.assert_equals(
2892 expect=main.TRUE,
2893 actual=correctCandidateResult,
2894 onpass="Correct Candidate Elected",
2895 onfail="Incorrect Candidate Elected" )
2896
Jon Hall5cf14d52015-07-16 12:15:19 -07002897 main.step( "Run for election on old leader( just so everyone " +
2898 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002899 if oldLeaderCLI is not None:
2900 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 else:
acsmars71adceb2015-08-31 15:09:26 -07002902 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002903 runResult = main.FALSE
2904 utilities.assert_equals(
2905 expect=main.TRUE,
2906 actual=runResult,
2907 onpass="App re-ran for election",
2908 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002909 main.step(
2910 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002911 # verify leader didn't just change
acsmars71adceb2015-08-31 15:09:26 -07002912 positionResult = main.TRUE
2913 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
2914
2915 # Reset and reuse the new candidate and leaders lists
2916 newAllCandidates = []
2917 newCandidates = []
2918 newLeaders = []
2919 for cli in main.CLIs:
2920 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2921 if oldLeader not in node: # election might no have finished yet
2922 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2923 "be sure elections are complete" )
2924 time.sleep(5)
2925 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2926 if oldLeader not in node: # election still isn't done, errors
2927 main.log.error(
2928 "Old leader was not elected on at least one node" )
2929 positionResult = main.FALSE
2930 newAllCandidates.append( node )
2931 newLeaders.append( node[ 0 ] )
2932 newCandidates = newAllCandidates[ 0 ]
2933
2934 # Check that each node has the same leader. Defines newLeader
2935 if len( set( newLeaders ) ) != 1:
2936 positionResult = main.FALSE
2937 main.log.error( "Nodes have different leaders: " +
2938 str( newLeaders ) )
2939 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002940 else:
acsmars71adceb2015-08-31 15:09:26 -07002941 newLeader = newLeaders[ 0 ]
2942
2943 # Check that each node's candidate list is the same
2944 for candidates in newAllCandidates:
2945 if set( candidates ) != set( newCandidates ):
2946 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002947 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002948
2949 # Check that the re-elected node is last on the candidate List
2950 if oldLeader != newCandidates[ -1 ]:
2951 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2952 str( newCandidates ) )
2953 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002954
2955 utilities.assert_equals(
2956 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002957 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002958 onpass="Old leader successfully re-ran for election",
2959 onfail="Something went wrong with Leadership election after " +
2960 "the old leader re-ran for election" )
2961
2962 def CASE16( self, main ):
2963 """
2964 Install Distributed Primitives app
2965 """
2966 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002967 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002968 assert main, "main not defined"
2969 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002970 assert main.CLIs, "main.CLIs not defined"
2971 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002972
2973 # Variables for the distributed primitives tests
2974 global pCounterName
2975 global iCounterName
2976 global pCounterValue
2977 global iCounterValue
2978 global onosSet
2979 global onosSetName
2980 pCounterName = "TestON-Partitions"
2981 iCounterName = "TestON-inMemory"
2982 pCounterValue = 0
2983 iCounterValue = 0
2984 onosSet = set([])
2985 onosSetName = "TestON-set"
2986
2987 description = "Install Primitives app"
2988 main.case( description )
2989 main.step( "Install Primitives app" )
2990 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07002991 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002992 utilities.assert_equals( expect=main.TRUE,
2993 actual=appResults,
2994 onpass="Primitives app activated",
2995 onfail="Primitives app not activated" )
2996 time.sleep( 5 ) # To allow all nodes to activate
2997
2998 def CASE17( self, main ):
2999 """
3000 Check for basic functionality with distributed primitives
3001 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003002 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003003 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003004 assert main, "main not defined"
3005 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003006 assert main.CLIs, "main.CLIs not defined"
3007 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003008 assert pCounterName, "pCounterName not defined"
3009 assert iCounterName, "iCounterName not defined"
3010 assert onosSetName, "onosSetName not defined"
3011 # NOTE: assert fails if value is 0/None/Empty/False
3012 try:
3013 pCounterValue
3014 except NameError:
3015 main.log.error( "pCounterValue not defined, setting to 0" )
3016 pCounterValue = 0
3017 try:
3018 iCounterValue
3019 except NameError:
3020 main.log.error( "iCounterValue not defined, setting to 0" )
3021 iCounterValue = 0
3022 try:
3023 onosSet
3024 except NameError:
3025 main.log.error( "onosSet not defined, setting to empty Set" )
3026 onosSet = set([])
3027 # Variables for the distributed primitives tests. These are local only
3028 addValue = "a"
3029 addAllValue = "a b c d e f"
3030 retainValue = "c d e f"
3031
3032 description = "Check for basic functionality with distributed " +\
3033 "primitives"
3034 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003035 main.caseExplanation = "Test the methods of the distributed " +\
3036 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003037 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003038 # Partitioned counters
3039 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003040 pCounters = []
3041 threads = []
3042 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003043 for i in range( main.numCtrls ):
3044 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3045 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003046 args=[ pCounterName ] )
3047 pCounterValue += 1
3048 addedPValues.append( pCounterValue )
3049 threads.append( t )
3050 t.start()
3051
3052 for t in threads:
3053 t.join()
3054 pCounters.append( t.result )
3055 # Check that counter incremented numController times
3056 pCounterResults = True
3057 for i in addedPValues:
3058 tmpResult = i in pCounters
3059 pCounterResults = pCounterResults and tmpResult
3060 if not tmpResult:
3061 main.log.error( str( i ) + " is not in partitioned "
3062 "counter incremented results" )
3063 utilities.assert_equals( expect=True,
3064 actual=pCounterResults,
3065 onpass="Default counter incremented",
3066 onfail="Error incrementing default" +
3067 " counter" )
3068
Jon Halle1a3b752015-07-22 13:02:46 -07003069 main.step( "Get then Increment a default counter on each node" )
3070 pCounters = []
3071 threads = []
3072 addedPValues = []
3073 for i in range( main.numCtrls ):
3074 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3075 name="counterGetAndAdd-" + str( i ),
3076 args=[ pCounterName ] )
3077 addedPValues.append( pCounterValue )
3078 pCounterValue += 1
3079 threads.append( t )
3080 t.start()
3081
3082 for t in threads:
3083 t.join()
3084 pCounters.append( t.result )
3085 # Check that counter incremented numController times
3086 pCounterResults = True
3087 for i in addedPValues:
3088 tmpResult = i in pCounters
3089 pCounterResults = pCounterResults and tmpResult
3090 if not tmpResult:
3091 main.log.error( str( i ) + " is not in partitioned "
3092 "counter incremented results" )
3093 utilities.assert_equals( expect=True,
3094 actual=pCounterResults,
3095 onpass="Default counter incremented",
3096 onfail="Error incrementing default" +
3097 " counter" )
3098
3099 main.step( "Counters we added have the correct values" )
3100 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3101 utilities.assert_equals( expect=main.TRUE,
3102 actual=incrementCheck,
3103 onpass="Added counters are correct",
3104 onfail="Added counters are incorrect" )
3105
3106 main.step( "Add -8 to then get a default counter on each node" )
3107 pCounters = []
3108 threads = []
3109 addedPValues = []
3110 for i in range( main.numCtrls ):
3111 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3112 name="counterIncrement-" + str( i ),
3113 args=[ pCounterName ],
3114 kwargs={ "delta": -8 } )
3115 pCounterValue += -8
3116 addedPValues.append( pCounterValue )
3117 threads.append( t )
3118 t.start()
3119
3120 for t in threads:
3121 t.join()
3122 pCounters.append( t.result )
3123 # Check that counter incremented numController times
3124 pCounterResults = True
3125 for i in addedPValues:
3126 tmpResult = i in pCounters
3127 pCounterResults = pCounterResults and tmpResult
3128 if not tmpResult:
3129 main.log.error( str( i ) + " is not in partitioned "
3130 "counter incremented results" )
3131 utilities.assert_equals( expect=True,
3132 actual=pCounterResults,
3133 onpass="Default counter incremented",
3134 onfail="Error incrementing default" +
3135 " counter" )
3136
3137 main.step( "Add 5 to then get a default counter on each node" )
3138 pCounters = []
3139 threads = []
3140 addedPValues = []
3141 for i in range( main.numCtrls ):
3142 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3143 name="counterIncrement-" + str( i ),
3144 args=[ pCounterName ],
3145 kwargs={ "delta": 5 } )
3146 pCounterValue += 5
3147 addedPValues.append( pCounterValue )
3148 threads.append( t )
3149 t.start()
3150
3151 for t in threads:
3152 t.join()
3153 pCounters.append( t.result )
3154 # Check that counter incremented numController times
3155 pCounterResults = True
3156 for i in addedPValues:
3157 tmpResult = i in pCounters
3158 pCounterResults = pCounterResults and tmpResult
3159 if not tmpResult:
3160 main.log.error( str( i ) + " is not in partitioned "
3161 "counter incremented results" )
3162 utilities.assert_equals( expect=True,
3163 actual=pCounterResults,
3164 onpass="Default counter incremented",
3165 onfail="Error incrementing default" +
3166 " counter" )
3167
3168 main.step( "Get then add 5 to a default counter on each node" )
3169 pCounters = []
3170 threads = []
3171 addedPValues = []
3172 for i in range( main.numCtrls ):
3173 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3174 name="counterIncrement-" + str( i ),
3175 args=[ pCounterName ],
3176 kwargs={ "delta": 5 } )
3177 addedPValues.append( pCounterValue )
3178 pCounterValue += 5
3179 threads.append( t )
3180 t.start()
3181
3182 for t in threads:
3183 t.join()
3184 pCounters.append( t.result )
3185 # Check that counter incremented numController times
3186 pCounterResults = True
3187 for i in addedPValues:
3188 tmpResult = i in pCounters
3189 pCounterResults = pCounterResults and tmpResult
3190 if not tmpResult:
3191 main.log.error( str( i ) + " is not in partitioned "
3192 "counter incremented results" )
3193 utilities.assert_equals( expect=True,
3194 actual=pCounterResults,
3195 onpass="Default counter incremented",
3196 onfail="Error incrementing default" +
3197 " counter" )
3198
3199 main.step( "Counters we added have the correct values" )
3200 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3201 utilities.assert_equals( expect=main.TRUE,
3202 actual=incrementCheck,
3203 onpass="Added counters are correct",
3204 onfail="Added counters are incorrect" )
3205
3206 # In-Memory counters
3207 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003208 iCounters = []
3209 addedIValues = []
3210 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003211 for i in range( main.numCtrls ):
3212 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003213 name="icounterIncrement-" + str( i ),
3214 args=[ iCounterName ],
3215 kwargs={ "inMemory": True } )
3216 iCounterValue += 1
3217 addedIValues.append( iCounterValue )
3218 threads.append( t )
3219 t.start()
3220
3221 for t in threads:
3222 t.join()
3223 iCounters.append( t.result )
3224 # Check that counter incremented numController times
3225 iCounterResults = True
3226 for i in addedIValues:
3227 tmpResult = i in iCounters
3228 iCounterResults = iCounterResults and tmpResult
3229 if not tmpResult:
3230 main.log.error( str( i ) + " is not in the in-memory "
3231 "counter incremented results" )
3232 utilities.assert_equals( expect=True,
3233 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003234 onpass="In-memory counter incremented",
3235 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003236 " counter" )
3237
Jon Halle1a3b752015-07-22 13:02:46 -07003238 main.step( "Get then Increment a in-memory counter on each node" )
3239 iCounters = []
3240 threads = []
3241 addedIValues = []
3242 for i in range( main.numCtrls ):
3243 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3244 name="counterGetAndAdd-" + str( i ),
3245 args=[ iCounterName ],
3246 kwargs={ "inMemory": True } )
3247 addedIValues.append( iCounterValue )
3248 iCounterValue += 1
3249 threads.append( t )
3250 t.start()
3251
3252 for t in threads:
3253 t.join()
3254 iCounters.append( t.result )
3255 # Check that counter incremented numController times
3256 iCounterResults = True
3257 for i in addedIValues:
3258 tmpResult = i in iCounters
3259 iCounterResults = iCounterResults and tmpResult
3260 if not tmpResult:
3261 main.log.error( str( i ) + " is not in in-memory "
3262 "counter incremented results" )
3263 utilities.assert_equals( expect=True,
3264 actual=iCounterResults,
3265 onpass="In-memory counter incremented",
3266 onfail="Error incrementing in-memory" +
3267 " counter" )
3268
3269 main.step( "Counters we added have the correct values" )
3270 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3271 utilities.assert_equals( expect=main.TRUE,
3272 actual=incrementCheck,
3273 onpass="Added counters are correct",
3274 onfail="Added counters are incorrect" )
3275
3276 main.step( "Add -8 to then get a in-memory counter on each node" )
3277 iCounters = []
3278 threads = []
3279 addedIValues = []
3280 for i in range( main.numCtrls ):
3281 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3282 name="counterIncrement-" + str( i ),
3283 args=[ iCounterName ],
3284 kwargs={ "delta": -8, "inMemory": True } )
3285 iCounterValue += -8
3286 addedIValues.append( iCounterValue )
3287 threads.append( t )
3288 t.start()
3289
3290 for t in threads:
3291 t.join()
3292 iCounters.append( t.result )
3293 # Check that counter incremented numController times
3294 iCounterResults = True
3295 for i in addedIValues:
3296 tmpResult = i in iCounters
3297 iCounterResults = iCounterResults and tmpResult
3298 if not tmpResult:
3299 main.log.error( str( i ) + " is not in in-memory "
3300 "counter incremented results" )
3301 utilities.assert_equals( expect=True,
3302 actual=pCounterResults,
3303 onpass="In-memory counter incremented",
3304 onfail="Error incrementing in-memory" +
3305 " counter" )
3306
3307 main.step( "Add 5 to then get a in-memory counter on each node" )
3308 iCounters = []
3309 threads = []
3310 addedIValues = []
3311 for i in range( main.numCtrls ):
3312 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3313 name="counterIncrement-" + str( i ),
3314 args=[ iCounterName ],
3315 kwargs={ "delta": 5, "inMemory": True } )
3316 iCounterValue += 5
3317 addedIValues.append( iCounterValue )
3318 threads.append( t )
3319 t.start()
3320
3321 for t in threads:
3322 t.join()
3323 iCounters.append( t.result )
3324 # Check that counter incremented numController times
3325 iCounterResults = True
3326 for i in addedIValues:
3327 tmpResult = i in iCounters
3328 iCounterResults = iCounterResults and tmpResult
3329 if not tmpResult:
3330 main.log.error( str( i ) + " is not in in-memory "
3331 "counter incremented results" )
3332 utilities.assert_equals( expect=True,
3333 actual=pCounterResults,
3334 onpass="In-memory counter incremented",
3335 onfail="Error incrementing in-memory" +
3336 " counter" )
3337
3338 main.step( "Get then add 5 to a in-memory counter on each node" )
3339 iCounters = []
3340 threads = []
3341 addedIValues = []
3342 for i in range( main.numCtrls ):
3343 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3344 name="counterIncrement-" + str( i ),
3345 args=[ iCounterName ],
3346 kwargs={ "delta": 5, "inMemory": True } )
3347 addedIValues.append( iCounterValue )
3348 iCounterValue += 5
3349 threads.append( t )
3350 t.start()
3351
3352 for t in threads:
3353 t.join()
3354 iCounters.append( t.result )
3355 # Check that counter incremented numController times
3356 iCounterResults = True
3357 for i in addedIValues:
3358 tmpResult = i in iCounters
3359 iCounterResults = iCounterResults and tmpResult
3360 if not tmpResult:
3361 main.log.error( str( i ) + " is not in in-memory "
3362 "counter incremented results" )
3363 utilities.assert_equals( expect=True,
3364 actual=iCounterResults,
3365 onpass="In-memory counter incremented",
3366 onfail="Error incrementing in-memory" +
3367 " counter" )
3368
3369 main.step( "Counters we added have the correct values" )
3370 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3371 utilities.assert_equals( expect=main.TRUE,
3372 actual=incrementCheck,
3373 onpass="Added counters are correct",
3374 onfail="Added counters are incorrect" )
3375
Jon Hall5cf14d52015-07-16 12:15:19 -07003376 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003377 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003378 utilities.assert_equals( expect=main.TRUE,
3379 actual=consistentCounterResults,
3380 onpass="ONOS counters are consistent " +
3381 "across nodes",
3382 onfail="ONOS Counters are inconsistent " +
3383 "across nodes" )
3384
3385 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003386 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3387 incrementCheck = incrementCheck and \
3388 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003389 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003390 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003391 onpass="Added counters are correct",
3392 onfail="Added counters are incorrect" )
3393 # DISTRIBUTED SETS
3394 main.step( "Distributed Set get" )
3395 size = len( onosSet )
3396 getResponses = []
3397 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003398 for i in range( main.numCtrls ):
3399 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003400 name="setTestGet-" + str( i ),
3401 args=[ onosSetName ] )
3402 threads.append( t )
3403 t.start()
3404 for t in threads:
3405 t.join()
3406 getResponses.append( t.result )
3407
3408 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003409 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003410 if isinstance( getResponses[ i ], list):
3411 current = set( getResponses[ i ] )
3412 if len( current ) == len( getResponses[ i ] ):
3413 # no repeats
3414 if onosSet != current:
3415 main.log.error( "ONOS" + str( i + 1 ) +
3416 " has incorrect view" +
3417 " of set " + onosSetName + ":\n" +
3418 str( getResponses[ i ] ) )
3419 main.log.debug( "Expected: " + str( onosSet ) )
3420 main.log.debug( "Actual: " + str( current ) )
3421 getResults = main.FALSE
3422 else:
3423 # error, set is not a set
3424 main.log.error( "ONOS" + str( i + 1 ) +
3425 " has repeat elements in" +
3426 " set " + onosSetName + ":\n" +
3427 str( getResponses[ i ] ) )
3428 getResults = main.FALSE
3429 elif getResponses[ i ] == main.ERROR:
3430 getResults = main.FALSE
3431 utilities.assert_equals( expect=main.TRUE,
3432 actual=getResults,
3433 onpass="Set elements are correct",
3434 onfail="Set elements are incorrect" )
3435
3436 main.step( "Distributed Set size" )
3437 sizeResponses = []
3438 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003439 for i in range( main.numCtrls ):
3440 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003441 name="setTestSize-" + str( i ),
3442 args=[ onosSetName ] )
3443 threads.append( t )
3444 t.start()
3445 for t in threads:
3446 t.join()
3447 sizeResponses.append( t.result )
3448
3449 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003450 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003451 if size != sizeResponses[ i ]:
3452 sizeResults = main.FALSE
3453 main.log.error( "ONOS" + str( i + 1 ) +
3454 " expected a size of " + str( size ) +
3455 " for set " + onosSetName +
3456 " but got " + str( sizeResponses[ i ] ) )
3457 utilities.assert_equals( expect=main.TRUE,
3458 actual=sizeResults,
3459 onpass="Set sizes are correct",
3460 onfail="Set sizes are incorrect" )
3461
3462 main.step( "Distributed Set add()" )
3463 onosSet.add( addValue )
3464 addResponses = []
3465 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003466 for i in range( main.numCtrls ):
3467 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003468 name="setTestAdd-" + str( i ),
3469 args=[ onosSetName, addValue ] )
3470 threads.append( t )
3471 t.start()
3472 for t in threads:
3473 t.join()
3474 addResponses.append( t.result )
3475
3476 # main.TRUE = successfully changed the set
3477 # main.FALSE = action resulted in no change in set
3478 # main.ERROR - Some error in executing the function
3479 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003480 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003481 if addResponses[ i ] == main.TRUE:
3482 # All is well
3483 pass
3484 elif addResponses[ i ] == main.FALSE:
3485 # Already in set, probably fine
3486 pass
3487 elif addResponses[ i ] == main.ERROR:
3488 # Error in execution
3489 addResults = main.FALSE
3490 else:
3491 # unexpected result
3492 addResults = main.FALSE
3493 if addResults != main.TRUE:
3494 main.log.error( "Error executing set add" )
3495
3496 # Check if set is still correct
3497 size = len( onosSet )
3498 getResponses = []
3499 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003500 for i in range( main.numCtrls ):
3501 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003502 name="setTestGet-" + str( i ),
3503 args=[ onosSetName ] )
3504 threads.append( t )
3505 t.start()
3506 for t in threads:
3507 t.join()
3508 getResponses.append( t.result )
3509 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003510 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003511 if isinstance( getResponses[ i ], list):
3512 current = set( getResponses[ i ] )
3513 if len( current ) == len( getResponses[ i ] ):
3514 # no repeats
3515 if onosSet != current:
3516 main.log.error( "ONOS" + str( i + 1 ) +
3517 " has incorrect view" +
3518 " of set " + onosSetName + ":\n" +
3519 str( getResponses[ i ] ) )
3520 main.log.debug( "Expected: " + str( onosSet ) )
3521 main.log.debug( "Actual: " + str( current ) )
3522 getResults = main.FALSE
3523 else:
3524 # error, set is not a set
3525 main.log.error( "ONOS" + str( i + 1 ) +
3526 " has repeat elements in" +
3527 " set " + onosSetName + ":\n" +
3528 str( getResponses[ i ] ) )
3529 getResults = main.FALSE
3530 elif getResponses[ i ] == main.ERROR:
3531 getResults = main.FALSE
3532 sizeResponses = []
3533 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003534 for i in range( main.numCtrls ):
3535 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003536 name="setTestSize-" + str( i ),
3537 args=[ onosSetName ] )
3538 threads.append( t )
3539 t.start()
3540 for t in threads:
3541 t.join()
3542 sizeResponses.append( t.result )
3543 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003544 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003545 if size != sizeResponses[ i ]:
3546 sizeResults = main.FALSE
3547 main.log.error( "ONOS" + str( i + 1 ) +
3548 " expected a size of " + str( size ) +
3549 " for set " + onosSetName +
3550 " but got " + str( sizeResponses[ i ] ) )
3551 addResults = addResults and getResults and sizeResults
3552 utilities.assert_equals( expect=main.TRUE,
3553 actual=addResults,
3554 onpass="Set add correct",
3555 onfail="Set add was incorrect" )
3556
3557 main.step( "Distributed Set addAll()" )
3558 onosSet.update( addAllValue.split() )
3559 addResponses = []
3560 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003561 for i in range( main.numCtrls ):
3562 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003563 name="setTestAddAll-" + str( i ),
3564 args=[ onosSetName, addAllValue ] )
3565 threads.append( t )
3566 t.start()
3567 for t in threads:
3568 t.join()
3569 addResponses.append( t.result )
3570
3571 # main.TRUE = successfully changed the set
3572 # main.FALSE = action resulted in no change in set
3573 # main.ERROR - Some error in executing the function
3574 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003575 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003576 if addResponses[ i ] == main.TRUE:
3577 # All is well
3578 pass
3579 elif addResponses[ i ] == main.FALSE:
3580 # Already in set, probably fine
3581 pass
3582 elif addResponses[ i ] == main.ERROR:
3583 # Error in execution
3584 addAllResults = main.FALSE
3585 else:
3586 # unexpected result
3587 addAllResults = main.FALSE
3588 if addAllResults != main.TRUE:
3589 main.log.error( "Error executing set addAll" )
3590
3591 # Check if set is still correct
3592 size = len( onosSet )
3593 getResponses = []
3594 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003595 for i in range( main.numCtrls ):
3596 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003597 name="setTestGet-" + str( i ),
3598 args=[ onosSetName ] )
3599 threads.append( t )
3600 t.start()
3601 for t in threads:
3602 t.join()
3603 getResponses.append( t.result )
3604 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003605 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003606 if isinstance( getResponses[ i ], list):
3607 current = set( getResponses[ i ] )
3608 if len( current ) == len( getResponses[ i ] ):
3609 # no repeats
3610 if onosSet != current:
3611 main.log.error( "ONOS" + str( i + 1 ) +
3612 " has incorrect view" +
3613 " of set " + onosSetName + ":\n" +
3614 str( getResponses[ i ] ) )
3615 main.log.debug( "Expected: " + str( onosSet ) )
3616 main.log.debug( "Actual: " + str( current ) )
3617 getResults = main.FALSE
3618 else:
3619 # error, set is not a set
3620 main.log.error( "ONOS" + str( i + 1 ) +
3621 " has repeat elements in" +
3622 " set " + onosSetName + ":\n" +
3623 str( getResponses[ i ] ) )
3624 getResults = main.FALSE
3625 elif getResponses[ i ] == main.ERROR:
3626 getResults = main.FALSE
3627 sizeResponses = []
3628 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003629 for i in range( main.numCtrls ):
3630 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003631 name="setTestSize-" + str( i ),
3632 args=[ onosSetName ] )
3633 threads.append( t )
3634 t.start()
3635 for t in threads:
3636 t.join()
3637 sizeResponses.append( t.result )
3638 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003639 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003640 if size != sizeResponses[ i ]:
3641 sizeResults = main.FALSE
3642 main.log.error( "ONOS" + str( i + 1 ) +
3643 " expected a size of " + str( size ) +
3644 " for set " + onosSetName +
3645 " but got " + str( sizeResponses[ i ] ) )
3646 addAllResults = addAllResults and getResults and sizeResults
3647 utilities.assert_equals( expect=main.TRUE,
3648 actual=addAllResults,
3649 onpass="Set addAll correct",
3650 onfail="Set addAll was incorrect" )
3651
3652 main.step( "Distributed Set contains()" )
3653 containsResponses = []
3654 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003655 for i in range( main.numCtrls ):
3656 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003657 name="setContains-" + str( i ),
3658 args=[ onosSetName ],
3659 kwargs={ "values": addValue } )
3660 threads.append( t )
3661 t.start()
3662 for t in threads:
3663 t.join()
3664 # NOTE: This is the tuple
3665 containsResponses.append( t.result )
3666
3667 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003668 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003669 if containsResponses[ i ] == main.ERROR:
3670 containsResults = main.FALSE
3671 else:
3672 containsResults = containsResults and\
3673 containsResponses[ i ][ 1 ]
3674 utilities.assert_equals( expect=main.TRUE,
3675 actual=containsResults,
3676 onpass="Set contains is functional",
3677 onfail="Set contains failed" )
3678
3679 main.step( "Distributed Set containsAll()" )
3680 containsAllResponses = []
3681 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003682 for i in range( main.numCtrls ):
3683 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003684 name="setContainsAll-" + str( i ),
3685 args=[ onosSetName ],
3686 kwargs={ "values": addAllValue } )
3687 threads.append( t )
3688 t.start()
3689 for t in threads:
3690 t.join()
3691 # NOTE: This is the tuple
3692 containsAllResponses.append( t.result )
3693
3694 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003695 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003696 if containsResponses[ i ] == main.ERROR:
3697 containsResults = main.FALSE
3698 else:
3699 containsResults = containsResults and\
3700 containsResponses[ i ][ 1 ]
3701 utilities.assert_equals( expect=main.TRUE,
3702 actual=containsAllResults,
3703 onpass="Set containsAll is functional",
3704 onfail="Set containsAll failed" )
3705
3706 main.step( "Distributed Set remove()" )
3707 onosSet.remove( addValue )
3708 removeResponses = []
3709 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003710 for i in range( main.numCtrls ):
3711 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003712 name="setTestRemove-" + str( i ),
3713 args=[ onosSetName, addValue ] )
3714 threads.append( t )
3715 t.start()
3716 for t in threads:
3717 t.join()
3718 removeResponses.append( t.result )
3719
3720 # main.TRUE = successfully changed the set
3721 # main.FALSE = action resulted in no change in set
3722 # main.ERROR - Some error in executing the function
3723 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003724 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003725 if removeResponses[ i ] == main.TRUE:
3726 # All is well
3727 pass
3728 elif removeResponses[ i ] == main.FALSE:
3729 # not in set, probably fine
3730 pass
3731 elif removeResponses[ i ] == main.ERROR:
3732 # Error in execution
3733 removeResults = main.FALSE
3734 else:
3735 # unexpected result
3736 removeResults = main.FALSE
3737 if removeResults != main.TRUE:
3738 main.log.error( "Error executing set remove" )
3739
3740 # Check if set is still correct
3741 size = len( onosSet )
3742 getResponses = []
3743 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003744 for i in range( main.numCtrls ):
3745 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003746 name="setTestGet-" + str( i ),
3747 args=[ onosSetName ] )
3748 threads.append( t )
3749 t.start()
3750 for t in threads:
3751 t.join()
3752 getResponses.append( t.result )
3753 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003754 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003755 if isinstance( getResponses[ i ], list):
3756 current = set( getResponses[ i ] )
3757 if len( current ) == len( getResponses[ i ] ):
3758 # no repeats
3759 if onosSet != current:
3760 main.log.error( "ONOS" + str( i + 1 ) +
3761 " has incorrect view" +
3762 " of set " + onosSetName + ":\n" +
3763 str( getResponses[ i ] ) )
3764 main.log.debug( "Expected: " + str( onosSet ) )
3765 main.log.debug( "Actual: " + str( current ) )
3766 getResults = main.FALSE
3767 else:
3768 # error, set is not a set
3769 main.log.error( "ONOS" + str( i + 1 ) +
3770 " has repeat elements in" +
3771 " set " + onosSetName + ":\n" +
3772 str( getResponses[ i ] ) )
3773 getResults = main.FALSE
3774 elif getResponses[ i ] == main.ERROR:
3775 getResults = main.FALSE
3776 sizeResponses = []
3777 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003778 for i in range( main.numCtrls ):
3779 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003780 name="setTestSize-" + str( i ),
3781 args=[ onosSetName ] )
3782 threads.append( t )
3783 t.start()
3784 for t in threads:
3785 t.join()
3786 sizeResponses.append( t.result )
3787 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003788 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003789 if size != sizeResponses[ i ]:
3790 sizeResults = main.FALSE
3791 main.log.error( "ONOS" + str( i + 1 ) +
3792 " expected a size of " + str( size ) +
3793 " for set " + onosSetName +
3794 " but got " + str( sizeResponses[ i ] ) )
3795 removeResults = removeResults and getResults and sizeResults
3796 utilities.assert_equals( expect=main.TRUE,
3797 actual=removeResults,
3798 onpass="Set remove correct",
3799 onfail="Set remove was incorrect" )
3800
3801 main.step( "Distributed Set removeAll()" )
3802 onosSet.difference_update( addAllValue.split() )
3803 removeAllResponses = []
3804 threads = []
3805 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003806 for i in range( main.numCtrls ):
3807 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003808 name="setTestRemoveAll-" + str( i ),
3809 args=[ onosSetName, addAllValue ] )
3810 threads.append( t )
3811 t.start()
3812 for t in threads:
3813 t.join()
3814 removeAllResponses.append( t.result )
3815 except Exception, e:
3816 main.log.exception(e)
3817
3818 # main.TRUE = successfully changed the set
3819 # main.FALSE = action resulted in no change in set
3820 # main.ERROR - Some error in executing the function
3821 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003822 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 if removeAllResponses[ i ] == main.TRUE:
3824 # All is well
3825 pass
3826 elif removeAllResponses[ i ] == main.FALSE:
3827 # not in set, probably fine
3828 pass
3829 elif removeAllResponses[ i ] == main.ERROR:
3830 # Error in execution
3831 removeAllResults = main.FALSE
3832 else:
3833 # unexpected result
3834 removeAllResults = main.FALSE
3835 if removeAllResults != main.TRUE:
3836 main.log.error( "Error executing set removeAll" )
3837
3838 # Check if set is still correct
3839 size = len( onosSet )
3840 getResponses = []
3841 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003842 for i in range( main.numCtrls ):
3843 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003844 name="setTestGet-" + str( i ),
3845 args=[ onosSetName ] )
3846 threads.append( t )
3847 t.start()
3848 for t in threads:
3849 t.join()
3850 getResponses.append( t.result )
3851 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003852 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003853 if isinstance( getResponses[ i ], list):
3854 current = set( getResponses[ i ] )
3855 if len( current ) == len( getResponses[ i ] ):
3856 # no repeats
3857 if onosSet != current:
3858 main.log.error( "ONOS" + str( i + 1 ) +
3859 " has incorrect view" +
3860 " of set " + onosSetName + ":\n" +
3861 str( getResponses[ i ] ) )
3862 main.log.debug( "Expected: " + str( onosSet ) )
3863 main.log.debug( "Actual: " + str( current ) )
3864 getResults = main.FALSE
3865 else:
3866 # error, set is not a set
3867 main.log.error( "ONOS" + str( i + 1 ) +
3868 " has repeat elements in" +
3869 " set " + onosSetName + ":\n" +
3870 str( getResponses[ i ] ) )
3871 getResults = main.FALSE
3872 elif getResponses[ i ] == main.ERROR:
3873 getResults = main.FALSE
3874 sizeResponses = []
3875 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003876 for i in range( main.numCtrls ):
3877 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003878 name="setTestSize-" + str( i ),
3879 args=[ onosSetName ] )
3880 threads.append( t )
3881 t.start()
3882 for t in threads:
3883 t.join()
3884 sizeResponses.append( t.result )
3885 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003886 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003887 if size != sizeResponses[ i ]:
3888 sizeResults = main.FALSE
3889 main.log.error( "ONOS" + str( i + 1 ) +
3890 " expected a size of " + str( size ) +
3891 " for set " + onosSetName +
3892 " but got " + str( sizeResponses[ i ] ) )
3893 removeAllResults = removeAllResults and getResults and sizeResults
3894 utilities.assert_equals( expect=main.TRUE,
3895 actual=removeAllResults,
3896 onpass="Set removeAll correct",
3897 onfail="Set removeAll was incorrect" )
3898
3899 main.step( "Distributed Set addAll()" )
3900 onosSet.update( addAllValue.split() )
3901 addResponses = []
3902 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003903 for i in range( main.numCtrls ):
3904 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003905 name="setTestAddAll-" + str( i ),
3906 args=[ onosSetName, addAllValue ] )
3907 threads.append( t )
3908 t.start()
3909 for t in threads:
3910 t.join()
3911 addResponses.append( t.result )
3912
3913 # main.TRUE = successfully changed the set
3914 # main.FALSE = action resulted in no change in set
3915 # main.ERROR - Some error in executing the function
3916 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003917 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003918 if addResponses[ i ] == main.TRUE:
3919 # All is well
3920 pass
3921 elif addResponses[ i ] == main.FALSE:
3922 # Already in set, probably fine
3923 pass
3924 elif addResponses[ i ] == main.ERROR:
3925 # Error in execution
3926 addAllResults = main.FALSE
3927 else:
3928 # unexpected result
3929 addAllResults = main.FALSE
3930 if addAllResults != main.TRUE:
3931 main.log.error( "Error executing set addAll" )
3932
3933 # Check if set is still correct
3934 size = len( onosSet )
3935 getResponses = []
3936 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003937 for i in range( main.numCtrls ):
3938 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003939 name="setTestGet-" + str( i ),
3940 args=[ onosSetName ] )
3941 threads.append( t )
3942 t.start()
3943 for t in threads:
3944 t.join()
3945 getResponses.append( t.result )
3946 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003947 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003948 if isinstance( getResponses[ i ], list):
3949 current = set( getResponses[ i ] )
3950 if len( current ) == len( getResponses[ i ] ):
3951 # no repeats
3952 if onosSet != current:
3953 main.log.error( "ONOS" + str( i + 1 ) +
3954 " has incorrect view" +
3955 " of set " + onosSetName + ":\n" +
3956 str( getResponses[ i ] ) )
3957 main.log.debug( "Expected: " + str( onosSet ) )
3958 main.log.debug( "Actual: " + str( current ) )
3959 getResults = main.FALSE
3960 else:
3961 # error, set is not a set
3962 main.log.error( "ONOS" + str( i + 1 ) +
3963 " has repeat elements in" +
3964 " set " + onosSetName + ":\n" +
3965 str( getResponses[ i ] ) )
3966 getResults = main.FALSE
3967 elif getResponses[ i ] == main.ERROR:
3968 getResults = main.FALSE
3969 sizeResponses = []
3970 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003971 for i in range( main.numCtrls ):
3972 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003973 name="setTestSize-" + str( i ),
3974 args=[ onosSetName ] )
3975 threads.append( t )
3976 t.start()
3977 for t in threads:
3978 t.join()
3979 sizeResponses.append( t.result )
3980 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003981 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003982 if size != sizeResponses[ i ]:
3983 sizeResults = main.FALSE
3984 main.log.error( "ONOS" + str( i + 1 ) +
3985 " expected a size of " + str( size ) +
3986 " for set " + onosSetName +
3987 " but got " + str( sizeResponses[ i ] ) )
3988 addAllResults = addAllResults and getResults and sizeResults
3989 utilities.assert_equals( expect=main.TRUE,
3990 actual=addAllResults,
3991 onpass="Set addAll correct",
3992 onfail="Set addAll was incorrect" )
3993
3994 main.step( "Distributed Set clear()" )
3995 onosSet.clear()
3996 clearResponses = []
3997 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003998 for i in range( main.numCtrls ):
3999 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004000 name="setTestClear-" + str( i ),
4001 args=[ onosSetName, " "], # Values doesn't matter
4002 kwargs={ "clear": True } )
4003 threads.append( t )
4004 t.start()
4005 for t in threads:
4006 t.join()
4007 clearResponses.append( t.result )
4008
4009 # main.TRUE = successfully changed the set
4010 # main.FALSE = action resulted in no change in set
4011 # main.ERROR - Some error in executing the function
4012 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004013 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004014 if clearResponses[ i ] == main.TRUE:
4015 # All is well
4016 pass
4017 elif clearResponses[ i ] == main.FALSE:
4018 # Nothing set, probably fine
4019 pass
4020 elif clearResponses[ i ] == main.ERROR:
4021 # Error in execution
4022 clearResults = main.FALSE
4023 else:
4024 # unexpected result
4025 clearResults = main.FALSE
4026 if clearResults != main.TRUE:
4027 main.log.error( "Error executing set clear" )
4028
4029 # Check if set is still correct
4030 size = len( onosSet )
4031 getResponses = []
4032 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004033 for i in range( main.numCtrls ):
4034 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004035 name="setTestGet-" + str( i ),
4036 args=[ onosSetName ] )
4037 threads.append( t )
4038 t.start()
4039 for t in threads:
4040 t.join()
4041 getResponses.append( t.result )
4042 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004043 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004044 if isinstance( getResponses[ i ], list):
4045 current = set( getResponses[ i ] )
4046 if len( current ) == len( getResponses[ i ] ):
4047 # no repeats
4048 if onosSet != current:
4049 main.log.error( "ONOS" + str( i + 1 ) +
4050 " has incorrect view" +
4051 " of set " + onosSetName + ":\n" +
4052 str( getResponses[ i ] ) )
4053 main.log.debug( "Expected: " + str( onosSet ) )
4054 main.log.debug( "Actual: " + str( current ) )
4055 getResults = main.FALSE
4056 else:
4057 # error, set is not a set
4058 main.log.error( "ONOS" + str( i + 1 ) +
4059 " has repeat elements in" +
4060 " set " + onosSetName + ":\n" +
4061 str( getResponses[ i ] ) )
4062 getResults = main.FALSE
4063 elif getResponses[ i ] == main.ERROR:
4064 getResults = main.FALSE
4065 sizeResponses = []
4066 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004067 for i in range( main.numCtrls ):
4068 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004069 name="setTestSize-" + str( i ),
4070 args=[ onosSetName ] )
4071 threads.append( t )
4072 t.start()
4073 for t in threads:
4074 t.join()
4075 sizeResponses.append( t.result )
4076 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004077 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004078 if size != sizeResponses[ i ]:
4079 sizeResults = main.FALSE
4080 main.log.error( "ONOS" + str( i + 1 ) +
4081 " expected a size of " + str( size ) +
4082 " for set " + onosSetName +
4083 " but got " + str( sizeResponses[ i ] ) )
4084 clearResults = clearResults and getResults and sizeResults
4085 utilities.assert_equals( expect=main.TRUE,
4086 actual=clearResults,
4087 onpass="Set clear correct",
4088 onfail="Set clear was incorrect" )
4089
4090 main.step( "Distributed Set addAll()" )
4091 onosSet.update( addAllValue.split() )
4092 addResponses = []
4093 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004094 for i in range( main.numCtrls ):
4095 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004096 name="setTestAddAll-" + str( i ),
4097 args=[ onosSetName, addAllValue ] )
4098 threads.append( t )
4099 t.start()
4100 for t in threads:
4101 t.join()
4102 addResponses.append( t.result )
4103
4104 # main.TRUE = successfully changed the set
4105 # main.FALSE = action resulted in no change in set
4106 # main.ERROR - Some error in executing the function
4107 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004108 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004109 if addResponses[ i ] == main.TRUE:
4110 # All is well
4111 pass
4112 elif addResponses[ i ] == main.FALSE:
4113 # Already in set, probably fine
4114 pass
4115 elif addResponses[ i ] == main.ERROR:
4116 # Error in execution
4117 addAllResults = main.FALSE
4118 else:
4119 # unexpected result
4120 addAllResults = main.FALSE
4121 if addAllResults != main.TRUE:
4122 main.log.error( "Error executing set addAll" )
4123
4124 # Check if set is still correct
4125 size = len( onosSet )
4126 getResponses = []
4127 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004128 for i in range( main.numCtrls ):
4129 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004130 name="setTestGet-" + str( i ),
4131 args=[ onosSetName ] )
4132 threads.append( t )
4133 t.start()
4134 for t in threads:
4135 t.join()
4136 getResponses.append( t.result )
4137 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004138 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004139 if isinstance( getResponses[ i ], list):
4140 current = set( getResponses[ i ] )
4141 if len( current ) == len( getResponses[ i ] ):
4142 # no repeats
4143 if onosSet != current:
4144 main.log.error( "ONOS" + str( i + 1 ) +
4145 " has incorrect view" +
4146 " of set " + onosSetName + ":\n" +
4147 str( getResponses[ i ] ) )
4148 main.log.debug( "Expected: " + str( onosSet ) )
4149 main.log.debug( "Actual: " + str( current ) )
4150 getResults = main.FALSE
4151 else:
4152 # error, set is not a set
4153 main.log.error( "ONOS" + str( i + 1 ) +
4154 " has repeat elements in" +
4155 " set " + onosSetName + ":\n" +
4156 str( getResponses[ i ] ) )
4157 getResults = main.FALSE
4158 elif getResponses[ i ] == main.ERROR:
4159 getResults = main.FALSE
4160 sizeResponses = []
4161 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004162 for i in range( main.numCtrls ):
4163 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004164 name="setTestSize-" + str( i ),
4165 args=[ onosSetName ] )
4166 threads.append( t )
4167 t.start()
4168 for t in threads:
4169 t.join()
4170 sizeResponses.append( t.result )
4171 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004172 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004173 if size != sizeResponses[ i ]:
4174 sizeResults = main.FALSE
4175 main.log.error( "ONOS" + str( i + 1 ) +
4176 " expected a size of " + str( size ) +
4177 " for set " + onosSetName +
4178 " but got " + str( sizeResponses[ i ] ) )
4179 addAllResults = addAllResults and getResults and sizeResults
4180 utilities.assert_equals( expect=main.TRUE,
4181 actual=addAllResults,
4182 onpass="Set addAll correct",
4183 onfail="Set addAll was incorrect" )
4184
4185 main.step( "Distributed Set retain()" )
4186 onosSet.intersection_update( retainValue.split() )
4187 retainResponses = []
4188 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004189 for i in range( main.numCtrls ):
4190 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004191 name="setTestRetain-" + str( i ),
4192 args=[ onosSetName, retainValue ],
4193 kwargs={ "retain": True } )
4194 threads.append( t )
4195 t.start()
4196 for t in threads:
4197 t.join()
4198 retainResponses.append( t.result )
4199
4200 # main.TRUE = successfully changed the set
4201 # main.FALSE = action resulted in no change in set
4202 # main.ERROR - Some error in executing the function
4203 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004204 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004205 if retainResponses[ i ] == main.TRUE:
4206 # All is well
4207 pass
4208 elif retainResponses[ i ] == main.FALSE:
4209 # Already in set, probably fine
4210 pass
4211 elif retainResponses[ i ] == main.ERROR:
4212 # Error in execution
4213 retainResults = main.FALSE
4214 else:
4215 # unexpected result
4216 retainResults = main.FALSE
4217 if retainResults != main.TRUE:
4218 main.log.error( "Error executing set retain" )
4219
4220 # Check if set is still correct
4221 size = len( onosSet )
4222 getResponses = []
4223 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004224 for i in range( main.numCtrls ):
4225 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004226 name="setTestGet-" + str( i ),
4227 args=[ onosSetName ] )
4228 threads.append( t )
4229 t.start()
4230 for t in threads:
4231 t.join()
4232 getResponses.append( t.result )
4233 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004234 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004235 if isinstance( getResponses[ i ], list):
4236 current = set( getResponses[ i ] )
4237 if len( current ) == len( getResponses[ i ] ):
4238 # no repeats
4239 if onosSet != current:
4240 main.log.error( "ONOS" + str( i + 1 ) +
4241 " has incorrect view" +
4242 " of set " + onosSetName + ":\n" +
4243 str( getResponses[ i ] ) )
4244 main.log.debug( "Expected: " + str( onosSet ) )
4245 main.log.debug( "Actual: " + str( current ) )
4246 getResults = main.FALSE
4247 else:
4248 # error, set is not a set
4249 main.log.error( "ONOS" + str( i + 1 ) +
4250 " has repeat elements in" +
4251 " set " + onosSetName + ":\n" +
4252 str( getResponses[ i ] ) )
4253 getResults = main.FALSE
4254 elif getResponses[ i ] == main.ERROR:
4255 getResults = main.FALSE
4256 sizeResponses = []
4257 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004258 for i in range( main.numCtrls ):
4259 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004260 name="setTestSize-" + str( i ),
4261 args=[ onosSetName ] )
4262 threads.append( t )
4263 t.start()
4264 for t in threads:
4265 t.join()
4266 sizeResponses.append( t.result )
4267 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004268 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004269 if size != sizeResponses[ i ]:
4270 sizeResults = main.FALSE
4271 main.log.error( "ONOS" + str( i + 1 ) +
4272 " expected a size of " +
4273 str( size ) + " for set " + onosSetName +
4274 " but got " + str( sizeResponses[ i ] ) )
4275 retainResults = retainResults and getResults and sizeResults
4276 utilities.assert_equals( expect=main.TRUE,
4277 actual=retainResults,
4278 onpass="Set retain correct",
4279 onfail="Set retain was incorrect" )
4280
Jon Hall2a5002c2015-08-21 16:49:11 -07004281 # Transactional maps
4282 main.step( "Partitioned Transactional maps put" )
4283 tMapValue = "Testing"
4284 numKeys = 100
4285 putResult = True
4286 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4287 if len( putResponses ) == 100:
4288 for i in putResponses:
4289 if putResponses[ i ][ 'value' ] != tMapValue:
4290 putResult = False
4291 else:
4292 putResult = False
4293 if not putResult:
4294 main.log.debug( "Put response values: " + str( putResponses ) )
4295 utilities.assert_equals( expect=True,
4296 actual=putResult,
4297 onpass="Partitioned Transactional Map put successful",
4298 onfail="Partitioned Transactional Map put values are incorrect" )
4299
4300 main.step( "Partitioned Transactional maps get" )
4301 getCheck = True
4302 for n in range( 1, numKeys + 1 ):
4303 getResponses = []
4304 threads = []
4305 valueCheck = True
4306 for i in range( main.numCtrls ):
4307 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4308 name="TMap-get-" + str( i ),
4309 args=[ "Key" + str ( n ) ] )
4310 threads.append( t )
4311 t.start()
4312 for t in threads:
4313 t.join()
4314 getResponses.append( t.result )
4315 for node in getResponses:
4316 if node != tMapValue:
4317 valueCheck = False
4318 if not valueCheck:
4319 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4320 main.log.warn( getResponses )
4321 getCheck = getCheck and valueCheck
4322 utilities.assert_equals( expect=True,
4323 actual=getCheck,
4324 onpass="Partitioned Transactional Map get values were correct",
4325 onfail="Partitioned Transactional Map values incorrect" )
4326
4327 main.step( "In-memory Transactional maps put" )
4328 tMapValue = "Testing"
4329 numKeys = 100
4330 putResult = True
4331 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4332 if len( putResponses ) == 100:
4333 for i in putResponses:
4334 if putResponses[ i ][ 'value' ] != tMapValue:
4335 putResult = False
4336 else:
4337 putResult = False
4338 if not putResult:
4339 main.log.debug( "Put response values: " + str( putResponses ) )
4340 utilities.assert_equals( expect=True,
4341 actual=putResult,
4342 onpass="In-Memory Transactional Map put successful",
4343 onfail="In-Memory Transactional Map put values are incorrect" )
4344
4345 main.step( "In-Memory Transactional maps get" )
4346 getCheck = True
4347 for n in range( 1, numKeys + 1 ):
4348 getResponses = []
4349 threads = []
4350 valueCheck = True
4351 for i in range( main.numCtrls ):
4352 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4353 name="TMap-get-" + str( i ),
4354 args=[ "Key" + str ( n ) ],
4355 kwargs={ "inMemory": True } )
4356 threads.append( t )
4357 t.start()
4358 for t in threads:
4359 t.join()
4360 getResponses.append( t.result )
4361 for node in getResponses:
4362 if node != tMapValue:
4363 valueCheck = False
4364 if not valueCheck:
4365 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4366 main.log.warn( getResponses )
4367 getCheck = getCheck and valueCheck
4368 utilities.assert_equals( expect=True,
4369 actual=getCheck,
4370 onpass="In-Memory Transactional Map get values were correct",
4371 onfail="In-Memory Transactional Map values incorrect" )