blob: 438338a48479d0bd0a0754dcd436dedc6621b5c4 [file] [log] [blame]
YPZhang737d0012016-03-24 13:56:24 -07001import sys
2import json
3import time
4import os
5'''
YPZhangebf9eb52016-05-12 15:20:24 -07006SCPFscalingMaxIntents
YPZhang737d0012016-03-24 13:56:24 -07007Push test Intents to onos
8CASE10: set up Null Provider
9CASE11: set up Open Flows
10Scale up when reach the Limited
11Start from 1 nodes, 8 devices. Then Scale up to 3,5,7 nodes
12Recommand batch size: 100, check interval: 100
13'''
14class SCPFscalingMaxIntentsWithFlowObj:
15 def __init__( self ):
16 self.default = ''
17
18 def CASE0( self, main):
19 import sys
20 import json
21 import time
22 import os
23 import imp
24
25 main.case( "Constructing test variables and building ONOS package" )
26 main.step( "Constructing test variables" )
27 stepResult = main.FALSE
28
29 # Test variables
30 main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
31 main.dependencyPath = main.testOnDirectory + \
32 main.params['DEPENDENCY']['path']
33 main.cellName = main.params[ 'ENV' ][ 'cellName' ]
34 main.apps = main.params[ 'ENV' ][ 'cellApps' ]
35 main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
36 main.scale = ( main.params[ 'SCALE' ] ).split( "," )
37 main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
38 main.timeout = int(main.params['SLEEP']['timeout'])
39 main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
40 main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
41 main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
42 main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
43 main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
44 main.ingress = main.params['LINK']['ingress']
45 main.egress = main.params['LINK']['egress']
46 main.dbFileName = main.params['DATABASE']['file']
47 main.cellData = {} # for creating cell file
48 main.reroute = main.params['reroute']
49 main.threadID = 0
50
51 if main.reroute == "True":
52 main.reroute = True
53 else:
54 main.reroute = False
55
56 main.CLIs = []
YPZhang737d0012016-03-24 13:56:24 -070057 main.setupSkipped = False
58
59 wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
60 gitBranch = main.params[ 'GIT' ][ 'branch' ]
61 gitPull = main.params[ 'GIT' ][ 'pull' ]
62 nic = main.params['DATABASE']['nic']
63 node = main.params['DATABASE']['node']
64 nic = main.params['DATABASE']['nic']
65 node = main.params['DATABASE']['node']
66 stepResult = main.TRUE
67
68 main.log.info("Cresting DB file")
69 with open(main.dbFileName, "w+") as dbFile:
70 dbFile.write("")
71
72 utilities.assert_equals( expect=main.TRUE,
73 actual=stepResult,
74 onpass="environment set up successfull",
75 onfail="environment set up Failed" )
76
77 def CASE1( self ):
78 # main.scale[ 0 ] determines the current number of ONOS controller
79 main.CLIs = []
80 main.numCtrls = int( main.scale[ 0 ] )
YPZhangebf9eb52016-05-12 15:20:24 -070081 main.ONOSip = []
82 main.maxNumBatch = 0
83 main.AllONOSip = main.ONOSbench.getOnosIps()
84 for i in range(main.numCtrls):
85 main.ONOSip.append(main.AllONOSip[i])
86 main.log.info(main.ONOSip)
87
YPZhang737d0012016-03-24 13:56:24 -070088 main.log.info( "Creating list of ONOS cli handles" )
89 for i in range(main.numCtrls):
90 main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
91
92 main.log.info(main.CLIs)
93 if not main.CLIs:
94 main.log.error( "Failed to create the list of ONOS cli handles" )
95 main.cleanup()
96 main.exit()
97
98 main.log.info( "Loading wrapper files" )
99 main.startUp = imp.load_source( wrapperFile1,
100 main.dependencyPath +
101 wrapperFile1 +
102 ".py" )
103
104 copyResult = main.ONOSbench.copyMininetFile( main.topology,
105 main.dependencyPath,
106 main.Mininet1.user_name,
107 main.Mininet1.ip_address )
108
109 commit = main.ONOSbench.getVersion(report=True)
110 commit = commit.split(" ")[1]
111
112 if gitPull == 'True':
113 if not main.startUp.onosBuild( main, gitBranch ):
114 main.log.error( "Failed to build ONOS" )
115 main.cleanup()
116 main.exit()
117 else:
118 main.log.warn( "Did not pull new code so skipping mvn " +
119 "clean install" )
120 with open(main.dbFileName, "a") as dbFile:
121 temp = "'" + commit + "',"
122 temp += "'" + nic + "',"
123 dbFile.write(temp)
124
125 def CASE2( self, main ):
126 """
127 - Uninstall ONOS cluster
128 - Verify ONOS start up
129 - Install ONOS cluster
130 - Connect to cli
131 """
132 main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
133 main.log.info( "Safety check, killing all ONOS processes" +
134 " before initiating environment setup" )
135
136 for i in range( main.numCtrls ):
137 main.ONOSbench.onosDie( main.ONOSip[ i ] )
138
139 main.log.info( "NODE COUNT = %s" % main.numCtrls)
140
141 tempOnosIp = []
142 for i in range( main.numCtrls ):
143 tempOnosIp.append( main.ONOSip[i] )
144
145 main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
146 "temp",
147 main.Mininet1.ip_address,
148 main.apps,
149 tempOnosIp )
150
151 main.step( "Apply cell to environment" )
152 cellResult = main.ONOSbench.setCell( "temp" )
153 verifyResult = main.ONOSbench.verifyCell()
154 stepResult = cellResult and verifyResult
155 utilities.assert_equals( expect=main.TRUE,
156 actual=stepResult,
157 onpass="Successfully applied cell to " + \
158 "environment",
159 onfail="Failed to apply cell to environment " )
160
161 main.step( "Creating ONOS package" )
162 packageResult = main.ONOSbench.onosPackage()
163 stepResult = packageResult
164 utilities.assert_equals( expect=main.TRUE,
165 actual=stepResult,
166 onpass="Successfully created ONOS package",
167 onfail="Failed to create ONOS package" )
168
169 main.step( "Uninstall ONOS package on all Nodes" )
170 uninstallResult = main.TRUE
171 for i in range( int( main.numCtrls ) ):
172 main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
173 u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
174 utilities.assert_equals( expect=main.TRUE, actual=u_result,
175 onpass="Test step PASS",
176 onfail="Test step FAIL" )
177 uninstallResult = ( uninstallResult and u_result )
178
179 main.step( "Install ONOS package on all Nodes" )
180 installResult = main.TRUE
181 for i in range( int( main.numCtrls ) ):
182 main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
183 i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
184 utilities.assert_equals( expect=main.TRUE, actual=i_result,
185 onpass="Test step PASS",
186 onfail="Test step FAIL" )
187 installResult = installResult and i_result
188
189 main.step( "Verify ONOS nodes UP status" )
190 statusResult = main.TRUE
191 for i in range( int( main.numCtrls ) ):
192 main.log.info( "ONOS Node " + main.ONOSip[i] + " status:" )
193 onos_status = main.ONOSbench.onosStatus( node=main.ONOSip[i] )
194 utilities.assert_equals( expect=main.TRUE, actual=onos_status,
195 onpass="Test step PASS",
196 onfail="Test step FAIL" )
197 statusResult = ( statusResult and onos_status )
198
199 main.step( "Start ONOS CLI on all nodes" )
200 cliResult = main.TRUE
201 main.log.step(" Start ONOS cli using thread ")
202 startCliResult = main.TRUE
203 pool = []
204
205 for i in range( int( main.numCtrls) ):
206 t = main.Thread( target=main.CLIs[i].startOnosCli,
207 threadID=main.threadID,
208 name="startOnosCli",
209 args=[ main.ONOSip[i] ],
210 kwargs = {"onosStartTimeout":main.timeout} )
211 pool.append(t)
212 t.start()
213 main.threadID = main.threadID + 1
214 for t in pool:
215 t.join()
216 startCliResult = startCliResult and t.result
217 time.sleep( main.startUpSleep )
218
219 def CASE10( self, main ):
220 """
221 Setting up null-provider
222 """
223 import json
224 # Activate apps
225 main.step("Activating null-provider")
226 appStatus = utilities.retry( main.CLIs[0].activateApp,
227 main.FALSE,
228 ['org.onosproject.null'],
229 sleep=main.verifySleep,
230 attempts=main.verifyAttempts )
231 utilities.assert_equals( expect=main.TRUE,
232 actual=appStatus,
233 onpass="Successfully activated null-provider",
234 onfail="Failed activate null-provider" )
235
236 # Setup the null-provider
237 main.step("Configuring null-provider")
238 cfgStatus = utilities.retry( main.ONOSbench.onosCfgSet,
239 main.FALSE,
240 [ main.ONOSip[0],
241 'org.onosproject.provider.nil.NullProviders', 'deviceCount 8'],
242 sleep=main.verifySleep,
243 attempts = main.verifyAttempts )
244 cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
245 main.FALSE,
246 [ main.ONOSip[0],
247 'org.onosproject.provider.nil.NullProviders', 'topoShape reroute'],
248 sleep=main.verifySleep,
249 attempts = main.verifyAttempts )
250
251 cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
252 main.FALSE,
253 [ main.ONOSip[0],
254 'org.onosproject.provider.nil.NullProviders', 'enabled true'],
255 sleep=main.verifySleep,
256 attempts = main.verifyAttempts )
257
258
259 utilities.assert_equals( expect=main.TRUE,
260 actual=cfgStatus,
261 onpass="Successfully configured null-provider",
262 onfail="Failed to configure null-provider" )
263
264 # give onos some time to settle
265 time.sleep(main.startUpSleep)
266
267 main.log.info("Setting default flows to zero")
268 main.defaultFlows = 0
269
270 main.step("Check status of null-provider setup")
271 caseResult = appStatus and cfgStatus
272 utilities.assert_equals( expect=main.TRUE,
273 actual=caseResult,
274 onpass="Setting up null-provider was successfull",
275 onfail="Failed to setup null-provider" )
276
277 # This tells the following cases if we are using the null-provider or ovs
278 main.switchType = "null:"
279
280 # If the null-provider setup was unsuccessfull, then there is no point to
281 # run the subsequent cases
282
283 time.sleep(main.startUpSleep)
284 main.step( "Balancing Masters" )
285
286 stepResult = main.FALSE
287 stepResult = utilities.retry( main.CLIs[0].balanceMasters,
288 main.FALSE,
289 [],
290 sleep=3,
291 attempts=3 )
292
293 utilities.assert_equals( expect=main.TRUE,
294 actual=stepResult,
295 onpass="Balance masters was successfull",
296 onfail="Failed to balance masters")
297
298 time.sleep( 5 )
299 if not caseResult:
300 main.setupSkipped = True
301
302 def CASE11( self, main):
303 '''
304 Setting up mininet
305 '''
306 import json
YPZhangebf9eb52016-05-12 15:20:24 -0700307 import time
308 devices = []
309 devices = main.CLIs[0].getAllDevicesId()
310 for d in devices:
311 main.CLIs[0].deviceRemove( d )
YPZhang737d0012016-03-24 13:56:24 -0700312
YPZhang737d0012016-03-24 13:56:24 -0700313 main.log.info("Set Intent Compiler use Flow Object")
YPZhangebf9eb52016-05-12 15:20:24 -0700314 main.CLIs[0].setCfg("org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator",
315 "useFlowObjectives", "true")
316 time.sleep(main.startUpSleep)
YPZhang737d0012016-03-24 13:56:24 -0700317 main.step('Starting mininet topology')
318 mnStatus = main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
319 utilities.assert_equals( expect=main.TRUE,
320 actual=mnStatus,
321 onpass="Successfully started Mininet",
322 onfail="Failed to activate Mininet" )
323
324 main.step("Assinging masters to switches")
325 switches = main.Mininet1.getSwitches()
326 swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip )
327 utilities.assert_equals( expect=main.TRUE,
328 actual=swStatus,
329 onpass="Successfully assigned switches to masters",
330 onfail="Failed assign switches to masters" )
331
332 time.sleep(main.startUpSleep)
YPZhangebf9eb52016-05-12 15:20:24 -0700333 # Balancing Masters
334 main.step( "Balancing Masters" )
335 stepResult = main.FALSE
336 stepResult = utilities.retry( main.CLIs[0].balanceMasters,
337 main.FALSE,
338 [],
339 sleep=3,
340 attempts=3 )
341
342 utilities.assert_equals( expect=main.TRUE,
343 actual=stepResult,
344 onpass="Balance masters was successfull",
345 onfail="Failed to balance masters" )
YPZhang737d0012016-03-24 13:56:24 -0700346
347 main.log.info("Getting default flows")
348 jsonSum = json.loads(main.CLIs[0].summary())
349 main.defaultFlows = jsonSum["flows"]
350
351 main.step("Check status of Mininet setup")
YPZhangebf9eb52016-05-12 15:20:24 -0700352 caseResult = mnStatus and swStatus
YPZhang737d0012016-03-24 13:56:24 -0700353 utilities.assert_equals( expect=main.TRUE,
354 actual=caseResult,
355 onpass="Successfully setup Mininet",
356 onfail="Failed setup Mininet" )
357
358 # This tells the following cases if we are using the null-provider or ovs
359 main.switchType = "of:"
360
361 time.sleep(main.startUpSleep)
362 main.step( "Balancing Masters" )
363
364 stepResult = main.FALSE
365 stepResult = utilities.retry( main.CLIs[0].balanceMasters,
366 main.FALSE,
367 [],
368 sleep=3,
369 attempts=3 )
370
371 utilities.assert_equals( expect=main.TRUE,
372 actual=stepResult,
373 onpass="Balance masters was successfull",
374 onfail="Failed to balance masters")
375
376 time.sleep(5)
377 if not caseResult:
378 main.setupSkipped = True
379
380
381
382 def CASE20( self, main ):
383 if main.reroute:
384 main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
385 main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
386 main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
387 main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
388 else:
389 main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
390 main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
391 main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
392 main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
393
394 # check if the case needs to be skipped
395 if main.setupSkipped:
396 main.setupSkipped = False
397 main.skipCase()
398
399 # the index where the next intents will be installed
400 offfset = 0
401 # keeps track of how many intents have been installed
402 currIntents = 0
403 # keeps track of how many flows have been installed, set to 0 at start
404 currFlows = 0
405 # limit for the number of intents that can be installed
YPZhangebf9eb52016-05-12 15:20:24 -0700406 main.batchSize = int( int(main.batchSize)/int(main.numCtrls))
YPZhang737d0012016-03-24 13:56:24 -0700407 limit = main.maxIntents / main.batchSize
408 # total intents installed
409 totalIntents = 0
410
411 intentsState = None
412
413 offtmp = 0
414 main.step( "Pushing intents" )
415 stepResult = main.TRUE
416 # temp variable to contain the number of flows
417 flowsNum = 0
YPZhangebf9eb52016-05-12 15:20:24 -0700418 if main.numCtrls > 1:
419 # if more than one onos nodes, we should check more frequently
420 main.checkInterval = main.checkInterval/4
YPZhang737d0012016-03-24 13:56:24 -0700421
YPZhangebf9eb52016-05-12 15:20:24 -0700422 # make sure the checkInterval divisible batchSize
423 main.checkInterval = int( int( main.checkInterval / main.batchSize ) * main.batchSize )
YPZhangac53ebf2016-05-13 16:26:19 -0700424 flowTemp=0
425 totalFlows=0
426 verifyTotalIntents=0
YPZhang737d0012016-03-24 13:56:24 -0700427 for i in range(limit):
428
429 # Threads pool
430 pool = []
431
432 for j in range( int( main.numCtrls) ):
433 if main.numCtrls > 1:
434 time.sleep( 1 )
435 offtmp = offfset + main.maxIntents * j
436 # Push intents by using threads
437 t = main.Thread( target=main.CLIs[j].pushTestIntents,
438 threadID=main.threadID,
439 name="Push-Test-Intents",
440 args=[ main.switchType + main.ingress,
441 main.switchType + main.egress,
442 main.batchSize ],
443 kwargs={ "offset": offtmp,
444 "options": "-i",
445 "timeout": main.timeout,
YPZhangebf9eb52016-05-12 15:20:24 -0700446 "background":False,
447 "noExit":True} )
YPZhang737d0012016-03-24 13:56:24 -0700448 pool.append(t)
449 t.start()
450 main.threadID = main.threadID + 1
451 for t in pool:
452 t.join()
453 stepResult = stepResult and t.result
454 offfset = offfset + main.batchSize
455
456 totalIntents = main.batchSize * main.numCtrls + totalIntents
457 if totalIntents >= main.minIntents and totalIntents % main.checkInterval == 0:
458 # if reach to minimum number and check interval, verify Intetns and flows
459 time.sleep( main.verifySleep * main.numCtrls )
460
461 main.log.info("Verify Intents states")
462 # k is a control variable for verify retry attempts
463 k = 1
YPZhang737d0012016-03-24 13:56:24 -0700464
465 while k <= main.verifyAttempts:
466 # while loop for check intents by using REST api
467 time.sleep(5)
468 temp = 0
YPZhangebf9eb52016-05-12 15:20:24 -0700469 intentsState = main.CLIs[0].checkIntentSummary(timeout=600)
470 if intentsState:
YPZhangac53ebf2016-05-13 16:26:19 -0700471 verifyTotalIntents = main.CLIs[0].getTotalIntentsNum(timeout=600)
472 if temp < verifyTotalIntents:
473 temp = verifyTotalIntents
YPZhangebf9eb52016-05-12 15:20:24 -0700474 else:
YPZhangac53ebf2016-05-13 16:26:19 -0700475 verifyTotalIntents = temp
YPZhang737d0012016-03-24 13:56:24 -0700476 break
YPZhangebf9eb52016-05-12 15:20:24 -0700477 main.log.info("Total Intents: {}".format( totalIntents) )
YPZhang737d0012016-03-24 13:56:24 -0700478 k = k+1
YPZhangac53ebf2016-05-13 16:26:19 -0700479
480 totalFlows = main.CLIs[0].getTotalFlowsNum( timeout=600, noExit=True )
481 if flowTemp<totalFlows:
482 flowTemp = totalFlows
483 else:
484 totalFlows = flowTemp
485
YPZhangebf9eb52016-05-12 15:20:24 -0700486 if not intentsState:
YPZhang737d0012016-03-24 13:56:24 -0700487 # If some intents are not installed, grep the previous flows list, and finished this test case
488 main.log.warn( "Some intens did not install" )
YPZhangf9f0fa92016-05-23 15:44:44 -0700489 verifyTotalIntents = main.CLIs[0].getTotalIntentsNum(timeout=600)
YPZhangebf9eb52016-05-12 15:20:24 -0700490 main.log.info("Total Intents: {}".format( totalIntents) )
YPZhang737d0012016-03-24 13:56:24 -0700491 break
YPZhange96a3062016-05-12 16:18:35 -0700492
YPZhang737d0012016-03-24 13:56:24 -0700493 del main.scale[0]
494 utilities.assert_equals( expect = main.TRUE,
YPZhangebf9eb52016-05-12 15:20:24 -0700495 actual = intentsState,
YPZhang737d0012016-03-24 13:56:24 -0700496 onpass = "Successfully pushed and verified intents",
497 onfail = "Failed to push and verify intents" )
498
YPZhang737d0012016-03-24 13:56:24 -0700499 main.log.info( "Total Intents Installed before crash: {}".format( totalIntents ) )
500 main.log.info( "Total Flows ADDED before crash: {}".format( totalFlows ) )
501
502 main.step('clean up Mininet')
503 main.Mininet1.stopNet()
YPZhang737d0012016-03-24 13:56:24 -0700504 main.log.info("Writing results to DS file")
505 with open(main.dbFileName, "a") as dbFile:
506 # Scale number
507 temp = str(main.numCtrls)
508 temp += ",'" + "baremetal1" + "'"
509 # how many intents we installed before crash
510 temp += "," + str(totalIntents)
511 # how many flows we installed before crash
512 temp += "," + str(totalFlows)
513 # other columns in database, but we didn't use in this test
514 temp += "," + "0,0,0,0,0,0"
515 temp += "\n"
516 dbFile.write( temp )