Add vpls drivers and test
Change-Id: I793d9f3a80af6808387f360b862d3e284f689246
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index e6e8cf9..90f79a9 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -587,11 +587,10 @@
main.log.info( self.name + ": no packets lost, host is reachable" )
return main.TRUE
else:
- main.log.info(
+ main.log.warn(
self.name +
": PACKET LOST, HOST IS NOT REACHABLE" )
return main.FALSE
-
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 08f8a5b..d7847b6 100755
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -3347,7 +3347,7 @@
main.cleanup()
main.exit()
- def partitions( self, jsonFormat=True ):
+ def partitions( self, candidates=False, jsonFormat=True ):
"""
Returns the output of the raft partitions command for ONOS.
"""
@@ -3364,6 +3364,8 @@
# },
try:
cmdStr = "onos:partitions"
+ if candidates:
+ cmdStr += " -c"
if jsonFormat:
cmdStr += " -j"
output = self.sendline( cmdStr )
@@ -4704,7 +4706,7 @@
return main.TRUE
except AssertionError:
main.log.exception( "" )
- return None
+ return main.FALSE
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return main.FALSE
@@ -4788,7 +4790,7 @@
return main.TRUE
except AssertionError:
main.log.exception( "" )
- return None
+ return main.FALSE
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return main.FALSE
@@ -4824,7 +4826,7 @@
return main.TRUE
except AssertionError:
main.log.exception( "" )
- return None
+ return main.FALSE
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return main.FALSE
@@ -4838,20 +4840,22 @@
main.cleanup()
main.exit()
- def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
+ def portstate( self, dpid, port, state ):
'''
Description:
Changes the state of port in an OF switch by means of the
PORTSTATUS OF messages.
params:
- dpid - (string) Datapath ID of the device
- port - (string) target port in the device
- state - (string) target state (enable or disabled)
+ dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
+ port - (string) target port in the device. Ex: '2'
+ state - (string) target state (enable or disable)
returns:
main.TRUE if no exceptions were thrown and no Errors are
present in the resoponse. Otherwise, returns main.FALSE
'''
try:
+ state = state.lower()
+ assert state == 'enable' or state == 'disable', "Unknown state"
cmd = "portstate {} {} {}".format( dpid, port, state )
response = self.sendline( cmd, showResponse=True )
assert response is not None, "Error in sendline"
@@ -4862,7 +4866,7 @@
return main.TRUE
except AssertionError:
main.log.exception( "" )
- return None
+ return main.FALSE
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return main.FALSE
@@ -5057,3 +5061,346 @@
main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
+
+ def vplsShow( self, jsonFormat=True ):
+ """
+ Description: Returns result of onos:vpls show, which should list the
+ configured VPLS networks and the assigned interfaces.
+ Optional:
+ * jsonFormat: enable json formatting of output
+ Returns:
+ The output of the command or None on error.
+ """
+ try:
+ cmdStr = "vpls show"
+ if jsonFormat:
+ raise NotImplementedError
+ cmdStr += " -j"
+ handle = self.sendline( cmdStr )
+ assert handle is not None, "Error in sendline"
+ assert "Command not found:" not in handle, handle
+ return handle
+ except AssertionError:
+ main.log.exception( "" )
+ return None
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return None
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except NotImplementedError:
+ main.log.exception( self.name + ": Json output not supported")
+ return None
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def parseVplsShow( self ):
+ """
+ Parse the cli output of 'vpls show' into json output. This is required
+ as there is currently no json output available.
+ """
+ try:
+ output = []
+ raw = self.vplsShow( jsonFormat=False )
+ namePat = "VPLS name: (?P<name>\w+)"
+ interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
+ encapPat = "Encapsulation: (?P<encap>\w+)"
+ pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
+ mIter = re.finditer( pattern, raw )
+ for match in mIter:
+ item = {}
+ item[ 'name' ] = match.group( 'name' )
+ ifaces = match.group( 'interfaces' ).split( ', ')
+ if ifaces == [ "" ]:
+ ifaces = []
+ item[ 'interfaces' ] = ifaces
+ encap = match.group( 'encap' )
+ if encap != 'NONE':
+ item[ 'encapsulation' ] = encap.lower()
+ output.append( item )
+ return output
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsList( self, jsonFormat=True ):
+ """
+ Description: Returns result of onos:vpls list, which should list the
+ configured VPLS networks.
+ Optional:
+ * jsonFormat: enable json formatting of output
+ """
+ try:
+ cmdStr = "vpls list"
+ if jsonFormat:
+ raise NotImplementedError
+ cmdStr += " -j"
+ handle = self.sendline( cmdStr )
+ assert handle is not None, "Error in sendline"
+ assert "Command not found:" not in handle, handle
+ return handle
+ except AssertionError:
+ main.log.exception( "" )
+ return None
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return None
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except NotImplementedError:
+ main.log.exception( self.name + ": Json output not supported")
+ return None
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsCreate( self, network ):
+ """
+ CLI command to create a new VPLS network.
+ Required arguments:
+ network - String name of the network to create.
+ returns:
+ main.TRUE on success and main.FALSE on failure
+ """
+ try:
+ network = str( network )
+ cmdStr = "vpls create "
+ cmdStr += network
+ output = self.sendline( cmdStr )
+ assert output is not None, "Error in sendline"
+ assert "Command not found:" not in output, output
+ assert "Error executing command" not in output, output
+ assert "VPLS already exists:" not in output, output
+ return main.TRUE
+ except AssertionError:
+ main.log.exception( "" )
+ return main.FALSE
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsDelete( self, network ):
+ """
+ CLI command to delete a VPLS network.
+ Required arguments:
+ network - Name of the network to delete.
+ returns:
+ main.TRUE on success and main.FALSE on failure
+ """
+ try:
+ network = str( network )
+ cmdStr = "vpls delete "
+ cmdStr += network
+ output = self.sendline( cmdStr )
+ assert output is not None, "Error in sendline"
+ assert "Command not found:" not in output, output
+ assert "Error executing command" not in output, output
+ assert " not found" not in output, output
+ return main.TRUE
+ except AssertionError:
+ main.log.exception( "" )
+ return main.FALSE
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsAddIface( self, network, iface ):
+ """
+ CLI command to add an interface to a VPLS network.
+ Required arguments:
+ network - Name of the network to add the interface to.
+ iface - The ONOS name for an interface.
+ returns:
+ main.TRUE on success and main.FALSE on failure
+ """
+ try:
+ network = str( network )
+ iface = str( iface )
+ cmdStr = "vpls add-if "
+ cmdStr += network + " " + iface
+ output = self.sendline( cmdStr )
+ assert output is not None, "Error in sendline"
+ assert "Command not found:" not in output, output
+ assert "Error executing command" not in output, output
+ assert "already associated to network" not in output, output
+ assert "Interface cannot be added." not in output, output
+ return main.TRUE
+ except AssertionError:
+ main.log.exception( "" )
+ return main.FALSE
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsRemIface( self, network, iface ):
+ """
+ CLI command to remove an interface from a VPLS network.
+ Required arguments:
+ network - Name of the network to remove the interface from.
+ iface - Name of the interface to remove.
+ returns:
+ main.TRUE on success and main.FALSE on failure
+ """
+ try:
+ iface = str( iface )
+ cmdStr = "vpls rem-if "
+ cmdStr += network + " " + iface
+ output = self.sendline( cmdStr )
+ assert output is not None, "Error in sendline"
+ assert "Command not found:" not in output, output
+ assert "Error executing command" not in output, output
+ assert "is not configured" not in output, output
+ return main.TRUE
+ except AssertionError:
+ main.log.exception( "" )
+ return main.FALSE
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsClean( self ):
+ """
+ Description: Clears the VPLS app configuration.
+ Returns: main.TRUE on success and main.FALSE on failure
+ """
+ try:
+ cmdStr = "vpls clean"
+ handle = self.sendline( cmdStr )
+ assert handle is not None, "Error in sendline"
+ assert "Command not found:" not in handle, handle
+ return handle
+ except AssertionError:
+ main.log.exception( "" )
+ return main.FALSE
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def vplsSetEncap( self, network, encapType ):
+ """
+ CLI command to add an interface to a VPLS network.
+ Required arguments:
+ network - Name of the network to create.
+ encapType - Type of encapsulation.
+ returns:
+ main.TRUE on success and main.FALSE on failure
+ """
+ try:
+ network = str( network )
+ encapType = str( encapType ).upper()
+ assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
+ cmdStr = "vpls set-encap "
+ cmdStr += network + " " + encapType
+ output = self.sendline( cmdStr )
+ assert output is not None, "Error in sendline"
+ assert "Command not found:" not in output, output
+ assert "Error executing command" not in output, output
+ assert "already associated to network" not in output, output
+ assert "Encapsulation type " not in output, output
+ return main.TRUE
+ except AssertionError:
+ main.log.exception( "" )
+ return main.FALSE
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def interfaces( self, jsonFormat=True ):
+ """
+ Description: Returns result of interfaces command.
+ Optional:
+ * jsonFormat: enable json formatting of output
+ Returns:
+ The output of the command or None on error.
+ """
+ try:
+ cmdStr = "interfaces"
+ if jsonFormat:
+ #raise NotImplementedError
+ cmdStr += " -j"
+ handle = self.sendline( cmdStr )
+ assert handle is not None, "Error in sendline"
+ assert "Command not found:" not in handle, handle
+ return handle
+ except AssertionError:
+ main.log.exception( "" )
+ return None
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return None
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except NotImplementedError:
+ main.log.exception( self.name + ": Json output not supported")
+ return None
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 655f17e..4514047 100755
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -745,43 +745,43 @@
NOTE: Assumes cells are located at:
~/<self.home>/tools/test/cells/
"""
- # Variable initialization
- cellDirectory = self.home + "/tools/test/cells/"
- # We want to create the cell file in the dependencies directory
- # of TestON first, then copy over to ONOS bench
- tempDirectory = "/tmp/"
- # Create the cell file in the directory for writing ( w+ )
- cellFile = open( tempDirectory + fileName, 'w+' )
- if isinstance( onosIpAddrs, types.StringType ):
- onosIpAddrs = [ onosIpAddrs ]
-
- # App string is hardcoded environment variables
- # That you may wish to use by default on startup.
- # 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
- if useSSH:
- onosUseSSH = "export ONOS_USE_SSH=true"
- mnString = "export OCN="
- if mnIpAddrs == "":
- mnString = ""
- onosString = "export OC"
- tempCount = 1
-
- # Create ONOSNIC ip address prefix
- tempOnosIp = str( onosIpAddrs[ 0 ] )
- tempList = []
- tempList = tempOnosIp.split( "." )
- # Omit last element of list to format for NIC
- tempList = tempList[ :-1 ]
- # Structure the nic string ip
- nicAddr = ".".join( tempList ) + ".*"
- self.nicAddr = nicAddr
- onosNicString = "export ONOS_NIC=" + nicAddr
-
try:
+ # Variable initialization
+ cellDirectory = self.home + "/tools/test/cells/"
+ # We want to create the cell file in the dependencies directory
+ # of TestON first, then copy over to ONOS bench
+ tempDirectory = "/tmp/"
+ # Create the cell file in the directory for writing ( w+ )
+ cellFile = open( tempDirectory + fileName, 'w+' )
+ if isinstance( onosIpAddrs, types.StringType ):
+ onosIpAddrs = [ onosIpAddrs ]
+
+ # App string is hardcoded environment variables
+ # That you may wish to use by default on startup.
+ # 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
+ if useSSH:
+ onosUseSSH = "export ONOS_USE_SSH=true"
+ mnString = "export OCN="
+ if mnIpAddrs == "":
+ mnString = ""
+ onosString = "export OC"
+ tempCount = 1
+
+ # Create ONOSNIC ip address prefix
+ tempOnosIp = str( onosIpAddrs[ 0 ] )
+ tempList = []
+ tempList = tempOnosIp.split( "." )
+ # Omit last element of list to format for NIC
+ tempList = tempList[ :-1 ]
+ # Structure the nic string ip
+ nicAddr = ".".join( tempList ) + ".*"
+ self.nicAddr = nicAddr
+ onosNicString = "export ONOS_NIC=" + nicAddr
+
# Start writing to file
cellFile.write( onosNicString + "\n" )
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.params b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.params
new file mode 100755
index 0000000..9d9bab2
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.params
@@ -0,0 +1,32 @@
+<PARAMS>
+
+ <testcases>1,2,3</testcases>
+
+ <num_controllers>3</num_controllers>
+
+ <DEPENDENCY>
+ <wrapper1>startUp</wrapper1>
+ <topology>~/onos/tools/test/topos/vpls.json</topology>
+ </DEPENDENCY>
+
+ <ENV>
+ <cellName>vpls</cellName>
+ <cellApps>drivers,openflow,vpls</cellApps>
+ <cellUser>sdn</cellUser>
+ </ENV>
+
+ <CTRL>
+ <port>6653</port>
+ </CTRL>
+
+ <vpls>
+ <name>org.onosproject.vpls</name>
+ <hosts>6</hosts>
+ </vpls>
+
+ <SLEEP>
+ <startup>10</startup>
+ <netcfg>10</netcfg>
+ </SLEEP>
+
+</PARAMS>
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
new file mode 100755
index 0000000..b09007e
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
@@ -0,0 +1,370 @@
+# CASE1: Startup
+# CASE2: Load vpls topology and configurations from demo script
+# CASE3: Test CLI commands
+
+class VPLSBasic:
+ def __init__( self ):
+ self.default = ''
+
+ def CASE1( self, main ):
+ """
+ CASE1 is to compile ONOS and push it to the test machines
+
+ Startup sequence:
+ cell <name>
+ onos-verify-cell
+ NOTE: temporary - onos-remove-raft-logs
+ onos-uninstall
+ start mininet
+ git pull
+ mvn clean install
+ onos-package
+ onos-install -f
+ onos-wait-for-start
+ start cli sessions
+ start tcpdump
+ """
+ import imp
+ import time
+ import json
+ main.case( "Setting up test environment" )
+ main.caseExplanation = "Setup the test environment including " +\
+ "installing ONOS, starting Mininet and ONOS" +\
+ "cli sessions."
+
+ # load some variables from the params file
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+ main.numCtrls = int( main.params[ 'num_controllers' ] )
+
+ ofPort = main.params[ 'CTRL' ][ 'port' ]
+
+ main.CLIs = []
+ main.RESTs = []
+ main.nodes = []
+ ipList = []
+ for i in range( 1, main.numCtrls + 1 ):
+ try:
+ main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+ main.RESTs.append( getattr( main, 'ONOSrest' + str( i ) ) )
+ main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+ ipList.append( main.nodes[ -1 ].ip_address )
+ except AttributeError:
+ break
+
+ main.step( "Create cell file" )
+ cellAppString = main.params[ 'ENV' ][ 'cellApps' ]
+ main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
+ main.Mininet1.ip_address,
+ cellAppString, ipList )
+ main.step( "Applying cell variable to environment" )
+ cellResult = main.ONOSbench.setCell( cellName )
+ verifyResult = main.ONOSbench.verifyCell()
+
+ main.log.info( "Uninstalling ONOS" )
+ for node in main.nodes:
+ main.ONOSbench.onosUninstall( node.ip_address )
+
+ # Make sure ONOS is DEAD
+ main.log.info( "Killing any ONOS processes" )
+ killResults = main.TRUE
+ for node in main.nodes:
+ killed = main.ONOSbench.onosKill( node.ip_address )
+ killResults = killResults and killed
+
+ cleanInstallResult = main.TRUE
+
+ main.step( "Starting Mininet" )
+ # scp topo file to mininet
+ # TODO: move to params?
+ topoName = "vpls"
+ topoFile = "vpls.py"
+ filePath = main.ONOSbench.home + "/tools/test/topos/"
+ main.ONOSbench.scp( main.Mininet1,
+ filePath + topoFile,
+ main.Mininet1.home,
+ direction="to" )
+ topo = " --custom " + main.Mininet1.home + topoFile + " --topo " + topoName
+ args = " --switch ovs,protocols=OpenFlow13 --controller=remote"
+ for node in main.nodes:
+ args += ",ip=" + node.ip_address
+ mnCmd = "sudo mn" + topo + args
+ mnResult = main.Mininet1.startNet( mnCmd=mnCmd )
+ utilities.assert_equals( expect=main.TRUE, actual=mnResult,
+ onpass="Mininet Started",
+ onfail="Error starting Mininet" )
+
+ main.ONOSbench.getVersion( report=True )
+
+ main.step( "Creating ONOS package" )
+ packageResult = main.ONOSbench.buckBuild()
+ utilities.assert_equals( expect=main.TRUE, actual=packageResult,
+ onpass="ONOS package successful",
+ onfail="ONOS package failed" )
+
+ main.step( "Installing ONOS package" )
+ onosInstallResult = main.TRUE
+ for node in main.nodes:
+ tmpResult = main.ONOSbench.onosInstall( options="-f",
+ node=node.ip_address )
+ onosInstallResult = onosInstallResult and tmpResult
+ utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
+ onpass="ONOS install successful",
+ onfail="ONOS install failed" )
+
+ main.step( "Checking if ONOS is up yet" )
+ for i in range( 2 ):
+ onosIsupResult = main.TRUE
+ for node in main.nodes:
+ started = main.ONOSbench.isup( node.ip_address )
+ if not started:
+ main.log.error( node.name + " hasn't started" )
+ onosIsupResult = onosIsupResult and started
+ if onosIsupResult == main.TRUE:
+ break
+ utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
+ onpass="ONOS startup successful",
+ onfail="ONOS startup failed" )
+
+ main.step( "Set up ONOS secure SSH" )
+ secureSshResult = main.TRUE
+ for node in main.nodes:
+ secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
+ utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+
+ main.step( "Starting ONOS CLI sessions" )
+ cliResults = main.TRUE
+ threads = []
+ for i in range( main.numCtrls ):
+ t = main.Thread( target=main.CLIs[i].startOnosCli,
+ name="startOnosCli-" + str( i ),
+ args=[main.nodes[i].ip_address] )
+ threads.append( t )
+ t.start()
+
+ for t in threads:
+ t.join()
+ cliResults = cliResults and t.result
+ utilities.assert_equals( expect=main.TRUE, actual=cliResults,
+ onpass="ONOS cli startup successful",
+ onfail="ONOS cli startup failed" )
+
+ main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
+
+ main.step( "Activate apps defined in the params file" )
+ # get data from the params
+ apps = main.params.get( 'apps' )
+ if apps:
+ apps = apps.split(',')
+ main.log.warn( apps )
+ activateResult = True
+ for app in apps:
+ main.CLIs[ 0 ].app( app, "Activate" )
+ # TODO: check this worked
+ time.sleep( SLEEP ) # wait for apps to activate
+ for app in apps:
+ state = main.CLIs[ 0 ].appStatus( app )
+ if state == "ACTIVE":
+ activateResult = activeResult and True
+ else:
+ main.log.error( "{} is in {} state".format( app, state ) )
+ activeResult = False
+ utilities.assert_equals( expect=True,
+ actual=activateResult,
+ onpass="Successfully activated apps",
+ onfail="Failed to activate apps" )
+ else:
+ main.log.warn( "No apps were specified to be loaded after startup" )
+
+ main.step( "Set ONOS configurations" )
+ config = main.params.get( 'ONOS_Configuration' )
+ if config:
+ main.log.debug( config )
+ checkResult = main.TRUE
+ for component in config:
+ for setting in config[component]:
+ value = config[component][setting]
+ check = main.CLIs[ 0 ].setCfg( component, setting, value )
+ main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
+ checkResult = check and checkResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=checkResult,
+ onpass="Successfully set config",
+ onfail="Failed to set config" )
+ else:
+ main.log.warn( "No configurations were specified to be changed after startup" )
+
+ main.step( "App Ids check" )
+ appCheck = main.TRUE
+ threads = []
+ for i in main.activeNodes:
+ t = main.Thread( target=main.CLIs[i].appToIDCheck,
+ name="appToIDCheck-" + str( i ),
+ args=[] )
+ threads.append( t )
+ t.start()
+
+ for t in threads:
+ t.join()
+ appCheck = appCheck and t.result
+ if appCheck != main.TRUE:
+ main.log.warn( main.CLIs[0].apps() )
+ main.log.warn( main.CLIs[0].appIDs() )
+ utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+ onpass="App Ids seem to be correct",
+ onfail="Something is wrong with app Ids" )
+
+ def CASE2( self, main ):
+ """
+ Load and test vpls configurations from json configuration file
+ """
+ import os.path
+ from tests.USECASE.VPLS.dependencies import vpls
+
+ pprint = main.ONOSrest1.pprint
+ hosts = int( main.params['vpls']['hosts'] )
+ SLEEP = int( main.params['SLEEP']['netcfg'] )
+
+ main.step( "Discover hosts using pings" )
+ for i in range( 1, hosts + 1 ):
+ src = "h" + str( i )
+ for j in range( 1, hosts + 1 ):
+ if j == i:
+ continue
+ dst = "h" + str( j )
+ pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
+
+ main.step( "Load VPLS configurations" )
+ # TODO: load from params
+ fileName = main.params['DEPENDENCY']['topology']
+ app = main.params['vpls']['name']
+ # TODO make this a function?
+ main.ONOSbench.handle.sendline( "onos-netcfg $OC1 " + fileName )
+ # Time for netcfg to load data
+ time.sleep( SLEEP )
+ # 'Master' copy of test configuration
+ try:
+ with open( os.path.expanduser( fileName ) ) as dataFile:
+ originalCfg = json.load( dataFile )
+ main.vplsConfig = originalCfg['apps'].get( app ).get( 'vpls' ).get( 'vplsList')
+ except Exception as e:
+ main.log.error( "Error loading config file: {}".format( e ) )
+ if main.vplsConfig:
+ result = True
+ else:
+ result = False
+ utilities.assert_equals( expect=True,
+ actual=result,
+ onpass="Loaded vpls configuration",
+ onfail="Failed to load vpls configuration" )
+
+ main.step( "Check interface configurations" )
+ result = False
+ getPorts = main.ONOSrest1.getNetCfg( subjectClass="ports" )
+ onosCfg = pprint( getPorts )
+ sentCfg = pprint( originalCfg.get( "ports" ) )
+
+ if onosCfg == sentCfg:
+ main.log.info( "ONOS interfaces NetCfg matches what was sent" )
+ result = True
+ else:
+ main.log.error( "ONOS interfaces NetCfg doesn't match what was sent" )
+ main.log.debug( "ONOS config: {}".format( onosCfg ) )
+ main.log.debug( "Sent config: {}".format( sentCfg ) )
+ utilities.assert_equals( expect=True,
+ actual=result,
+ onpass="Net Cfg added for interfaces",
+ onfail="Net Cfg not added for interfaces" )
+
+ # Run a bunch of checks to verify functionality based on configs
+ vpls.verify( main )
+
+ def CASE3( self, main ):
+ """
+ Test VPLS cli commands
+ High level steps:
+ remove interface from a network
+ Clean configs
+ create vpls network
+ add interfaces to a network
+ add encap
+ change encap
+ remove encap
+ list?
+ """
+ from tests.USECASE.VPLS.dependencies import vpls
+ SLEEP = int( main.params['SLEEP']['netcfg'] )
+ pprint = main.ONOSrest1.pprint
+
+ main.step( "Remove an interface from a vpls network" )
+ main.CLIs[0].vplsRemIface( 'VPLS1', 'h1' )
+ time.sleep( SLEEP )
+ #update master config json
+ for network in main.vplsConfig:
+ if network.get( 'name' ) == 'VPLS1':
+ ifaces = network.get( 'interfaces' )
+ ifaces.remove('h1')
+ vpls.verify( main )
+
+ main.step( "Clean all vpls configurations" )
+ main.CLIs[0].vplsClean()
+ time.sleep( SLEEP )
+ main.vplsConfig = []
+ vpls.verify( main )
+
+ main.step( "Create a new vpls network" )
+ name = "Network1"
+ main.CLIs[0].vplsCreate( name )
+ time.sleep( SLEEP )
+ network1 = { 'name': name, 'interfaces': [], 'encapsulation': 'NONE' }
+ main.vplsConfig.append( network1 )
+ vpls.verify( main )
+
+ main.step( "Add interfaces to the network" )
+ main.CLIs[0].vplsAddIface( name, "h1" )
+ main.CLIs[0].vplsAddIface( name, "h5" )
+ main.CLIs[0].vplsAddIface( name, "h4" )
+ time.sleep( SLEEP )
+ for network in main.vplsConfig:
+ if network.get( 'name' ) == name:
+ ifaces = network.get( 'interfaces' )
+ ifaces.append( 'h1' )
+ ifaces.append( 'h4' )
+ ifaces.append( 'h5' )
+ network[ 'interfaces' ] = ifaces
+ vpls.verify( main )
+
+ main.step( "Add MPLS encapsulation to a vpls network" )
+ encapType = "MPLS"
+ main.CLIs[0].vplsSetEncap( name, encapType )
+ for network in main.vplsConfig:
+ if network.get( 'name' ) == name:
+ network['encapsulation'] = encapType
+ time.sleep( SLEEP )
+ vpls.verify( main )
+
+ main.step( "Change an encapsulation type" )
+ encapType = "VLAN"
+ main.CLIs[0].vplsSetEncap( name, encapType )
+ for network in main.vplsConfig:
+ if network.get( 'name' ) == name:
+ network['encapsulation'] = encapType
+ time.sleep( SLEEP )
+ vpls.verify( main )
+
+ main.step( "Remove encapsulation" )
+ encapType = "NONE"
+ main.CLIs[0].vplsSetEncap( name, encapType )
+ for network in main.vplsConfig:
+ if network.get( 'name' ) == name:
+ network['encapsulation'] = encapType
+ time.sleep( SLEEP )
+ vpls.verify( main )
+
+ main.step( "Clean all vpls configurations" )
+ main.CLIs[0].vplsClean()
+ time.sleep( SLEEP )
+ main.vplsConfig = []
+ vpls.verify( main )
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
new file mode 100755
index 0000000..e9a1f8e
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
@@ -0,0 +1,115 @@
+<TOPOLOGY>
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <nodes>1</nodes>
+ </COMPONENTS>
+ </ONOSbench>
+
+ <ONOScli1>
+ <host>localhost</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli1>
+
+ <ONOScli2>
+ <host>localhost</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli2>
+
+ <ONOScli3>
+ <host>localhost</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli3>
+
+ <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>
+
+ <ONOSrest1>
+ <host>OC1</host>
+ <port>8181</port>
+ <user>onos</user>
+ <password>rocks</password>
+ <type>OnosRestDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </ONOSrest1>
+
+ <ONOSrest2>
+ <host>OC2</host>
+ <port>8181</port>
+ <user>onos</user>
+ <password>rocks</password>
+ <type>OnosRestDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </ONOSrest2>
+
+ <ONOSrest3>
+ <host>OC3</host>
+ <port>8181</port>
+ <user>onos</user>
+ <password>rocks</password>
+ <type>OnosRestDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </ONOSrest3>
+
+
+ <Mininet1>
+ <host>OCN</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>MininetCliDriver</type>
+ <connect_order>7</connect_order>
+ <COMPONENTS>
+ <home>~/mininet/custom/</home>
+ </COMPONENTS>
+ </Mininet1>
+
+ </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/__init__.py b/TestON/tests/USECASE/VPLS/VPLSBasic/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/dependencies/__init__.py b/TestON/tests/USECASE/VPLS/VPLSBasic/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/dependencies/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/__init__.py b/TestON/tests/USECASE/VPLS/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/dependencies/__init__.py b/TestON/tests/USECASE/VPLS/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/dependencies/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/dependencies/vpls.py b/TestON/tests/USECASE/VPLS/dependencies/vpls.py
new file mode 100644
index 0000000..8dfdd46
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/dependencies/vpls.py
@@ -0,0 +1,144 @@
+"""
+Functions for the vpls tests
+"""
+import time
+import json
+
+def sanitizeConfig( config ):
+ """
+ Take a python json object for vpls config and normalize it.
+ Things it does:
+ Converts all strings to the same format
+ Make sure each network has an encapsulation key:value
+ Makes sure encapsulation type is all uppercase
+ Make sure an empty list of interfaces is formated consistently
+ Sorts the list of interfaces
+ """
+ # Convert to same string formats
+ config = json.loads( json.dumps( config ) )
+ for network in config:
+ encap = network.get( 'encapsulation', None )
+ if encap is None:
+ encap = "NONE"
+ network[ 'encapsulation' ] = encap.upper()
+ ifaces = network.get( 'interfaces' )
+ if ifaces == ['']:
+ ifaces = []
+ else:
+ ifaces = sorted( ifaces )
+ network['interfaces'] = ifaces
+ return config
+
+def verify( main ):
+ """
+ Runs some tests to verify the vpls configurations.
+ - Compare sent vpls network configuration to what is stored in each:
+ - ONOS network configuration
+ - ONOS VPLS application configuration
+ - Ping between each pair of hosts to check connectivity
+
+ NOTE: This requires the expected/sent network config json for the vpls
+ application be stored in main.vplsConfig
+ """
+ # Variables
+ app = main.params['vpls']['name']
+ pprint = main.ONOSrest1.pprint
+ SLEEP = int( main.params['SLEEP']['netcfg'] )
+
+ main.step( "Check network configurations for vpls application" )
+ clusterResult = True
+ for node in main.RESTs:
+ result = False
+ getVPLS = node.getNetCfg( subjectClass="apps",
+ subjectKey=app )
+ onosCfg = json.loads( getVPLS ).get( 'vpls' ).get( 'vplsList' )
+ onosCfg = pprint( sanitizeConfig( onosCfg ) )
+ sentCfg = pprint( sanitizeConfig( main.vplsConfig ) )
+ result = onosCfg == sentCfg
+ if result:
+ main.log.info( "ONOS NetCfg matches what was sent" )
+ else:
+ clusterResult = False
+ main.log.error( "ONOS NetCfg doesn't match what was sent" )
+ main.log.debug( "ONOS config: {}".format( onosCfg ) )
+ main.log.debug( "Sent config: {}".format( sentCfg ) )
+ utilities.assert_equals( expect=True,
+ actual=clusterResult,
+ onpass="Net Cfg added for vpls",
+ onfail="Net Cfg not added for vpls" )
+
+ main.step( "Check vpls app configurations" )
+ clusterResult = True
+ for node in main.CLIs:
+ result = False
+ #TODO Read from vpls show and match to pushed json
+ vpls = node.parseVplsShow()
+ parsedVpls = pprint( sanitizeConfig( vpls ) )
+ sentVpls = pprint( sanitizeConfig( main.vplsConfig ) )
+ result = parsedVpls == sentVpls
+ if result:
+ main.log.info( "VPLS config matches sent NetCfg" )
+ else:
+ clusterResult = False
+ main.log.error( "VPLS config doesn't match sent NetCfg" )
+ main.log.debug( "ONOS config: {}".format( parsedVpls ) )
+ main.log.debug( "Sent config: {}".format( sentVpls ) )
+ utilities.assert_equals( expect=True,
+ actual=clusterResult,
+ onpass="VPLS successfully configured",
+ onfail="VPLS not configured correctly" )
+
+ # FIXME This doesn't work, some will be withdrawn if interfaces are removed
+ # TODO: if encapsulation is set, look for that
+ # TODO: can we look at the intent keys?
+ """
+ main.step( "Check intent states" )
+ # Print the intent states
+ intents = main.CLIs[0].intents()
+ count = 0
+ while count <= 5:
+ installedCheck = True
+ try:
+ for intent in json.loads( intents ):
+ state = intent.get( 'state', None )
+ if "INSTALLED" not in state:
+ installedCheck = False
+ except ( ValueError, TypeError ):
+ main.log.exception( "Error parsing intents" )
+ if installedCheck:
+ break
+ count += 1
+ utilities.assert_equals( expect=True,
+ actual=installedCheck ,
+ onpass="All Intents in installed state",
+ onfail="Not all Intents in installed state" )
+ """
+
+ main.step( "Check connectivity" )
+ connectivityCheck = True
+ hosts = int( main.params['vpls']['hosts'] )
+ networks = []
+ for network in main.vplsConfig:
+ nodes = network.get( 'interfaces', None )
+ if nodes:
+ networks.append( nodes )
+ for i in range( 1, hosts + 1 ):
+ src = "h" + str( i )
+ for j in range( 1, hosts + 1 ):
+ if j == i:
+ continue
+ dst = "h" + str( j )
+ pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
+ expected = main.FALSE
+ for network in networks:
+ if src in network and dst in network:
+ expected = main.TRUE
+ break
+ if pingResult != expected:
+ connectivityCheck = False
+ main.log.error( "%s <-> %s: %s; Expected: %s" %
+ ( src, dst, pingResult, expected ) )
+ utilities.assert_equals( expect=True,
+ actual=connectivityCheck,
+ onpass="Connectivity is as expected",
+ onfail="Connectivity is not as expected" )