Merge "Revert "Add workaround for onos not respawning""
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 54e7d0f..a34741a 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -181,7 +181,7 @@
main.log.info(
"Starting Mininet from topo file " +
topoFile )
- cmdString += topoFile + " "
+ cmdString += "-E python " + topoFile + " "
if args is None:
args = ''
# TODO: allow use of args from .topo file?
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 32856b4..9e6d5ff 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -671,7 +671,7 @@
main.exit()
def createCellFile( self, benchIp, fileName, mnIpAddrs,
- appString, onosIpAddrs ):
+ appString, onosIpAddrs, onosUser="sdn" ):
"""
Creates a cell file based on arguments
Required:
@@ -683,6 +683,8 @@
supported currently
* ONOS IP addresses ( onosIpAddrs )
- Must be passed in as last arguments
+ * ONOS USER (onosUser)
+ - optional argument to set ONOS_USER environment variable
NOTE: Assumes cells are located at:
~/<self.home>/tools/test/cells/
@@ -702,6 +704,8 @@
# Note that you may not want certain apps listed
# on here.
appString = "export ONOS_APPS=" + appString
+ onosGroup = "export ONOS_GROUP=" + onosUser
+ onosUser = "export ONOS_USER=" + onosUser
mnString = "export OCN="
if mnIpAddrs == "":
mnString = ""
@@ -734,6 +738,8 @@
cellFile.write( "export OCI=$OC1\n" )
cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cellFile.write( appString + "\n" )
+ cellFile.write( onosGroup + "\n" )
+ cellFile.write( onosUser + "\n" )
cellFile.close()
# We use os.system to send the command to TestON cluster
@@ -994,17 +1000,19 @@
"\$",
"Unknown\sinstance",
pexpect.TIMEOUT ], timeout=120 )
- self.handle.expect( "\$" )
if i == 0:
+ self.handle.expect( "\$" )
main.log.info( "Service is already running" )
return main.TRUE
elif i == 1:
+ self.handle.expect( "\$" )
main.log.info( "ONOS service started" )
return main.TRUE
elif i == 2:
main.log.info( "ONOS service started" )
return main.TRUE
else:
+ self.handle.expect( "\$" )
main.log.error( "ONOS service failed to start" )
main.cleanup()
main.exit()
diff --git a/TestON/tests/USECASE_SegmentRouting/2x2.json b/TestON/tests/USECASE_SegmentRouting/2x2.json
new file mode 100644
index 0000000..c6c2eb8
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/2x2.json
@@ -0,0 +1,104 @@
+{
+ "ports" : {
+ "of:0000000000000001/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.1.254/24" ]
+ }
+ ]
+ },
+ "of:0000000000000001/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.1.254/24" ]
+ }
+ ]
+ },
+ "of:0000000000000002/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.2.254/24" ]
+ }
+ ]
+ },
+ "of:0000000000000002/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.2.254/24" ]
+ }
+ ]
+ }
+ },
+ "devices" : {
+ "of:0000000000000001" : {
+ "basic":{ "driver" : "ofdpa-cpqd" },
+ "segmentrouting" : {
+ "name" : "Leaf-R1",
+ "nodeSid" : 1,
+ "routerIp" : "192.168.0.1",
+ "routerMac" : "00:00:00:00:00:01",
+ "isEdgeRouter" : true,
+ "adjacencySids" : []
+ }
+ },
+ "of:0000000000000002" : {
+ "basic":{ "driver" : "ofdpa-cpqd" },
+ "segmentrouting" : {
+ "name" : "Leaf-R2",
+ "nodeSid" : 2,
+ "routerIp" : "192.168.0.2",
+ "routerMac" : "00:00:00:00:00:02",
+ "isEdgeRouter" : true,
+ "adjacencySids" : []
+ }
+ },
+ "of:0000000000000101" : {
+ "basic":{ "driver" : "ofdpa-cpqd" },
+ "segmentrouting" : {
+ "name" : "Spine-R1",
+ "nodeSid" : 101,
+ "routerIp" : "192.168.0.101",
+ "routerMac" : "00:00:00:00:01:01",
+ "isEdgeRouter" : false,
+ "adjacencySids" : []
+ }
+ },
+ "of:0000000000000102" : {
+ "basic":{ "driver" : "ofdpa-cpqd" },
+ "segmentrouting" : {
+ "name" : "Spine-R2",
+ "nodeSid" : 102,
+ "routerIp" : "192.168.0.102",
+ "routerMac" : "00:00:00:00:01:02",
+ "isEdgeRouter" : false,
+ "adjacencySids" : []
+ }
+ }
+ },
+ "hosts" : {
+ "00:00:00:00:00:01/4093" : {
+ "basic": {
+ "ips": ["10.0.1.1"],
+ "location": "of:0000000000000001/3"
+ }
+ },
+ "00:00:00:00:00:02/4093" : {
+ "basic": {
+ "ips": ["10.0.1.2"],
+ "location": "of:0000000000000001/4"
+ }
+ },
+ "00:00:00:00:00:03/4093" : {
+ "basic": {
+ "ips": ["10.0.2.1"],
+ "location": "of:0000000000000002/3"
+ }
+ },
+ "00:00:00:00:00:04/4093" : {
+ "basic": {
+ "ips": ["10.0.2.2"],
+ "location": "of:0000000000000002/4"
+ }
+ }
+ }
+}
diff --git a/TestON/tests/USECASE_SegmentRouting/Dependency/cord_fabric.py b/TestON/tests/USECASE_SegmentRouting/Dependency/cord_fabric.py
new file mode 100755
index 0000000..b710b12
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/Dependency/cord_fabric.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+import os
+from optparse import OptionParser
+
+from mininet.net import Mininet
+from mininet.topo import Topo
+from mininet.node import RemoteController, UserSwitch, Host
+from mininet.link import TCLink
+from mininet.log import setLogLevel
+from mininet.cli import CLI
+
+# Parse command line options and dump results
+def parseOptions():
+ """Parse command line options"""
+ parser = OptionParser()
+ parser.add_option('--spine', dest='spine', type='int', default=2,
+ help='number of spine switches, default=2')
+ parser.add_option('--leaf', dest='leaf', type='int', default=2,
+ help='number of leaf switches, default=2')
+ parser.add_option('--fanout', dest='fanout', type='int', default=2,
+ help='number of hosts per leaf switch, default=2')
+ parser.add_option('--onos', dest='onos', type='int', default=0,
+ help='number of ONOS Instances, default=0, 0 means localhost, 1 will use OC1 and so on')
+
+ (options, args) = parser.parse_args()
+ return options, args
+
+opts, args = parseOptions()
+
+class LeafAndSpine(Topo):
+ def __init__(self, spine=2, leaf=2, fanout=2, **opts):
+ "Create Leaf and Spine Topo."
+
+ Topo.__init__(self, **opts)
+
+ # Add spine switches
+ spines = {}
+ for s in range(spine):
+ spines[s] = self.addSwitch('spine10%s' % (s + 1), dpid="00000000010%s" % (s + 1))
+ # Set link speeds to 100Mb/s
+ linkopts = dict(bw=10)
+
+ # Add Leaf switches
+ for ls in range(leaf):
+ leafSwitch = self.addSwitch('leaf%s' % (ls + 1), dpid="00000000000%s" % (1+ls))
+ # Connect leaf to all spines
+ for s in range(spine):
+ switch = spines[s]
+ self.addLink(leafSwitch, switch, **linkopts)
+ # Add hosts under a leaf, fanout hosts per leaf switch
+ for f in range(fanout):
+ host = self.addHost('h%s' % (ls * fanout + f + 1),
+ cls=IpHost,
+ ip='10.0.%s.%s/24' % ((ls + 1), (f + 1)),
+ gateway='10.0.%s.254' % (ls + 1))
+ self.addLink(host, leafSwitch, **linkopts)
+
+class IpHost(Host):
+ def __init__(self, name, gateway, *args, **kwargs):
+ super(IpHost, self).__init__(name, *args, **kwargs)
+ self.gateway = gateway
+
+ def config(self, **kwargs):
+ Host.config(self, **kwargs)
+ mtu = "ifconfig "+self.name+"-eth0 mtu 1490"
+ self.cmd(mtu)
+ self.cmd('ip route add default via %s' % self.gateway)
+
+def config(opts):
+ spine = opts.spine
+ leaf = opts.leaf
+ fanout = opts.fanout
+ controllers= [ os.environ['OC%s' % i] for i in range(1,opts.onos+1) ] if (opts.onos) else ['127.0.0.1']
+ topo = LeafAndSpine(spine=spine, leaf=leaf, fanout=fanout)
+ net = Mininet(topo=topo, link=TCLink, build=False,
+ switch=UserSwitch,
+ controller = None,
+ autoSetMacs = True)
+ i = 0
+ for ip in controllers:
+ net.addController( "c%s" % (i), controller=RemoteController, ip=ip)
+ i += 1;
+ net.build()
+ net.start()
+ CLI(net)
+ net.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ config(opts)
+ os.system('sudo mn -c')
+
diff --git a/TestON/tests/USECASE_SegmentRouting/Dependency/startUp.py b/TestON/tests/USECASE_SegmentRouting/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/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/USECASE_SegmentRouting/README.md b/TestON/tests/USECASE_SegmentRouting/README.md
new file mode 100644
index 0000000..da75079
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/README.md
@@ -0,0 +1,18 @@
+This test is designed to verify basic connectivity the SegmentRouting application.
+
+It consists of
+
+1) Installing and Starting ONOS
+2) Starting Mininet and testing connectivity
+
+Requirements
+
+ - A single ONOS instance is required for the test, the application is currently not stable in a cluster.
+ - An updated version of the CPQD switch has to be running to make sure it supports group chaining.
+
+Step 1:
+In this step we copy the proper config file to ONOS, next we package ONOS and install it in the target machine.
+
+Step 2:
+
+In this step we start a 2x2 leaf-spine topology, connect to ONOS, and next we send several pings between hosts to test connectivity.
diff --git a/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.params b/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.params
new file mode 100755
index 0000000..93c957f
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.params
@@ -0,0 +1,35 @@
+<PARAMS>
+
+ <testcases>1,2,11,9</testcases>
+
+ <SCALE>
+ <size>1</size>
+ <max>1</max>
+ </SCALE>
+
+ <DEPENDENCY>
+ <path>/tests/USECASE_SegmentRouting/Dependency/</path>
+ <wrapper1>startUp</wrapper1>
+ <topology>cord_fabric.py</topology>
+ </DEPENDENCY>
+
+ <ENV>
+ <cellName>productionCell</cellName>
+ <cellApps>drivers,openflow-base,netcfghostprovider,netcfglinksprovider,segmentrouting,vrouter,hostprovider</cellApps>
+ <cellUser>sdn</cellUser>
+ </ENV>
+
+ <GIT>
+ <pull>False</pull>
+ <branch>master</branch>
+ </GIT>
+
+ <CTRL>
+ <port>6653</port>
+ </CTRL>
+
+ <SLEEP>
+ <startup>15</startup>
+ </SLEEP>
+
+</PARAMS>
diff --git a/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.py b/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.py
new file mode 100644
index 0000000..7ba0b30
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.py
@@ -0,0 +1,237 @@
+
+# This test is to determine if the Segment Routing application is working properly
+
+class USECASE_SegmentRouting:
+
+ def __init__( self ):
+ self.default = ''
+
+ def CASE1( self, main ):
+ import time
+ import os
+ import imp
+ import re
+
+ """
+ - Construct tests variables
+ - GIT ( optional )
+ - Checkout ONOS master branch
+ - Pull latest ONOS code
+ - Building ONOS ( optional )
+ - Install ONOS package
+ - Build ONOS package
+ """
+
+ main.case( "Constructing test variables and building ONOS package" )
+ main.step( "Constructing test variables" )
+ stepResult = main.FALSE
+
+ # Test variables
+ main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
+ main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+ main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+ gitBranch = main.params[ 'GIT' ][ 'branch' ]
+ main.dependencyPath = main.testOnDirectory + \
+ main.params[ 'DEPENDENCY' ][ 'path' ]
+ main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+ main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
+ main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
+ main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+ wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+ main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+ gitPull = main.params[ 'GIT' ][ 'pull' ]
+ main.cellData = {} # for creating cell file
+ main.CLIs = []
+ main.ONOSip = []
+
+ main.ONOSip = main.ONOSbench.getOnosIps()
+
+ # Assigning ONOS cli handles to a list
+ for i in range( 1, main.maxNodes + 1 ):
+ main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+
+ # -- INIT SECTION, ONLY RUNS ONCE -- #
+ main.startUp = imp.load_source( wrapperFile1,
+ main.dependencyPath +
+ wrapperFile1 +
+ ".py" )
+
+ copyResult1 = main.ONOSbench.scp( main.Mininet1,
+ main.dependencyPath +
+ main.topology,
+ main.Mininet1.home,
+ direction="to" )
+ if main.CLIs:
+ stepResult = main.TRUE
+ else:
+ main.log.error( "Did not properly created list of ONOS CLI handle" )
+ stepResult = main.FALSE
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully construct " +
+ "test variables ",
+ onfail="Failed to construct test variables" )
+
+ if gitPull == 'True':
+ main.step( "Building ONOS in " + gitBranch + " branch" )
+ onosBuildResult = main.startUp.onosBuild( main, gitBranch )
+ stepResult = onosBuildResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully compiled " +
+ "latest ONOS",
+ onfail="Failed to compile " +
+ "latest ONOS" )
+ else:
+ main.log.warn( "Did not pull new code so skipping mvn " +
+ "clean install" )
+
+ def CASE2( self, main ):
+ """
+ - Set up cell
+ - Create cell file
+ - Set cell file
+ - Verify cell file
+ - Kill ONOS process
+ - Uninstall ONOS cluster
+ - Verify ONOS start up
+ - Install ONOS cluster
+ - Connect to cli
+ """
+
+ # main.scale[ 0 ] determines the current number of ONOS controller
+ main.numCtrls = int( main.scale[ 0 ] )
+
+ main.case( "Starting up " + str( main.numCtrls ) +
+ " node(s) ONOS cluster" )
+
+ #kill off all onos processes
+ main.log.info( "Safety check, killing all ONOS processes" +
+ " before initiating environment setup" )
+
+ for i in range( main.maxNodes ):
+ main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+ print "NODE COUNT = ", main.numCtrls
+
+ tempOnosIp = []
+ for i in range( main.numCtrls ):
+ tempOnosIp.append( main.ONOSip[i] )
+
+ onosUser = main.params[ 'ENV' ][ 'cellUser' ]
+ main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+ "temp",
+ main.Mininet1.ip_address,
+ main.apps,
+ tempOnosIp,
+ onosUser)
+
+ 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" )
+ main.ONOSbench.handle.sendline( "cp ~/TestON/tests/USECASE_SegmentRouting/2x2.json ~/onos/tools/package/config/network-cfg.json")
+ 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" )
+
+ time.sleep( main.startUpSleep )
+ main.step( "Installing ONOS package" )
+ onosInstallResult = main.TRUE
+ for i in range( main.numCtrls ):
+ onosInstallResult = onosInstallResult and \
+ main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
+ stepResult = onosInstallResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully installed ONOS package",
+ onfail="Failed to install ONOS package" )
+
+ main.step( "Starting ONOS service" )
+ stopResult = main.TRUE
+ startResult = main.TRUE
+ onosIsUp = main.TRUE
+
+ for i in range( main.numCtrls ):
+ onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+ if onosIsUp == main.TRUE:
+ main.log.report( "ONOS instance is up and ready" )
+ else:
+ main.log.report( "ONOS instance may not be up, stop and " +
+ "start ONOS again " )
+ for i in range( main.numCtrls ):
+ stopResult = stopResult and \
+ main.ONOSbench.onosStop( main.ONOSip[ i ] )
+ for i in range( main.numCtrls ):
+ startResult = startResult and \
+ main.ONOSbench.onosStart( main.ONOSip[ i ] )
+ stepResult = onosIsUp and stopResult and startResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="ONOS service is ready",
+ onfail="ONOS service did not start properly" )
+ time.sleep( main.startUpSleep )
+
+ def CASE9( self, main ):
+ '''
+ Report errors/warnings/exceptions
+ '''
+ #main.ONOSbench.logReport( main.ONOSip[ 0 ],
+ # [ "INFO" ],
+ # "a" )
+ #main.log.info("Error report: \n" )
+ main.ONOSbench.logReport( main.ONOSip[ 0 ],
+ [ "INFO",
+ "FOLLOWER",
+ "WARN",
+ "flow",
+ "ERROR",
+ "Except" ],
+ "s" )
+
+
+ def CASE11( self, main ):
+ """
+ Start mininet
+ """
+ main.log.report( "Start Mininet topology" )
+ main.log.case( "Start Mininet topology" )
+
+ main.step( "Starting Mininet Topology" )
+ topoResult = main.Mininet1.startNet( topoFile= main.dependencyPath + main.topology, args="--onos 1" )
+ stepResult = topoResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully loaded topology",
+ onfail="Failed to load topology" )
+ # Exit if topology did not load properly
+ if not topoResult:
+ main.cleanup()
+ main.exit()
+ main.step("Waiting for switch initialization and configuration")
+ time.sleep( main.startUpSleep )
+ pa = main.Mininet1.pingall()
+ utilities.assert_equals( expect=main.TRUE, actual=pa,
+ onpass="Full connectivity successfully tested",
+ onfail="Full connectivity failed" )
+ # cleanup mininet
+ main.CLIs[0].logout()
+ main.ONOSbench.onosStop( main.ONOSip[0] )
+ main.Mininet1.stopNet()
+ main.Mininet1.disconnect()
+
+
+
+
+
diff --git a/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.topo b/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.topo
new file mode 100755
index 0000000..0484c01
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/USECASE_SegmentRouting.topo
@@ -0,0 +1,37 @@
+<TOPOLOGY>
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <nodes>1</nodes>
+ </COMPONENTS>
+ </ONOSbench>
+
+ <ONOScli1>
+ <host>localhost</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </ONOScli1>
+
+ <Mininet1>
+ <host>OCN</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>MininetCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS>
+ <home>~/mininet/custom/</home>
+ </COMPONENTS>
+ </Mininet1>
+
+ </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/USECASE_SegmentRouting/__init__.py b/TestON/tests/USECASE_SegmentRouting/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE_SegmentRouting/__init__.py