blob: e405fd33896471fd9043281f3c673b207f7a74b6 [file] [log] [blame]
import sys
import json
import time
import os
'''
SCPFscalingMaxIntentsWithFlowObj
Push test Intents to onos
CASE10: set up Null Provider
CASE11: set up Open Flows
Scale up when reach the Limited
Start from 1 nodes, 8 devices. Then Scale up to 3,5,7 nodes
Recommand batch size: 100, check interval: 100
'''
class SCPFscalingMaxIntentsWithFlowObj:
def __init__( self ):
self.default = ''
def CASE0( self, main):
import sys
import json
import time
import os
import imp
main.case( "Constructing test variables and building ONOS package" )
main.step( "Constructing test variables" )
stepResult = main.FALSE
# Test variables
main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
main.dependencyPath = main.testOnDirectory + \
main.params['DEPENDENCY']['path']
main.cellName = main.params[ 'ENV' ][ 'cellName' ]
main.apps = main.params[ 'ENV' ][ 'cellApps' ]
main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
main.scale = ( main.params[ 'SCALE' ] ).split( "," )
main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
main.timeout = int(main.params['SLEEP']['timeout'])
main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
main.ingress = main.params['LINK']['ingress']
main.egress = main.params['LINK']['egress']
main.dbFileName = main.params['DATABASE']['file']
main.cellData = {} # for creating cell file
main.reroute = main.params['reroute']
main.threadID = 0
if main.reroute == "True":
main.reroute = True
else:
main.reroute = False
main.CLIs = []
main.ONOSip = []
main.maxNumBatch = 0
main.ONOSip = main.ONOSbench.getOnosIps()
main.log.info(main.ONOSip)
main.setupSkipped = False
wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
gitBranch = main.params[ 'GIT' ][ 'branch' ]
gitPull = main.params[ 'GIT' ][ 'pull' ]
nic = main.params['DATABASE']['nic']
node = main.params['DATABASE']['node']
nic = main.params['DATABASE']['nic']
node = main.params['DATABASE']['node']
stepResult = main.TRUE
main.log.info("Cresting DB file")
with open(main.dbFileName, "w+") as dbFile:
dbFile.write("")
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="environment set up successfull",
onfail="environment set up Failed" )
def CASE1( self ):
# main.scale[ 0 ] determines the current number of ONOS controller
main.CLIs = []
main.numCtrls = int( main.scale[ 0 ] )
main.log.info( "Creating list of ONOS cli handles" )
for i in range(main.numCtrls):
main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
main.log.info(main.CLIs)
if not main.CLIs:
main.log.error( "Failed to create the list of ONOS cli handles" )
main.cleanup()
main.exit()
main.log.info( "Loading wrapper files" )
main.startUp = imp.load_source( wrapperFile1,
main.dependencyPath +
wrapperFile1 +
".py" )
copyResult = main.ONOSbench.copyMininetFile( main.topology,
main.dependencyPath,
main.Mininet1.user_name,
main.Mininet1.ip_address )
commit = main.ONOSbench.getVersion(report=True)
commit = commit.split(" ")[1]
if gitPull == 'True':
if not main.startUp.onosBuild( main, gitBranch ):
main.log.error( "Failed to build ONOS" )
main.cleanup()
main.exit()
else:
main.log.warn( "Did not pull new code so skipping mvn " +
"clean install" )
with open(main.dbFileName, "a") as dbFile:
temp = "'" + commit + "',"
temp += "'" + nic + "',"
dbFile.write(temp)
def CASE2( self, main ):
"""
- Uninstall ONOS cluster
- Verify ONOS start up
- Install ONOS cluster
- Connect to cli
"""
main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
main.log.info( "Safety check, killing all ONOS processes" +
" before initiating environment setup" )
for i in range( main.numCtrls ):
main.ONOSbench.onosDie( main.ONOSip[ i ] )
main.log.info( "NODE COUNT = %s" % main.numCtrls)
tempOnosIp = []
for i in range( main.numCtrls ):
tempOnosIp.append( main.ONOSip[i] )
main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
"temp",
main.Mininet1.ip_address,
main.apps,
tempOnosIp )
main.step( "Apply cell to environment" )
cellResult = main.ONOSbench.setCell( "temp" )
verifyResult = main.ONOSbench.verifyCell()
stepResult = cellResult and verifyResult
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="Successfully applied cell to " + \
"environment",
onfail="Failed to apply cell to environment " )
main.step( "Creating ONOS package" )
packageResult = main.ONOSbench.onosPackage()
stepResult = packageResult
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="Successfully created ONOS package",
onfail="Failed to create ONOS package" )
main.step( "Uninstall ONOS package on all Nodes" )
uninstallResult = main.TRUE
for i in range( int( main.numCtrls ) ):
main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
utilities.assert_equals( expect=main.TRUE, actual=u_result,
onpass="Test step PASS",
onfail="Test step FAIL" )
uninstallResult = ( uninstallResult and u_result )
main.step( "Install ONOS package on all Nodes" )
installResult = main.TRUE
for i in range( int( main.numCtrls ) ):
main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
utilities.assert_equals( expect=main.TRUE, actual=i_result,
onpass="Test step PASS",
onfail="Test step FAIL" )
installResult = installResult and i_result
main.step( "Verify ONOS nodes UP status" )
statusResult = main.TRUE
for i in range( int( main.numCtrls ) ):
main.log.info( "ONOS Node " + main.ONOSip[i] + " status:" )
onos_status = main.ONOSbench.onosStatus( node=main.ONOSip[i] )
utilities.assert_equals( expect=main.TRUE, actual=onos_status,
onpass="Test step PASS",
onfail="Test step FAIL" )
statusResult = ( statusResult and onos_status )
main.step( "Start ONOS CLI on all nodes" )
cliResult = main.TRUE
main.log.step(" Start ONOS cli using thread ")
startCliResult = main.TRUE
pool = []
for i in range( int( main.numCtrls) ):
t = main.Thread( target=main.CLIs[i].startOnosCli,
threadID=main.threadID,
name="startOnosCli",
args=[ main.ONOSip[i] ],
kwargs = {"onosStartTimeout":main.timeout} )
pool.append(t)
t.start()
main.threadID = main.threadID + 1
for t in pool:
t.join()
startCliResult = startCliResult and t.result
time.sleep( main.startUpSleep )
def CASE10( self, main ):
"""
Setting up null-provider
"""
import json
# Activate apps
main.step("Activating null-provider")
appStatus = utilities.retry( main.CLIs[0].activateApp,
main.FALSE,
['org.onosproject.null'],
sleep=main.verifySleep,
attempts=main.verifyAttempts )
utilities.assert_equals( expect=main.TRUE,
actual=appStatus,
onpass="Successfully activated null-provider",
onfail="Failed activate null-provider" )
# Setup the null-provider
main.step("Configuring null-provider")
cfgStatus = utilities.retry( main.ONOSbench.onosCfgSet,
main.FALSE,
[ main.ONOSip[0],
'org.onosproject.provider.nil.NullProviders', 'deviceCount 8'],
sleep=main.verifySleep,
attempts = main.verifyAttempts )
cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
main.FALSE,
[ main.ONOSip[0],
'org.onosproject.provider.nil.NullProviders', 'topoShape reroute'],
sleep=main.verifySleep,
attempts = main.verifyAttempts )
cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
main.FALSE,
[ main.ONOSip[0],
'org.onosproject.provider.nil.NullProviders', 'enabled true'],
sleep=main.verifySleep,
attempts = main.verifyAttempts )
utilities.assert_equals( expect=main.TRUE,
actual=cfgStatus,
onpass="Successfully configured null-provider",
onfail="Failed to configure null-provider" )
# give onos some time to settle
time.sleep(main.startUpSleep)
main.log.info("Setting default flows to zero")
main.defaultFlows = 0
main.step("Check status of null-provider setup")
caseResult = appStatus and cfgStatus
utilities.assert_equals( expect=main.TRUE,
actual=caseResult,
onpass="Setting up null-provider was successfull",
onfail="Failed to setup null-provider" )
# This tells the following cases if we are using the null-provider or ovs
main.switchType = "null:"
# If the null-provider setup was unsuccessfull, then there is no point to
# run the subsequent cases
time.sleep(main.startUpSleep)
main.step( "Balancing Masters" )
stepResult = main.FALSE
stepResult = utilities.retry( main.CLIs[0].balanceMasters,
main.FALSE,
[],
sleep=3,
attempts=3 )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="Balance masters was successfull",
onfail="Failed to balance masters")
time.sleep( 5 )
if not caseResult:
main.setupSkipped = True
def CASE11( self, main):
'''
Setting up mininet
'''
import json
import time
time.sleep(main.startUpSleep)
main.step("Activating openflow")
appStatus = utilities.retry( main.ONOSrest1.activateApp,
main.FALSE,
['org.onosproject.openflow'],
sleep=3,
attempts=3 )
utilities.assert_equals( expect=main.TRUE,
actual=appStatus,
onpass="Successfully activated openflow",
onfail="Failed activate openflow" )
time.sleep(main.startUpSleep)
main.log.info("Set Intent Compiler use Flow Object")
main.CLIs[0].setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator", "useFlowObjectives", "true" )
main.step('Starting mininet topology')
mnStatus = main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
utilities.assert_equals( expect=main.TRUE,
actual=mnStatus,
onpass="Successfully started Mininet",
onfail="Failed to activate Mininet" )
main.step("Assinging masters to switches")
switches = main.Mininet1.getSwitches()
swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip )
utilities.assert_equals( expect=main.TRUE,
actual=swStatus,
onpass="Successfully assigned switches to masters",
onfail="Failed assign switches to masters" )
time.sleep(main.startUpSleep)
main.log.info("Getting default flows")
jsonSum = json.loads(main.CLIs[0].summary())
main.defaultFlows = jsonSum["flows"]
main.step("Check status of Mininet setup")
caseResult = appStatus and mnStatus and swStatus
utilities.assert_equals( expect=main.TRUE,
actual=caseResult,
onpass="Successfully setup Mininet",
onfail="Failed setup Mininet" )
# This tells the following cases if we are using the null-provider or ovs
main.switchType = "of:"
time.sleep(main.startUpSleep)
main.step( "Balancing Masters" )
stepResult = main.FALSE
stepResult = utilities.retry( main.CLIs[0].balanceMasters,
main.FALSE,
[],
sleep=3,
attempts=3 )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="Balance masters was successfull",
onfail="Failed to balance masters")
time.sleep(5)
if not caseResult:
main.setupSkipped = True
def CASE20( self, main ):
if main.reroute:
main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
else:
main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
# check if the case needs to be skipped
if main.setupSkipped:
main.setupSkipped = False
main.skipCase()
# the index where the next intents will be installed
offfset = 0
# keeps track of how many intents have been installed
currIntents = 0
# keeps track of how many flows have been installed, set to 0 at start
currFlows = 0
# limit for the number of intents that can be installed
limit = main.maxIntents / main.batchSize
# total intents installed
totalIntents = 0
intentsState = None
offtmp = 0
main.step( "Pushing intents" )
stepResult = main.TRUE
# temp variable to contain the number of flows
flowsNum = 0
for i in range(limit):
# Threads pool
pool = []
for j in range( int( main.numCtrls) ):
if main.numCtrls > 1:
time.sleep( 1 )
offtmp = offfset + main.maxIntents * j
# Push intents by using threads
t = main.Thread( target=main.CLIs[j].pushTestIntents,
threadID=main.threadID,
name="Push-Test-Intents",
args=[ main.switchType + main.ingress,
main.switchType + main.egress,
main.batchSize ],
kwargs={ "offset": offtmp,
"options": "-i",
"timeout": main.timeout,
"background":False } )
pool.append(t)
t.start()
main.threadID = main.threadID + 1
for t in pool:
t.join()
stepResult = stepResult and t.result
offfset = offfset + main.batchSize
totalIntents = main.batchSize * main.numCtrls + totalIntents
if totalIntents >= main.minIntents and totalIntents % main.checkInterval == 0:
# if reach to minimum number and check interval, verify Intetns and flows
time.sleep( main.verifySleep * main.numCtrls )
main.log.info("Verify Intents states")
# k is a control variable for verify retry attempts
k = 1
intentVerify = main.FALSE
while k <= main.verifyAttempts:
# while loop for check intents by using REST api
time.sleep(5)
temp = 0
intentsState = json.loads( main.ONOSrest1.intents() )
for f in intentsState:
# get INSTALLED intents number
if f.get("state") == "INSTALLED":
temp = temp + 1
main.log.info("Total Intents: {} INSTALLED: {}".format(totalIntents, temp))
if totalIntents == temp:
intentVerify = main.TRUE
break
intentVerify = main.FALSE
k = k+1
if not intentVerify:
# If some intents are not installed, grep the previous flows list, and finished this test case
main.log.warn( "Some intens did not install" )
# We don't want to check flows if intents not installed, because onos will drop flows
if currFlows == 0:
# If currFlows equal 0, which means we failed to install intents at first, or we didn't get
# the correct number, so we need get flows here.
flowsState = json.loads( main.ONOSrest1.flows() )
break
main.log.info("Verify Flows states")
k = 1
flowsVerify = main.TRUE
while k <= main.verifyAttempts:
# while loop for check flows by using REST api
time.sleep(3)
temp = 0
flowsStateCount = []
flowsState = json.loads( main.ONOSrest1.flows() )
main.log.info("Total flows now: {}".format(len(flowsState)))
if ( flowsNum < len(flowsState) ):
flowsNum = len(flowsState)
print(flowsNum)
for f in flowsState:
# get PENDING_ADD flows
if f.get("state") == "PENDING_ADD":
temp = temp + 1
flowsStateCount.append(temp)
temp = 0
for f in flowsState:
# get PENDING_REMOVE flows
if f.get("state") == "PENDING_REMOVE":
temp = temp + 1
flowsStateCount.append(temp)
temp = 0
for f in flowsState:
# get REMOVED flows
if f.get("state") == "REMOVED":
temp = temp + 1
flowsStateCount.append(temp)
temp = 0
for f in flowsState:
# get FAILED flwos
if f.get("state") == "FAILED":
temp = temp + 1
flowsStateCount.append(temp)
temp = 0
k = k + 1
for c in flowsStateCount:
if int(c) > 0:
flowsVerify = main.FALSE
main.log.info( "Check flows States:" )
main.log.info( "PENDING_ADD: {}".format( flowsStateCount[0]) )
main.log.info( "PENDING_REMOVE: {}".format( flowsStateCount[1]) )
main.log.info( "REMOVED: {}".format( flowsStateCount[2]) )
main.log.info( "FAILED: {}".format( flowsStateCount[3]) )
if flowsVerify == main.TRUE:
break
del main.scale[0]
utilities.assert_equals( expect = main.TRUE,
actual = intentVerify,
onpass = "Successfully pushed and verified intents",
onfail = "Failed to push and verify intents" )
# we need the total intents before crash
totalIntents = len(intentsState)
totalFlows = flowsNum
main.log.info( "Total Intents Installed before crash: {}".format( totalIntents ) )
main.log.info( "Total Flows ADDED before crash: {}".format( totalFlows ) )
main.step('clean up Mininet')
main.Mininet1.stopNet()
main.log.info("Writing results to DS file")
with open(main.dbFileName, "a") as dbFile:
# Scale number
temp = str(main.numCtrls)
temp += ",'" + "baremetal1" + "'"
# how many intents we installed before crash
temp += "," + str(totalIntents)
# how many flows we installed before crash
temp += "," + str(totalFlows)
# other columns in database, but we didn't use in this test
temp += "," + "0,0,0,0,0,0"
temp += "\n"
dbFile.write( temp )