Add 4 new intent test case with FlowObj
- SCPFintentEventTpWithFlowObj
- SCPFintentInstallWithdrawLatWithFlowObj
- SCPFintentRerouteLatWithFlowObj
- SCPFscalingMaxIntentsWithFlowObj
1) Create a new case for cfg set and create DB file for flowObj
2) Append data to new DB file for flowObj
Change-Id: I4f955876607560b2a6e103ea4cbcbaac479bd74b
diff --git a/TestON/tests/SCPFintentEventTpWithFlowObj/README b/TestON/tests/SCPFintentEventTpWithFlowObj/README
new file mode 100644
index 0000000..980c748
--- /dev/null
+++ b/TestON/tests/SCPFintentEventTpWithFlowObj/README
@@ -0,0 +1,28 @@
+INTENT EVENT THROUGHPUT
+
+Summary: This is a performance test suite to test the intent
+ throughput capabilities of ONOS with various controller cluster sizes.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES. OC1->OC7
+ must be set before initiating the test. Passwordless login must be set
+ from TestStation "admin" root user.
+
+***If you wish to run this test with less than 7 nodes the following
+ alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in the
+ <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases>
+ tag for each value you removed from <scale> (case 1 and 2 are each
+ called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3, or 5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.params b/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.params
new file mode 100644
index 0000000..5ccea03
--- /dev/null
+++ b/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.params
@@ -0,0 +1,71 @@
+<PARAMS>
+
+ <testcases>1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2</testcases>
+
+ <debugMode></debugMode> #nothing means false
+
+ <ENV>
+ <cellName>intentTP</cellName>
+ <cellApps>drivers,null,intentperf</cellApps>
+ </ENV>
+
+ <SCALE>1,3,3,5,5,7,7</SCALE>
+ <max>7</max>
+
+ <GIT>
+ <autopull>off</autopull>
+ <checkout>master</checkout>
+ </GIT>
+
+ <CTRL>
+ <USER>admin</USER>
+
+ <ip1>OC1</ip1>
+ <port1>6653</port1>
+
+ <ip2>OC2</ip2>
+ <port2>6653</port2>
+
+ <ip3>OC3</ip3>
+ <port3>6653</port3>
+
+ <ip4>OC4</ip4>
+ <port4>6653</port4>
+
+ <ip5>OC5</ip5>
+ <port5>6653</port5>
+
+ <ip6>OC6</ip6>
+ <port6>6653</port6>
+
+ <ip7>OC7</ip7>
+ <port7>6653</port7>
+ </CTRL>
+
+ <MN><ip1>OCN</ip1></MN>
+
+ <BENCH>
+ <user>admin</user>
+ <ip1>OCN</ip1>
+ </BENCH>
+
+ <TEST>
+ <loadFrom>1,1,1,1,1,1,1</loadFrom> #generate load on server, 1 = generator on
+ <numSwitches>10,10,10,10,10,10,10</numSwitches>
+ <skipCleanInstall>yes</skipCleanInstall>
+ <duration>400</duration>
+ <log_interval>10</log_interval>
+ <numKeys>40000</numKeys>
+ <cyclePeriod>1000</cyclePeriod>
+ <neighbors>0,a</neighbors> #a == all nodes (-1)
+ <flowRuleBUEnabled>true</flowRuleBUEnabled>
+ <skipReleaseResourcesOnWithdrawal>true</skipReleaseResourcesOnWithdrawal>
+ </TEST>
+
+ <METRICS>
+ <intents_rate>intents-events-metrics|grep "Intent Installed Events"|cut -d ' ' -f7</intents_rate>
+ <intents_withdrawn>intents-events-metrics|grep "Intent Withdrawn Events"|cut -d ' ' -f7</intents_withdrawn>
+ <intents_failed>intents-events-metrics|grep "Intent Failed Events"|cut -d ' ' -f7</intents_failed>
+ </METRICS>
+
+</PARAMS>
diff --git a/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.py b/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.py
new file mode 100644
index 0000000..41b46da
--- /dev/null
+++ b/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.py
@@ -0,0 +1,325 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+import time
+
+
+class SCPFintentEventTpWithFlowObj:
+
+ def __init__( self ):
+ self.default = ''
+
+ def CASE1( self, main ):
+ import sys
+ import os.path
+ import time
+
+ global init
+ try:
+ if type(init) is not bool:
+ init = False
+ except NameError:
+ init = False
+
+ #Load values from params file
+ checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+ gitPull = main.params[ 'GIT' ][ 'autopull' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+ Apps = main.params[ 'ENV' ][ 'cellApps' ]
+ BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+ BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+ MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+ maxNodes = int(main.params[ 'max' ])
+ main.maxNodes = maxNodes
+ skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+ numSwitches = (main.params[ 'TEST' ][ 'numSwitches' ]).split(",")
+ flowRuleBU = main.params[ 'TEST' ][ 'flowRuleBUEnabled' ]
+ skipRelRsrc = main.params[ 'TEST'][ 'skipReleaseResourcesOnWithdrawal']
+ homeDir = os.path.expanduser('~')
+
+ main.exceptions = [0]*11
+ main.warnings = [0]*11
+ main.errors = [0]*11
+
+ # -- INIT SECTION, ONLY RUNS ONCE -- #
+ if init == False:
+ init = True
+ global clusterCount #number of nodes running
+ global ONOSIp #list of ONOS IP addresses
+ global scale
+ global commit
+
+ clusterCount = 0
+ ONOSIp = main.ONOSbench.getOnosIps()
+ print ONOSIp
+ print main.ONOSbench.onosIps.values()
+
+ scale = (main.params[ 'SCALE' ]).split(",")
+ clusterCount = int(scale[0])
+
+ #Populate ONOSIp with ips from params
+ ONOSIp.extend(main.ONOSbench.getOnosIps())
+
+ #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+ if skipMvn != "yes":
+ mvnResult = main.ONOSbench.cleanInstall()
+
+ #git
+ main.step( "Git checkout and pull " + checkoutBranch )
+ if gitPull == 'on':
+ checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+ pullResult = main.ONOSbench.gitPull()
+
+ else:
+ checkoutResult = main.TRUE
+ pullResult = main.TRUE
+ main.log.info( "Skipped git checkout and pull" )
+
+ main.log.step("Grabbing commit number")
+ commit = main.ONOSbench.getVersion()
+ commit = (commit.split(" "))[1]
+
+ main.log.step("Creating results file")
+ # Create results file with flow object
+ flowObjResultsDB = open("/tmp/IntentEventTPflowObjDB", "w+")
+ flowObjResultsDB.close()
+
+ # -- END OF INIT SECTION --#
+
+ main.log.step("Adjusting scale")
+ print str(scale)
+ print str(ONOSIp)
+ clusterCount = int(scale[0])
+ scale.remove(scale[0])
+
+ MN1Ip = ONOSIp[len(ONOSIp) -1]
+ BENCHIp = ONOSIp[len(ONOSIp) -2]
+
+ #kill off all onos processes
+ main.log.step("Safety check, killing all ONOS processes")
+ main.log.step("before initiating environment setup")
+ for node in range(maxNodes):
+ main.ONOSbench.onosDie(ONOSIp[node])
+
+ MN1Ip = ONOSIp[len(ONOSIp) -1]
+ BENCHIp = ONOSIp[len(ONOSIp) -2]
+
+ #Uninstall everywhere
+ main.log.step( "Cleaning Enviornment..." )
+ for i in range(maxNodes):
+ main.log.info(" Uninstalling ONOS " + str(i) )
+ main.ONOSbench.onosUninstall( ONOSIp[i] )
+ main.log.info("Sleep 10 second for uninstall to settle...")
+ time.sleep(10)
+ main.ONOSbench.handle.sendline(" ")
+ main.ONOSbench.handle.expect(":~")
+
+ #construct the cell file
+ main.log.info("Creating cell file")
+ cellIp = []
+ for node in range (clusterCount):
+ cellIp.append(ONOSIp[node])
+
+ main.ONOSbench.createCellFile("localhost",cellName,MN1Ip,str(Apps), cellIp)
+
+ main.step( "Set Cell" )
+ main.ONOSbench.setCell(cellName)
+
+ myDistribution = []
+ for node in range (clusterCount):
+ myDistribution.append(numSwitches[node])
+
+ main.step( "Creating ONOS package" )
+ packageResult = main.ONOSbench.onosPackage()
+
+ main.step( "verify cells" )
+ verifyCellResult = main.ONOSbench.verifyCell()
+
+ main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
+ for node in range(clusterCount):
+ main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+ main.ONOSbench.onosInstall( ONOSIp[node])
+
+ for node in range(clusterCount):
+ for i in range( 2 ):
+ isup = main.ONOSbench.isup( ONOSIp[node] )
+ if isup:
+ main.log.info("ONOS " + str(node) + " is up\n")
+ break
+ if not isup:
+ main.log.report( "ONOS " + str(node) + " didn't start!" )
+ main.log.info("Startup sequence complete")
+
+ time.sleep(20)
+
+ main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.store.flow.impl.NewDistributedFlowRuleStore", "backupEnabled " + str(flowRuleBU))
+ main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.net.intent.impl.IntentManager", "skipReleaseResourcesOnWithdrawal " + skipRelRsrc)
+ devices = int(clusterCount)*10
+
+ main.log.step("Setting up null provider")
+ for i in range(3):
+ main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(devices))
+ main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+ main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "enabled true")
+ time.sleep(5)
+
+ main.ONOSbench.handle.sendline("onos $OC1 summary")
+ main.ONOSbench.handle.expect(":~")
+
+ before = main.ONOSbench.handle.before
+ if ("devices=" + str(devices)) in before:
+ break
+
+ main.ONOSbench.handle.sendline("""onos $OC1 "balance-masters" """)
+ main.ONOSbench.handle.expect(":~")
+ print main.ONOSbench.handle.before
+
+ for i in range(3):
+ passed = main.ONOSbench.verifySummary( ONOSIp[0] )
+ if passed:
+ main.log.info("Clusters have converged")
+ break
+ else:
+ main.log.error("Clusters have not converged, retying...")
+ time.sleep(3)
+
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+ def CASE2( self, main ):
+ import time
+ import json
+ import string
+ import csv
+ import numpy
+ import os.path
+
+ global currentNeighbors
+ neighbors = []
+
+ try:
+ currentNeighbors
+ except:
+ currentNeighbors = "0"
+ neighbors = ['0']
+ else:
+ if currentNeighbors == "r": #reset
+ currentNeighbors = "a"
+ neighbors = ['0']
+ else:
+ currentNeighbors = "r"
+ neighbors = ['a']
+
+ if clusterCount == 1:
+ currentNeighbors = "r"
+
+ main.log.info("Cluster Count = " + str(clusterCount))
+
+ intentsRate = main.params['METRICS']['intents_rate']
+ intentsWithdrawn = main.params[ 'METRICS' ][ 'intents_withdrawn' ]
+ intentsFailed = main.params[ 'METRICS' ][ 'intents_failed' ]
+ testDuration = main.params[ 'TEST' ][ 'duration' ]
+ logInterval = main.params[ 'TEST' ][ 'log_interval' ]
+ debug = main.params[ 'debugMode' ]
+ numKeys = main.params[ 'TEST' ][ 'numKeys' ]
+ cyclePeriod = main.params[ 'TEST' ][ 'cyclePeriod' ]
+ #neighbors = (main.params[ 'TEST' ][ 'neighbors' ]).split(",")
+ metricList = [intentsRate, intentsWithdrawn, intentsFailed]
+
+ for n in range(0, len(neighbors)):
+ if neighbors[n] == 'a':
+ neighbors[n] = str(clusterCount -1)
+ if int(clusterCount) == 1:
+ neighbors = neighbors.pop()
+
+ for n in neighbors:
+ main.log.info("Run with " + n + " neighbors")
+ time.sleep(5)
+ main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller numKeys " + numKeys )
+ main.ONOSbench.handle.expect(":~")
+ main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller numNeighbors " + n )
+ main.ONOSbench.handle.expect(":~")
+ main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller cyclePeriod " + cyclePeriod )
+ main.ONOSbench.handle.expect(":~")
+
+ cmd = "onos $OC1 intent-perf-start"
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ main.log.info("Starting ONOS (all nodes) intent-perf from $OC1" )
+
+ main.log.info( "Starting test loop for " + str(testDuration) + " seconds...\n" )
+ stop = time.time() + float( testDuration )
+
+ while time.time() < stop:
+ time.sleep( float( logInterval ) )
+ groupResult = []
+ for node in range (1, clusterCount + 1):
+ groupResult.append(0)
+
+ cmd = " onos-ssh $OC" + str(node) + """ cat /opt/onos/log/karaf.log | grep "Throughput:" | tail -1 """
+ main.log.info("COMMAND: " + str(cmd))
+
+ x = 0
+ while True:
+ main.ONOSbench.handle.sendline(cmd)
+ time.sleep(6)
+ main.ONOSbench.handle.expect(":~")
+ raw = main.ONOSbench.handle.before
+ if "OVERALL=" in raw:
+ break
+ x += 1
+ if x > 10:
+ main.log.error("Expected output not being recieved... continuing")
+ break
+ time.sleep(2)
+
+ raw = raw.splitlines()
+ splitResults = []
+ for line in raw:
+ splitResults.extend(line.split(" "))
+
+ myResult = "--"
+ for field in splitResults:
+ if "OVERALL" in field:
+ myResult = field
+
+ if myResult == "--":
+ main.log.error("Parsing/Pexpect error\n" + str(splitResults))
+
+ myResult = myResult.replace(";", "")
+ myResult = myResult.replace("OVERALL=","")
+ myResult = float(myResult)
+ groupResult[len(groupResult) -1] = myResult
+
+ main.log.info("Node " + str(node) + " overall rate: " + str(myResult))
+
+ clusterTotal = str(numpy.sum(groupResult))
+ main.log.report("Results from this round of polling: " + str(groupResult))
+ main.log.report("Cluster Total: " + clusterTotal + "\n")
+
+ cmd = "onos $OC1 intent-perf-stop"
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ main.log.info("Stopping intentperf" )
+
+ with open("/tmp/IntentEventTPflowObjDB", "a") as resultsDB:
+ for node in groupResult:
+ resultString = "'" + commit + "',"
+ resultString += "'1gig',"
+ resultString += str(clusterCount) + ","
+ resultString += "'baremetal" + str(int(groupResult.index(node)) + 1) + "',"
+ resultString += n + ","
+ resultString += str(node) + ","
+ resultString += str(0) + "\n" #no stddev
+ resultsDB.write(resultString)
+ resultsDB.close()
+ resultsDB.close()
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+ def CASE3( self, main ):
+ main.log.info("Set Intent Compiler use Flow Object")
+ stepResult = main.ONOSbench.onosCfgSet( ONOSIp[0],"org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator", "useFlowObjectives true")
\ No newline at end of file
diff --git a/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.topo b/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.topo
new file mode 100644
index 0000000..01370b6
--- /dev/null
+++ b/TestON/tests/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <home>~/onos</home>
+ <nodes>7</nodes>
+ </COMPONENTS>
+ </ONOSbench>
+
+ <ONOS1cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1cli>
+
+ <ONOS2cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2cli>
+
+ <ONOS3cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3cli>
+
+ <ONOS4cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4cli>
+
+ <ONOS5cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>6</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5cli>
+
+ <ONOS6cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>7</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6cli>
+
+ <ONOS7cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>8</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7cli>
+
+ <ONOS1>
+ <host>OC1</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>9</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1>
+
+ <ONOS2>
+ <host>OC2</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>10</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2>
+
+ <ONOS3>
+ <host>OC3</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>11</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3>
+
+ <ONOS4>
+ <host>OC4</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>12</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4>
+
+
+ <ONOS5>
+ <host>OC5</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>13</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5>
+
+ <ONOS6>
+ <host>OC6</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>14</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6>
+
+ <ONOS7>
+ <host>OC7</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>15</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7>
+
+ </COMPONENT>
+
+</TOPOLOGY>
+
diff --git a/TestON/tests/SCPFintentEventTpWithFlowObj/__init__.py b/TestON/tests/SCPFintentEventTpWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPFintentEventTpWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.params b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.params
new file mode 100644
index 0000000..1521a75
--- /dev/null
+++ b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.params
@@ -0,0 +1,66 @@
+<PARAMS>
+
+ <testcases>1,2,1,2,1,2,1,2</testcases>
+
+ <SCALE>1,3,5,7</SCALE>
+ <max>7</max>
+
+ <ENV>
+ <cellName>IntentInstallWithdrawCell</cellName>
+ <cellApps>drivers,null</cellApps>
+ </ENV>
+
+ <TEST>
+ <skipCleanInstall>yes</skipCleanInstall>
+ <switchCount>7</switchCount>
+ <warmUp>5</warmUp>
+ <sampleSize>20</sampleSize>
+ <wait></wait>
+ <intents>1,100,1000</intents> #list format, will be split on ','
+ <debug>True</debug> #"True" for true
+ </TEST>
+
+ <GIT>
+ <autopull>off</autopull>
+ <checkout>master</checkout>
+ </GIT>
+
+ <CTRL>
+ <USER>admin</USER>
+
+ <ip1>OC1</ip1>
+ <port1>6653</port1>
+
+ <ip2>OC2</ip2>
+ <port2>6653</port2>
+
+ <ip3>OC3</ip3>
+ <port3>6653</port3>
+
+ <ip4>OC4</ip4>
+ <port4>6653</port4>
+
+ <ip5>OC5</ip5>
+ <port5>6653</port5>
+
+ <ip6>OC6</ip6>
+ <port6>6653</port6>
+
+ <ip7>OC7</ip7>
+ <port7>6653</port7>
+
+ </CTRL>
+
+ <MN>
+ <ip1>localhost</ip1>
+ </MN>
+
+ <BENCH>
+ <user>admin</user>
+ <ip1>localhost</ip1>
+ </BENCH>
+
+ <JSON>
+ </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.py b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.py
new file mode 100644
index 0000000..ec47721
--- /dev/null
+++ b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.py
@@ -0,0 +1,274 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFintentInstallWithdrawLatWithFlowObj:
+
+ def __init__( self ):
+ self.default = ''
+
+ def CASE1( self, main ):
+
+ import time
+ global init
+ try:
+ if type(init) is not bool:
+ init = False
+ except NameError:
+ init = False
+
+ #Load values from params file
+ checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+ gitPull = main.params[ 'GIT' ][ 'autopull' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+ Apps = main.params[ 'ENV' ][ 'cellApps' ]
+ BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+ BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+ MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+ main.maxNodes = int(main.params[ 'max' ])
+ skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+ switchCount = main.params[ 'TEST' ][ 'switchCount' ]
+
+ # -- INIT SECTION, ONLY RUNS ONCE -- #
+ if init == False:
+ init = True
+ global clusterCount #number of nodes running
+ global ONOSIp #list of ONOS IP addresses
+ global scale
+ global commit
+
+ clusterCount = 0
+ ONOSIp = [ 0 ]
+ scale = (main.params[ 'SCALE' ]).split(",")
+ clusterCount = int(scale[0])
+
+ #Populate ONOSIp with ips from params
+ ONOSIp = [0]
+ ONOSIp.extend(main.ONOSbench.getOnosIps())
+
+ #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+ if skipMvn != "yes":
+ mvnResult = main.ONOSbench.cleanInstall()
+
+ #git
+ main.step( "Git checkout and pull " + checkoutBranch )
+ if gitPull == 'on':
+ checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+ pullResult = main.ONOSbench.gitPull()
+
+ else:
+ checkoutResult = main.TRUE
+ pullResult = main.TRUE
+ main.log.info( "Skipped git checkout and pull" )
+
+ commit = main.ONOSbench.getVersion()
+ commit = (commit.split(" "))[1]
+
+ resultsDB = open("/tmp/IntentInstallWithdrawLatDBWFO", "w+")
+ resultsDB.close()
+
+ # -- END OF INIT SECTION --#
+
+ clusterCount = int(scale[0])
+ scale.remove(scale[0])
+
+ #kill off all onos processes
+ main.log.step("Safety check, killing all ONOS processes")
+ main.log.step("before initiating environment setup")
+ for node in range(1, main.maxNodes + 1):
+ main.ONOSbench.onosDie(ONOSIp[node])
+
+ #Uninstall everywhere
+ main.log.step( "Cleaning Enviornment..." )
+ for i in range(1, main.maxNodes + 1):
+ main.log.info(" Uninstalling ONOS " + str(i) )
+ main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+ #construct the cell file
+ main.log.info("Creating cell file")
+ cellIp = []
+ for node in range (1, clusterCount + 1):
+ cellIp.append(ONOSIp[node])
+
+ main.ONOSbench.createCellFile(BENCHIp,cellName,MN1Ip,str(Apps), cellIp)
+
+ main.step( "Set Cell" )
+ main.ONOSbench.setCell(cellName)
+
+ main.step( "Creating ONOS package" )
+ packageResult = main.ONOSbench.onosPackage()
+
+ main.step( "verify cells" )
+ verifyCellResult = main.ONOSbench.verifyCell()
+
+ main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
+ for node in range(1, clusterCount + 1):
+ main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+ main.ONOSbench.onosInstall( ONOSIp[node])
+
+ for node in range(1, clusterCount + 1):
+ for i in range( 2 ):
+ isup = main.ONOSbench.isup( ONOSIp[node] )
+ if isup:
+ main.log.info("ONOS " + str(node) + " is up\n")
+ break
+ if not isup:
+ main.log.report( "ONOS " + str(node) + " didn't start!" )
+
+ main.ONOS1cli.startOnosCli( ONOSIp[1] )
+ main.log.info("Startup sequence complete")
+
+ time.sleep(30)
+
+ for i in range(3):
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", ("deviceCount " + str(switchCount)) )
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true")
+ main.ONOS1cli.setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator"," useFlowObjectives","true" )
+ if main.ONOSbench.verifySummary(ONOSIp[1], switchCount):
+ break
+ else:
+ print "Failed- looping"
+
+ main.ONOSbench.handle.sendline("""onos $OC1 "balance-masters" """)
+ main.ONOSbench.handle.expect(":~")
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+ def CASE2( self, main ):
+
+ import time
+ import numpy
+
+ testStatus = "pass"
+ sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+ warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+ intentsList = (main.params[ 'TEST' ][ 'intents' ]).split(",")
+ switchCount = int(main.params[ 'TEST' ][ 'switchCount' ])
+ debug = main.params[ 'TEST' ][ 'switchCount' ]
+ for i in range(0,len(intentsList)):
+ intentsList[i] = int(intentsList[i])
+
+ ######################
+ debug = True
+ ######################
+
+ linkCount = 0
+ for i in range(0,10):
+ main.ONOSbench.handle.sendline("onos $OC1 links|wc -l")
+ main.ONOSbench.handle.expect(":~")
+ linkCount = main.ONOSbench.handle.before
+ if debug: main.log.info("Link Count check: " + linkCount)
+ if str((switchCount*2)-2) in linkCount:
+ break
+ time.sleep(2)
+
+ links = "--"
+ for i in range(8):
+ if debug: main.log.info("top of loop")
+ main.ONOSbench.handle.sendline("onos $OC1 links")
+ main.ONOSbench.handle.expect(":~")
+ links = main.ONOSbench.handle.before
+ if "=null:" in links:
+ break
+ if debug: main.log.info(str(links))
+ if i > 3:
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+ if i == 7:
+ main.log.error("link data missing")
+ time.sleep(3)
+
+ links = links.splitlines()
+ templinks = links
+
+ tempDevices = []
+ for line in links:
+ temp = line.split(" ")
+ temp[0].replace("src=","")
+ temp[0] = (temp[0].split("/"))[0]
+ tempDevices.append(temp[0])
+
+ tempDevices.sort()
+ devices = []
+ for i in tempDevices:
+ if "src=null" in i:
+ devices.append(i.replace("src=", ""))
+ if debug: main.log.info(str(devices))
+
+ ingress = devices[0]
+ egress = devices.pop()
+ if debug: main.log.info(ingress)
+ if debug: main.log.info(egress)
+
+ for intentSize in intentsList:
+ cmd = "onos $OC1 push-test-intents "
+ cmd += ingress + "/6 "
+ cmd += egress + "/5 "
+ cmd += str(intentSize) + " 1"
+ installed = []
+ withdrawn = []
+ testStatus = ""
+
+ for run in range(0, (warmUp + sampleSize)):
+ if run > warmUp:
+ time.sleep(5)
+
+ myRawResult = "--"
+
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ myRawResult = main.ONOSbench.handle.before
+
+ if debug: main.log.info(myRawResult)
+
+ if run >= warmUp:
+ myRawResult = myRawResult.splitlines()
+ for line in myRawResult:
+ if "Failure:" in line:
+ main.log.error("INTENT TEST FAILURE, ABORTING TESTCASE")
+ testStatus = "fail"
+ break
+
+ if "install" in line:
+ installed.append(int(line.split(" ")[5]))
+
+ if "withdraw" in line:
+ withdrawn.append(int(line.split(" ")[5]))
+
+ if testStatus == "fail":
+ main.log.info("Installed: " + str(installed))
+ main.log.info("Withdrawn: " + str(withdrawn))
+ main.log.info("Scale: " + str(clusterCount))
+ main.log.info("Warmup: " + str(warmUp) + " SampleSize: " + str(sampleSize))
+ main.log.info("Run: " + str(run))
+ main.log.error("Skipping test case")
+ main.skipCase()
+
+ main.log.report("----------------------------------------------------")
+ main.log.report("Scale: " + str(clusterCount) + "\tIntent batch size: " + str(intentSize))
+ main.log.report("Data samples: " + str(sampleSize) + "\tWarm up tests: " + str(warmUp))
+ main.log.report("Installed average: " + str(numpy.mean(installed)))
+ main.log.report("Installed standard deviation: " + str(numpy.std(installed)))
+ main.log.report("Withdraw average: " + str(numpy.mean(withdrawn)))
+ main.log.report("Withdraw standard deviation: " + str(numpy.std(withdrawn)))
+ main.log.report(" ")
+
+ resultString = "'" + commit + "',"
+ resultString += str(clusterCount) + ","
+ resultString += str(intentSize) + ","
+ resultString += str(numpy.mean(installed)) + ","
+ resultString += str(numpy.std(installed)) + ","
+ resultString += str(numpy.mean(withdrawn)) + ","
+ resultString += str(numpy.std(withdrawn)) + "\n"
+ resultsDB = open("/tmp/IntentInstallWithdrawLatDBWFO", "a")
+ resultsDB.write(resultString)
+ resultsDB.close()
+
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+ time.sleep(20)
diff --git a/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.topo b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.topo
new file mode 100644
index 0000000..01370b6
--- /dev/null
+++ b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <home>~/onos</home>
+ <nodes>7</nodes>
+ </COMPONENTS>
+ </ONOSbench>
+
+ <ONOS1cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1cli>
+
+ <ONOS2cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2cli>
+
+ <ONOS3cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3cli>
+
+ <ONOS4cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4cli>
+
+ <ONOS5cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>6</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5cli>
+
+ <ONOS6cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>7</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6cli>
+
+ <ONOS7cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>8</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7cli>
+
+ <ONOS1>
+ <host>OC1</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>9</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1>
+
+ <ONOS2>
+ <host>OC2</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>10</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2>
+
+ <ONOS3>
+ <host>OC3</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>11</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3>
+
+ <ONOS4>
+ <host>OC4</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>12</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4>
+
+
+ <ONOS5>
+ <host>OC5</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>13</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5>
+
+ <ONOS6>
+ <host>OC6</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>14</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6>
+
+ <ONOS7>
+ <host>OC7</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>15</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7>
+
+ </COMPONENT>
+
+</TOPOLOGY>
+
diff --git a/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/__init__.py b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPFintentInstallWithdrawLatWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPFintentRerouteLatWithFlowObj/README b/TestON/tests/SCPFintentRerouteLatWithFlowObj/README
new file mode 100644
index 0000000..af912f1
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLatWithFlowObj/README
@@ -0,0 +1,29 @@
+INTENT REROUTE LATENCY
+
+Summary: This is a performance test designed to benchmark the
+ intent reroute speed of ONOS at various controller cluster sizes.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+ OC1->OC7 must be set before initiating the test. Passwordless login
+ must be set from TestStation "admin" root user.
+
+***If you wish to run this test with less than 7 nodes the
+ following alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in
+ the <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases> tag for
+ each value you removed from <scale> (case1 and 2 are each
+ called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3,5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to
+ your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.params b/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.params
new file mode 100644
index 0000000..73175d1
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.params
@@ -0,0 +1,79 @@
+<PARAMS>
+
+ <testcases>1,2,1,2,1,2,1,2</testcases>
+
+ <SCALE>1,3,5,7</SCALE>
+ <max>7</max>
+
+ <ENV>
+ <cellName>intentRerouteCell</cellName>
+ <cellApps>drivers,null,intentperf,metrics</cellApps>
+ </ENV>
+
+ <TEST>
+ <skipCleanInstall>yes</skipCleanInstall>
+ <warmUp>5</warmUp>
+ <sampleSize>20</sampleSize>
+ <wait></wait>
+ <intents>1,100,1000</intents> #list format, will be split on ','
+ <debug>True</debug>
+
+ <s1>1,1,1,1,1,1,1,1</s1>
+ <s3>2,2,1,1,3,3,3,1</s3>
+ <s5>2,2,1,1,3,4,5,3</s5>
+ <s7>2,3,1,1,5,6,7,4</s7>
+
+ </TEST>
+
+ <METRICS>
+ <Submitted>0</Submitted>
+ <Installed>1</Installed>
+ <Failed>0</Failed>
+ <Withdraw>0</Withdraw>
+ <Withdrawn>0</Withdrawn>
+ </METRICS>
+
+ <GIT>
+ <autopull>off</autopull>
+ <checkout>master</checkout>
+ </GIT>
+
+ <CTRL>
+ <USER>admin</USER>
+
+ <ip1>OC1</ip1>
+ <port1>6653</port1>
+
+ <ip2>OC2</ip2>
+ <port2>6653</port2>
+
+ <ip3>OC3</ip3>
+ <port3>6653</port3>
+
+ <ip4>OC4</ip4>
+ <port4>6653</port4>
+
+ <ip5>OC5</ip5>
+ <port5>6653</port5>
+
+ <ip6>OC6</ip6>
+ <port6>6653</port6>
+
+ <ip7>OC7</ip7>
+ <port7>6653</port7>
+
+ </CTRL>
+
+ <MN>
+ <ip1>localhost</ip1>
+ </MN>
+
+ <BENCH>
+ <user>admin</user>
+ <ip1>localhost</ip1>
+ </BENCH>
+
+ <JSON>
+ </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.py b/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.py
new file mode 100644
index 0000000..a7ecb43
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.py
@@ -0,0 +1,419 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFintentRerouteLatWithFlowObj:
+
+ def __init__( self ):
+ self.default = ''
+
+ def CASE1( self, main ):
+
+ import time
+
+ global init
+ try:
+ if type(init) is not bool:
+ init = False
+ except NameError:
+ init = False
+
+ #Load values from params file
+ checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+ gitPull = main.params[ 'GIT' ][ 'autopull' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+ Apps = main.params[ 'ENV' ][ 'cellApps' ]
+ BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+ BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+ MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+ main.maxNodes = int(main.params[ 'max' ])
+ skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+ # -- INIT SECTION, ONLY RUNS ONCE -- #
+ if init == False:
+ init = True
+ global clusterCount #number of nodes running
+ global ONOSIp #list of ONOS IP addresses
+ global scale
+ global commit
+
+ clusterCount = 0
+ ONOSIp = [ 0 ]
+ scale = (main.params[ 'SCALE' ]).split(",")
+ clusterCount = int(scale[0])
+
+ #Populate ONOSIp with ips from params
+ ONOSIp = [0]
+ ONOSIp.extend(main.ONOSbench.getOnosIps())
+
+ print("-----------------" + str(ONOSIp))
+ #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+ if skipMvn != "yes":
+ mvnResult = main.ONOSbench.cleanInstall()
+
+ #git
+ main.step( "Git checkout and pull " + checkoutBranch )
+ if gitPull == 'on':
+ checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+ pullResult = main.ONOSbench.gitPull()
+
+ else:
+ checkoutResult = main.TRUE
+ pullResult = main.TRUE
+ main.log.info( "Skipped git checkout and pull" )
+
+ commit = main.ONOSbench.getVersion()
+ commit = (commit.split(" "))[1]
+
+ resultsDB = open("/tmp/IntentRerouteLatDBWithFlowObj", "w+")
+ resultsDB.close()
+
+ # -- END OF INIT SECTION --#
+
+ clusterCount = int(scale[0])
+ scale.remove(scale[0])
+
+ #kill off all onos processes
+ main.log.step("Safety check, killing all ONOS processes")
+ main.log.step("before initiating environment setup")
+ for node in range(1, main.maxNodes + 1):
+ main.ONOSbench.onosDie(ONOSIp[node])
+
+ #Uninstall everywhere
+ main.log.step( "Cleaning Enviornment..." )
+ for i in range(1, main.maxNodes + 1):
+ main.log.info(" Uninstalling ONOS " + str(i) )
+ main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+ #construct the cell file
+ main.log.info("Creating cell file")
+ cellIp = []
+ for node in range (1, clusterCount + 1):
+ cellIp.append(ONOSIp[node])
+
+ main.ONOSbench.createCellFile(BENCHIp,cellName,MN1Ip,str(Apps), cellIp)
+
+ main.step( "Set Cell" )
+ main.ONOSbench.setCell(cellName)
+
+ main.step( "Creating ONOS package" )
+ packageResult = main.ONOSbench.onosPackage()
+
+ main.step( "verify cells" )
+ verifyCellResult = main.ONOSbench.verifyCell()
+
+ main.log.report( "Initializing " + str( clusterCount ) + " node cluster." )
+ for node in range(1, clusterCount + 1):
+ main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+ main.ONOSbench.onosInstall( ONOSIp[node])
+
+ for node in range(1, clusterCount + 1):
+ for i in range( 2 ):
+ isup = main.ONOSbench.isup( ONOSIp[node] )
+ if isup:
+ main.log.info("ONOS " + str(node) + " is up\n")
+ break
+ if not isup:
+ main.log.report( "ONOS " + str(node) + " didn't start!" )
+ main.log.info("Startup sequence complete")
+
+ deviceMastership = (main.params[ 'TEST' ][ "s" + str(clusterCount) ]).split(",")
+ print("Device mastership list: " + str(deviceMastership))
+
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.store.flow.impl.NewDistributedFlowRuleStore", "backupEnabled false")
+
+ main.log.step("Setting up null provider")
+ for i in range(3):
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "deviceCount 8")
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape reroute")
+ main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true")
+ main.ONOS1cli.setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator", "useFlowObjectives", "true")
+ time.sleep(5)
+ main.ONOSbench.handle.sendline("onos $OC1 summary")
+ main.ONOSbench.handle.expect(":~")
+ x = main.ONOSbench.handle.before
+ if "devices=8" in x and "links=16," in x:
+ break
+
+ index = 1
+ for node in deviceMastership:
+ for attempt in range(0,10):
+ cmd = ( "onos $OC" + node + """ "device-role null:000000000000000""" + str(index) + " " + ONOSIp[int(node)] + """ master" """)
+ main.log.info("assigning mastership of device " + str(index) + " to node " + node + ": \n " + cmd + "\n")
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ time.sleep(4)
+
+ cmd = ( "onos $OC" + node + " roles|grep 00000" + str(index))
+ main.log.info(cmd)
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ check = main.ONOSbench.handle.before
+ main.log.info("CHECK:\n" + check)
+ if ("master=" + ONOSIp[int(node)]) in check:
+ break
+ index += 1
+
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+ def CASE2( self, main ):
+
+ import time
+ import numpy
+ import datetime
+ #from scipy import stats
+
+ ts = time.time()
+
+ sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+ warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+ intentsList = (main.params[ 'TEST' ][ 'intents' ]).split(",")
+ debug = main.params[ 'TEST' ][ 'debug' ]
+ for i in range(0,len(intentsList)):
+ intentsList[i] = int(intentsList[i])
+
+ timestampMetrics = []
+ if main.params['METRICS']['Submitted'] == "1":
+ timestampMetrics.append("Submitted")
+ if main.params['METRICS']['Installed'] == "1":
+ timestampMetrics.append("Installed")
+ if main.params['METRICS']['Failed'] == "1":
+ timestampMetrics.append("Failed")
+ if main.params['METRICS']['Withdraw'] == "1":
+ timestampMetrics.append("Withdraw")
+ if main.params['METRICS']['Withdrawn'] == "1":
+ timestampMetrics.append("Withdrawn")
+ if debug: main.log.info(timestampMetrics)
+
+ if debug == "True":
+ debug = True
+ else:
+ debug = False
+
+ ingress = "null:0000000000000001"
+ egress = "null:0000000000000007"
+
+ for intents in intentsList:
+ main.log.report("Intent Batch size: " + str(intents) + "\n ")
+ myResult = [["latency", "lastNode"] for x in range(sampleSize)]
+
+ for run in range(0, (warmUp + sampleSize)):
+ if run > warmUp:
+ main.log.info("Starting test iteration " + str(run-warmUp))
+
+ cmd = """onos $OC1 "push-test-intents -i """
+ cmd += ingress + "/0 "
+ cmd += egress + "/0 "
+ cmd += str(intents) +""" 1" """
+ if debug: main.log.info(cmd)
+
+ withdrawCmd = cmd.replace("intents -i", "intents -w ")
+
+ #push-test-intents
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ myRawResult = main.ONOSbench.handle.before
+
+ for i in range(0, 40):
+ main.ONOSbench.handle.sendline("onos $OC1 summary")
+ main.ONOSbench.handle.expect(":~")
+ linkCheck = main.ONOSbench.handle.before
+ if ("links=16,") in linkCheck and ("flows=" + str(intents*7) + ","):
+ break
+ if i == 39:
+ main.log.error("Flow/link count incorrect, data invalid."+ linkCheck)
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+ #main.ONOSbench.logReport(ONOSIp[(clusterCount-1)], ["ERROR", "WARNING", "EXCEPT"], "d")
+ main.ONOSbench.sendline("onos $OC1 summary")
+ main.ONOSbench.sendline("onos $OC1 devices")
+ main.ONOSbench.sendline("onos $OC1 links")
+ main.ONOSbench.expect(":~")
+ main.log.info(main.ONOSbench.before)
+
+ #collect timestamp from link cut
+ cmd = """onos $OC1 null-link "null:0000000000000004/1 null:0000000000000003/2 down" """
+ if debug: main.log.info("COMMAND: " + str(cmd))
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+
+ cmd = "onos-ssh $OC1 cat /opt/onos/log/karaf.log | grep TopologyManager| tail -1"
+ for i in range(0,10):
+ main.ONOSbench.handle.sendline(cmd)
+ time.sleep(2)
+ main.ONOSbench.handle.expect(":~")
+ raw = main.ONOSbench.handle.before
+ #if "NullLinkProvider" in raw and "links=14" in raw:
+ if "links=14" in raw:
+ break
+ if i >= 9:
+ main.log.error("Expected output not being recieved... continuing")
+ main.log.info(raw)
+ break
+ time.sleep(2)
+
+ if debug: main.log.debug("raw: " + raw)
+
+ temp = raw.splitlines()
+
+ if debug: main.log.debug("temp (after splitlines): " + str(temp))
+
+ # Since the string is deterministic the date is always the 3rd element.
+ # However, if the data were grepping for in the onos log changes then this will
+ # not work. This is why we print out the raw and temp string so we can visually
+ # check if everything is in the correct order. temp should like this:
+ # temp = ['/onos$ onos-ssh $OC1 cat /opt/onos/log/karaf.log | grep Top ',
+ # 'ologyManager| tail -1', '2015-10-15 12:03:33,736 ... ]
+ temp = temp[2]
+
+ if debug: main.log.debug("temp (checking for date): " + str(temp))
+
+ cutTimestamp = (temp.split(" "))[0] + " " + (temp.split(" "))[1]
+
+ if debug: main.log.info("Cut timestamp: " + cutTimestamp)
+
+ #validate link count and flow count
+ for i in range(0, 40):
+ main.ONOSbench.handle.sendline("onos $OC1 summary")
+ main.ONOSbench.handle.expect(":~")
+ linkCheck = main.ONOSbench.handle.before
+ #if "links=" + str(7*intents)+ "," in linkCheck and ("flows=" + str(7*intents) + ",") in linkCheck:
+ if "links=14," in linkCheck and ("flows=" + str(8*intents) + ",") in linkCheck:
+ break
+ if i == 39:
+ main.log.error("Link or flow count incorrect, data invalid." + linkCheck)
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+
+ time.sleep(5) #trying to avoid negative values
+
+ #intents events metrics installed timestamp
+ IEMtimestamps = [0]*(clusterCount + 1)
+ installedTemp = [0]*(clusterCount + 1)
+ for node in range(1, clusterCount +1):
+ cmd = "onos $OC" + str(node) + """ "intents-events-metrics"|grep Timestamp """
+ raw = ""
+ while "epoch)" not in raw:
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+ raw = main.ONOSbench.handle.before
+
+ print(raw)
+
+ intentsTimestamps = {}
+ rawTimestamps = raw.splitlines()
+ for line in rawTimestamps:
+ if "Timestamp" in line and "grep" not in line:
+ metricKey = (line.split(" "))[1]
+ metricTimestamp = (line.split(" ")[len(line.split(" ")) -1]).replace("epoch)=","")
+ metricTimestamp = float(metricTimestamp)
+ metricTimestamp = numpy.divide(metricTimestamp, 1000)
+ if debug: main.log.info(repr(metricTimestamp))
+ intentsTimestamps[metricKey] = metricTimestamp
+ if metricKey == "Installed":
+ installedTemp[node] = metricTimestamp
+
+ main.log.info("Node: " + str(node) + " Timestamps: " + str(intentsTimestamps))
+ IEMtimestamps[node] = intentsTimestamps
+
+ myMax = max(installedTemp)
+ indexOfMax = installedTemp.index(myMax)
+
+ #number crunch
+ for metric in timestampMetrics: #this is where we sould add support for computing other timestamp metrics
+ if metric == "Installed":
+ if run >= warmUp:
+ main.log.report("link cut timestamp: " + cutTimestamp)
+ #readableInstalledTimestamp = str(intentsTimestamps["Installed"])
+ readableInstalledTimestamp = str(myMax)
+
+ #main.log.report("Intent Installed timestamp: " + str(intentsTimestamps["Installed"]))
+ main.log.report("Intent Installed timestamp: " + str(myMax))
+
+ cutEpoch = time.mktime(time.strptime(cutTimestamp, "%Y-%m-%d %H:%M:%S,%f"))
+ if debug: main.log.info("cutEpoch=" + str(cutEpoch))
+ #rerouteLatency = float(intentsTimestamps["Installed"] - cutEpoch)
+ rerouteLatency = float(myMax - cutEpoch)
+
+ rerouteLatency = numpy.divide(rerouteLatency, 1000)
+ main.log.report("Reroute latency:" + str(rerouteLatency) + " (seconds)\n ")
+ myResult[run-warmUp][0] = rerouteLatency
+ myResult[run-warmUp][1] = indexOfMax
+ if debug: main.log.info("Latency: " + str(myResult[run-warmUp][0]))
+ if debug: main.log.info("last node: " + str(myResult[run-warmUp][1]))
+
+ cmd = """ onos $OC1 null-link "null:0000000000000004/1 null:0000000000000003/2 up" """
+ if debug: main.log.info(cmd)
+ main.ONOSbench.handle.sendline(cmd)
+ main.ONOSbench.handle.expect(":~")
+
+ #wait for intent withdraw
+ main.ONOSbench.handle.sendline(withdrawCmd)
+ main.log.info(withdrawCmd)
+ main.ONOSbench.handle.expect(":~")
+ if debug: main.log.info(main.ONOSbench.handle.before)
+ main.ONOSbench.handle.sendline("onos $OC1 intents|grep WITHDRAWN|wc -l")
+ main.ONOSbench.handle.expect(":~")
+ intentWithdrawCheck = main.ONOSbench.handle.before
+ if (str(intents)) in intentWithdrawCheck:
+ main.log.info("intents withdrawn")
+ if debug: main.log.info(intentWithdrawCheck)
+
+ # wait for links to be reestablished
+ for i in range(0, 10):
+ main.ONOSbench.handle.sendline("onos $OC1 summary")
+ main.ONOSbench.handle.expect(":~")
+ linkCheck = main.ONOSbench.handle.before
+ if "links=16," in linkCheck:
+ break
+ time.sleep(1)
+ if i == 9:
+ main.log.info("Links Failed to reconnect, next iteration of data invalid." + linkCheck)
+
+ if run < warmUp:
+ main.log.info("Warm up run " + str(run+1) + " completed")
+
+ if debug: main.log.info(myResult)
+ latTemp = []
+ nodeTemp = []
+ for i in myResult:
+ latTemp.append(i[0])
+ nodeTemp.append(i[1])
+
+ mode = {}
+ for i in nodeTemp:
+ if i in mode:
+ mode[i] += 1
+ else:
+ mode[i] = 1
+
+ for i in mode.keys():
+ if mode[i] == max(mode.values()):
+ nodeMode = i
+
+ average = numpy.average(latTemp)
+ stdDev = numpy.std(latTemp)
+
+ average = numpy.multiply(average, 1000)
+ stdDev = numpy.multiply(stdDev, 1000)
+
+ main.log.report("Scale: " + str(clusterCount) + " \tIntent batch: " + str(intents))
+ main.log.report("Latency average:................" + str(average))
+ main.log.report("Latency standard deviation:....." + str(stdDev))
+ main.log.report("Mode of last node to respond:..." + str(nodeMode))
+ main.log.report("________________________________________________________")
+
+ resultsDB = open("/tmp/IntentRerouteLatDBWithFlowObj", "a")
+ resultsDB.write("'" + commit + "',")
+ resultsDB.write(str(clusterCount) + ",")
+ resultsDB.write(str(intents) + ",")
+ resultsDB.write(str(average) + ",")
+ resultsDB.write(str(stdDev) + "\n")
+ resultsDB.close()
+
+ main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
diff --git a/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.topo b/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.topo
new file mode 100644
index 0000000..01370b6
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <home>~/onos</home>
+ <nodes>7</nodes>
+ </COMPONENTS>
+ </ONOSbench>
+
+ <ONOS1cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1cli>
+
+ <ONOS2cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2cli>
+
+ <ONOS3cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3cli>
+
+ <ONOS4cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4cli>
+
+ <ONOS5cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>6</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5cli>
+
+ <ONOS6cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>7</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6cli>
+
+ <ONOS7cli>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>8</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7cli>
+
+ <ONOS1>
+ <host>OC1</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>9</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1>
+
+ <ONOS2>
+ <host>OC2</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>10</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2>
+
+ <ONOS3>
+ <host>OC3</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>11</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3>
+
+ <ONOS4>
+ <host>OC4</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>12</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4>
+
+
+ <ONOS5>
+ <host>OC5</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>13</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5>
+
+ <ONOS6>
+ <host>OC6</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>14</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6>
+
+ <ONOS7>
+ <host>OC7</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>15</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7>
+
+ </COMPONENT>
+
+</TOPOLOGY>
+
diff --git a/TestON/tests/SCPFintentRerouteLatWithFlowObj/__init__.py b/TestON/tests/SCPFintentRerouteLatWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLatWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/Dependency/rerouteTopo.py b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/Dependency/rerouteTopo.py
new file mode 100755
index 0000000..774f12f
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/Dependency/rerouteTopo.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+ def __init__( self ):
+ # Initialize topology
+ Topo.__init__( self )
+
+ host1 = self.addHost('h1', ip='10.1.0.1/24')
+ host2 = self.addHost('h2', ip='10.1.0.2/24')
+ host3 = self.addHost('h3', ip='10.1.0.3/24')
+ host4 = self.addHost('h4', ip='10.1.0.4/24')
+ host5 = self.addHost('h5', ip='10.1.0.5/24')
+ host6 = self.addHost('h6', ip='10.1.0.6/24')
+ host7 = self.addHost('h7', ip='10.1.0.7/24')
+
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+ s4 = self.addSwitch( 's4' )
+ s5 = self.addSwitch( 's5' )
+ s6 = self.addSwitch( 's6' )
+ s7 = self.addSwitch( 's7' )
+ s8 = self.addSwitch( 's8' )
+
+
+ self.addLink(s1, host1)
+ self.addLink(s2, host2)
+ self.addLink(s3, host3)
+ self.addLink(s4, host4)
+ self.addLink(s5, host5)
+ self.addLink(s6, host6)
+ self.addLink(s7, host7)
+
+
+
+ self.addLink(s1,s2)
+ self.addLink(s2,s3)
+ self.addLink(s3,s4)
+ self.addLink(s4,s5)
+ self.addLink(s5,s6)
+ self.addLink(s6,s7)
+ self.addLink(s4,s8)
+ self.addLink(s8,s5)
+
+ topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = MyTopo()
+ network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/Dependency/startUp.py b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+ This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+ """
+ This includes pulling ONOS and building it using maven install
+ """
+
+ buildResult = main.FALSE
+
+ # Git checkout a branch of ONOS
+ checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+ # Does the git pull on the branch that was checked out
+ if not checkOutResult:
+ main.log.warn( "Failed to checked out " + gitBranch +
+ " branch")
+ else:
+ main.log.info( "Successfully checked out " + gitBranch +
+ " branch")
+ gitPullResult = main.ONOSbench.gitPull()
+ if gitPullResult == main.ERROR:
+ main.log.error( "Error pulling git branch" )
+ else:
+ main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+ # Maven clean install
+ buildResult = main.ONOSbench.cleanInstall()
+
+ return buildResult
+
+
+
+
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/README b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/README
new file mode 100644
index 0000000..0c16859
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/README
@@ -0,0 +1,11 @@
+Summary:
+ This is a performance test suit, designed to test the upper limits
+ of onos and ovsdb with respect to installing intents.
+ In this test, CASE10 set up null provoder, CASE 11 set up ovs. Start from
+ 1 node, and scale to 7 nodes.
+ We push intents to every node by using Thread, and when the intents number
+ reach to the minimun number, we will verify intents and flows. If intents are
+ not installed correctly, test will stop pushing and finish this case.
+NOTE:
+ This test is largely based on the hardware used to run onos and mininet.
+ Therefore, results will very test station to test station.
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.params b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.params
new file mode 100644
index 0000000..a6a3377
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.params
@@ -0,0 +1,99 @@
+<PARAMS>
+
+ # 0-init
+ # 1-setup
+ # 2-Install
+ # 10-null provider setup
+ # 20-pushing intents, and rerouting intents if reroute is true
+ # 0,1,2,10,20,1,2,10,20,1,2,10,20
+ <testcases>0,1,2,11,20,1,2,11,20,1,2,11,20,1,2,11,20</testcases>
+
+ <reroute>False</reroute>
+
+ <SCALE>1,3,5,7</SCALE>
+
+ <DEPENDENCY>
+ <path>/tests/SCPFscalingMaxIntents/Dependency/</path>
+ <wrapper1>startUp</wrapper1>
+ <topology>rerouteTopo.py</topology>
+ </DEPENDENCY>
+
+ <ENV>
+ <cellName>productionCell</cellName>
+ <cellApps>drivers</cellApps>
+ </ENV>
+
+ <GIT>
+ <pull>False</pull>
+ <branch>master</branch>
+ </GIT>
+
+ <CTRL>
+ <port>6653</port>
+ </CTRL>
+
+ <SLEEP>
+ <startup>10</startup>
+ <install>10</install>
+ <verify>15</verify>
+ <reroute>3</reroute>
+ # timeout for pexpect
+ <timeout>300</timeout>
+ </SLEEP>
+
+ <ATTEMPTS>
+ <verify>3</verify>
+ <push>3</push>
+ </ATTEMPTS>
+
+ <DATABASE>
+ <file>/tmp/ScalingMaxIntentDBWFO</file>
+ <nic>1gig</nic>
+ <node>baremetal</node>
+ </DATABASE>
+
+ <LINK>
+ <ingress>0000000000000001/5</ingress>
+ <egress>0000000000000007/5</egress>
+ </LINK>
+
+ # CASE10
+ <NULL>
+ # CASE20
+ <PUSH>
+ <batch_size>100</batch_size>
+ <min_intents>100</min_intents>
+ <max_intents>100000</max_intents>
+ <check_interval>100</check_interval>
+ </PUSH>
+
+ # if reroute is true
+ <REROUTE>
+ <batch_size>1000</batch_size>
+ <min_intents>10000</min_intents>
+ <max_intents>1000000</max_intents>
+ <check_interval>100000</check_interval>
+ </REROUTE>
+ </NULL>
+
+ # CASE11
+ <OVS>
+ # CASE20
+ <PUSH>
+ <batch_size>1000</batch_size>
+ <min_intents>10000</min_intents>
+ <max_intents>500000</max_intents>
+ <check_interval>10000</check_interval>
+ </PUSH>
+
+ # if reroute is true
+ <REROUTE>
+ <batch_size>1000</batch_size>
+ <min_intents>10000</min_intents>
+ <max_intents>500000</max_intents>
+ <check_interval>10000</check_interval>
+ </REROUTE>
+ </OVS>
+
+
+</PARAMS>
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.py b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.py
new file mode 100644
index 0000000..e405fd3
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.py
@@ -0,0 +1,561 @@
+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 )
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.topo b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.topo
new file mode 100755
index 0000000..fd28336
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.topo
@@ -0,0 +1,101 @@
+<TOPOLOGY>
+
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <home>~/onos</home>
+ <nodes>7</nodes>
+ </COMPONENTS>
+ </ONOSbench>
+
+ <ONOSrest1>
+ <host>OC1</host>
+ <port>8181</port>
+ <user>onos</user>
+ <password>rocks</password>
+ <type>OnosRestDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </ONOSrest1>
+ <ONOScli1>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli1>
+
+ <ONOScli2>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli2>
+
+ <ONOScli3>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli3>
+
+ <ONOScli4>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli4>
+
+ <ONOScli5>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>6</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli5>
+
+ <ONOScli6>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>7</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli6>
+
+ <ONOScli7>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>8</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli7>
+
+ <Mininet1>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>MininetCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </Mininet1>
+
+ </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/__init__.py b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPFscalingMaxIntentsWithFlowObj/__init__.py