Added more functionality to flow test suite
- Added MPLS class
- Testing MPLS selector
- Testing TCP selector
- Testing UDP selector
- Checks flow tables in Mininet
Change-Id: Ibd624e7055fb0bcd736811cd2aff563f29fc2c38
diff --git a/TestON/tests/FUNCflow/FUNCflow.py b/TestON/tests/FUNCflow/FUNCflow.py
index 0fa77a2..929596c 100644
--- a/TestON/tests/FUNCflow/FUNCflow.py
+++ b/TestON/tests/FUNCflow/FUNCflow.py
@@ -39,11 +39,14 @@
main.startMNSleep = int( main.params[ 'SLEEP' ][ 'startMN' ] )
main.addFlowSleep = int( main.params[ 'SLEEP' ][ 'addFlow' ] )
main.delFlowSleep = int( main.params[ 'SLEEP' ][ 'delFlow' ] )
+ main.debug = main.params['DEBUG']
main.swDPID = main.params[ 'TEST' ][ 'swDPID' ]
main.cellData = {} # for creating cell file
main.CLIs = []
main.ONOSip = []
+ main.debug = True if "on" in main.debug else False
+
main.ONOSip = main.ONOSbench.getOnosIps()
# Assigning ONOS cli handles to a list
@@ -61,6 +64,7 @@
wrapperFile2 +
".py" )
+
copyResult = main.ONOSbench.scp( main.Mininet1,
main.dependencyPath+main.topology,
main.Mininet1.home+'/custom/',
@@ -398,7 +402,7 @@
ingressPort=ingress,
ethSrc=main.h1.hostMac,
ethDst=main.h2.hostMac,
- debug=True )
+ debug=main.debug )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
@@ -410,7 +414,6 @@
main.step( "Check flows are in the ADDED state" )
- #TODO: We should check mininet if flows are added as well
main.log.info( "Get the flows from ONOS" )
flows = json.loads( main.ONOSrest.flows() )
@@ -426,6 +429,22 @@
onpass="All flows are in the ADDED state",
onfail="All flows are NOT in the ADDED state" )
+ main.step( "Check flows are in Mininet's flow table" )
+
+ # get the flow IDs that were added through rest
+ main.log.info( "Getting the flow IDs from ONOS" )
+ flowIds = [ f.get("id") for f in flows if "rest" in f.get("appId") ]
+ # convert the flowIDs to ints then hex and finally back to strings
+ flowIds = [str(hex(int(x))) for x in flowIds]
+ main.log.info( "ONOS flow IDs: {}".format(flowIds) )
+
+ stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in mininet",
+ onfail="All flows are NOT in mininet" )
+
main.step( "Send a packet to verify the flows are correct" )
# Specify the src and dst MAC addr
@@ -435,7 +454,7 @@
# Filter for packets with the correct host name. Otherwise,
# the filter we catch any packet that is sent to host2
# NOTE: I believe it doesn't matter which host name it is,
- # as long as its host1 or host2
+ # as long as the src and dst are both specified
main.log.info( "Starting filter on host2" )
main.h2.startFilter( pktFilter="ether host %s" % main.h1.hostMac)
@@ -499,7 +518,7 @@
ethType=IPv4,
ipSrc=("IPV4_SRC", main.h1.hostIp+"/32"),
ipDst=("IPV4_DST", main.h2.hostIp+"/32"),
- debug=True )
+ debug=main.debug )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
@@ -526,6 +545,22 @@
onpass="All flows are in the ADDED state",
onfail="All flows are NOT in the ADDED state" )
+ main.step( "Check flows are in Mininet's flow table" )
+
+ # get the flow IDs that were added through rest
+ main.log.info( "Getting the flow IDs from ONOS" )
+ flowIds = [ f.get("id") for f in flows if "rest" in f.get("appId") ]
+ # convert the flowIDs to ints then hex and finally back to strings
+ flowIds = [str(hex(int(x))) for x in flowIds]
+ main.log.info( "ONOS flow IDs: {}".format(flowIds) )
+
+ stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in mininet",
+ onfail="All flows are NOT in mininet" )
+
main.step( "Send a packet to verify the flow is correct" )
main.log.info( "Constructing packet" )
@@ -598,7 +633,7 @@
ingressPort=ingress,
ethType=ethType,
vlan=vlan,
- debug=True )
+ debug=main.debug )
utilities.assert_equals( expect=main.TRUE,
@@ -626,6 +661,22 @@
onpass="All flows are in the ADDED state",
onfail="All flows are NOT in the ADDED state" )
+ main.step( "Check flows are in Mininet's flow table" )
+
+ # get the flow IDs that were added through rest
+ main.log.info( "Getting the flow IDs from ONOS" )
+ flowIds = [ f.get("id") for f in flows if "rest" in f.get("appId") ]
+ # convert the flowIDs to ints then hex and finally back to strings
+ flowIds = [str(hex(int(x))) for x in flowIds]
+ main.log.info( "ONOS flow IDs: {}".format(flowIds) )
+
+ stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in mininet",
+ onfail="All flows are NOT in mininet" )
+
main.step( "Send a packet to verify the flow are correct" )
# The receiving interface
@@ -636,10 +687,10 @@
# Broadcast the packet on the vlan interface. We only care if the flow forwards
# the packet with the correct vlan tag, not if the mac addr is correct
- BROADCAST = "FF:FF:FF:FF:FF:FF"
sendIface = "{}-eth0.{}".format(main.h3.name, vlan)
main.log.info( "Broadcasting the packet with a vlan tag" )
- main.h3.sendPacket( iface=sendIface, packet="Ether(dst='{}')/Dot1Q(vlan={})".format(BROADCAST, vlan))
+ main.h3.sendPacket( iface=sendIface,
+ packet="Ether()/Dot1Q(vlan={})".format(vlan) )
main.log.info( "Checking filter for our packet" )
stepResult = main.h4.checkFilter()
@@ -658,6 +709,369 @@
onpass="Successfully sent a packet",
onfail="Failed to send a packet" )
+ def CASE1300( self, main ):
+ '''
+ Add flows with MPLS selector and verify the flows
+ '''
+ import json
+ import time
+
+ main.case( "Verify the MPLS selector is correctly compiled on the flow." )
+ main.caseExplanation = "Install one flow with an MPLS selector, " +\
+ "verify the flow is added in ONOS, and finally "+\
+ "send a packet via scapy that has a MPLS label."
+
+ main.step( "Add a flow with a MPLS selector" )
+
+ main.log.info( "Creating host components" )
+ main.Mininet1.createHostComponent( "h1" )
+ main.Mininet1.createHostComponent( "h2" )
+ hosts = [main.h1, main.h2]
+ stepResult = main.TRUE
+ for host in hosts:
+ host.startHostCli()
+ host.startScapy( main.dependencyPath )
+ host.updateSelf()
+
+ # ports
+ egress = 2
+ ingress = 1
+ # MPLS etherType
+ ethType = main.params[ 'TEST' ][ 'mplsType' ]
+ # MPLS label
+ mplsLabel = main.params[ 'TEST' ][ 'mpls' ]
+
+ # Add a flow that connects host1 on port1 to host2 on port2
+ main.log.info( "Adding flow with MPLS selector" )
+ stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+ egressPort=egress,
+ ingressPort=ingress,
+ ethType=ethType,
+ mpls=mplsLabel,
+ debug=main.debug )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully added flow",
+ onfail="Failed add flow" )
+
+ # Giving ONOS time to add the flow
+ time.sleep( main.addFlowSleep )
+
+ main.step( "Check flow is in the ADDED state" )
+
+ main.log.info( "Get the flows from ONOS" )
+ flows = json.loads( main.ONOSrest.flows() )
+
+ stepResult = main.TRUE
+ for f in flows:
+ if "rest" in f.get("appId"):
+ if "ADDED" not in f.get("state"):
+ stepResult = main.FALSE
+ main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in the ADDED state",
+ onfail="All flows are NOT in the ADDED state" )
+
+ main.step( "Check flows are in Mininet's flow table" )
+
+ # get the flow IDs that were added through rest
+ main.log.info( "Getting the flow IDs from ONOS" )
+ flowIds = [ f.get("id") for f in flows if "rest" in f.get("appId") ]
+ # convert the flowIDs to ints then hex and finally back to strings
+ flowIds = [str(hex(int(x))) for x in flowIds]
+ main.log.info( "ONOS flow IDs: {}".format(flowIds) )
+
+ stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=True )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in mininet",
+ onfail="All flows are NOT in mininet" )
+
+ main.step( "Send a packet to verify the flow is correct" )
+
+ main.log.info( "Starting filter on host2" )
+ main.h2.startFilter( pktFilter="mpls" )
+
+ main.log.info( "Constructing packet" )
+ main.log.info( "Sending packet to host2" )
+ main.h1.sendPacket( packet='Ether()/MPLS(label={})'.format(mplsLabel) )
+
+ main.log.info( "Checking filter for our packet" )
+ stepResult = main.h2.checkFilter()
+ if stepResult:
+ main.log.info( "Packet: %s" % main.h2.readPackets() )
+ else: main.h2.killFilter()
+
+ main.log.info( "Clean up host components" )
+ for host in hosts:
+ host.stopScapy()
+ main.Mininet1.removeHostComponent("h1")
+ main.Mininet1.removeHostComponent("h2")
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully sent a packet",
+ onfail="Failed to send a packet" )
+
+ def CASE1400( self, main ):
+ '''
+ Add flows with a TCP selector and verify the flow
+ '''
+ import json
+ import time
+
+ main.case( "Verify the TCP selector is correctly compiled on the flow" )
+ main.caseExplanation = "Install a flow with only the TCP selector " +\
+ "specified, verify the flow is added in ONOS, and finally "+\
+ "send a TCP packet to verify the TCP selector is compiled correctly."
+
+ main.step( "Add a flow with a TCP selector" )
+
+ main.log.info( "Creating host components" )
+ main.Mininet1.createHostComponent( "h1" )
+ main.Mininet1.createHostComponent( "h2" )
+ hosts = [main.h1, main.h2]
+ stepResult = main.TRUE
+ for host in hosts:
+ host.startHostCli()
+ host.startScapy()
+ host.updateSelf()
+
+ # Add a flow that connects host1 on port1 to host2 on port2
+ egress = 2
+ ingress = 1
+ # IPv4 etherType
+ ethType = main.params[ 'TEST' ][ 'ip4Type' ]
+ # IP protocol
+ ipProto = main.params[ 'TEST' ][ 'tcpProto' ]
+ # TCP port destination
+ tcpDst = main.params[ 'TEST' ][ 'tcpDst' ]
+
+ main.log.info( "Add a flow that connects host1 on port1 to host2 on port2" )
+ stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+ egressPort=egress,
+ ingressPort=ingress,
+ ethType=ethType,
+ ipProto=ipProto,
+ tcpDst=tcpDst,
+ debug=main.debug )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully added flows",
+ onfail="Failed add flows" )
+
+ # Giving ONOS time to add the flow
+ time.sleep( main.addFlowSleep )
+
+ main.step( "Check flow is in the ADDED state" )
+
+ main.log.info( "Get the flows from ONOS" )
+ flows = json.loads( main.ONOSrest.flows() )
+
+ stepResult = main.TRUE
+ for f in flows:
+ if "rest" in f.get("appId"):
+ if "ADDED" not in f.get("state"):
+ stepResult = main.FALSE
+ main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in the ADDED state",
+ onfail="All flows are NOT in the ADDED state" )
+
+ main.step( "Check flows are in Mininet's flow table" )
+
+ # get the flow IDs that were added through rest
+ main.log.info( "Getting the flow IDs from ONOS" )
+ flowIds = [ f.get("id") for f in flows if "rest" in f.get("appId") ]
+ # convert the flowIDs to ints then hex and finally back to strings
+ flowIds = [str(hex(int(x))) for x in flowIds]
+ main.log.info( "ONOS flow IDs: {}".format(flowIds) )
+
+ stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in mininet",
+ onfail="All flows are NOT in mininet" )
+
+ main.step( "Send a packet to verify the flow is correct" )
+
+ main.log.info( "Constructing packet" )
+ # No need for the MAC src dst
+ main.h1.buildEther( dst=main.h2.hostMac )
+ main.h1.buildIP( dst=main.h2.hostIp )
+ main.h1.buildTCP( dport=tcpDst )
+
+ main.log.info( "Starting filter on host2" )
+ # Defaults to ip
+ main.h2.startFilter( pktFilter="tcp" )
+
+ main.log.info( "Sending packet to host2" )
+ main.h1.sendPacket()
+
+ main.log.info( "Checking filter for our packet" )
+ stepResult = main.h2.checkFilter()
+ if stepResult:
+ main.log.info( "Packet: %s" % main.h2.readPackets() )
+ else: main.h2.killFilter()
+
+ main.log.info( "Clean up host components" )
+ for host in hosts:
+ host.stopScapy()
+ main.Mininet1.removeHostComponent("h1")
+ main.Mininet1.removeHostComponent("h2")
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully sent a packet",
+ onfail="Failed to send a packet" )
+
+ def CASE1500( self, main ):
+ '''
+ Add flows with a UDP selector and verify the flow
+ '''
+ import json
+ import time
+
+ main.case( "Verify the UDP selector is correctly compiled on the flow" )
+ main.caseExplanation = "Install a flow with only the UDP selector " +\
+ "specified, verify the flow is added in ONOS, and finally "+\
+ "send a UDP packet to verify the UDP selector is compiled correctly."
+
+ main.step( "Add a flow with a UDP selector" )
+
+ main.log.info( "Creating host components" )
+ main.Mininet1.createHostComponent( "h1" )
+ main.Mininet1.createHostComponent( "h2" )
+ hosts = [main.h1, main.h2]
+ stepResult = main.TRUE
+ for host in hosts:
+ host.startHostCli()
+ host.startScapy()
+ host.updateSelf()
+
+ # Add a flow that connects host1 on port1 to host2 on port2
+ egress = 2
+ ingress = 1
+ # IPv4 etherType
+ ethType = main.params[ 'TEST' ][ 'ip4Type' ]
+ # IP protocol
+ ipProto = main.params[ 'TEST' ][ 'udpProto' ]
+ # UDP port destination
+ udpDst = main.params[ 'TEST' ][ 'udpDst' ]
+
+ main.log.info( "Add a flow that connects host1 on port1 to host2 on port2" )
+ stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+ egressPort=egress,
+ ingressPort=ingress,
+ ethType=ethType,
+ ipProto=ipProto,
+ udpDst=udpDst,
+ debug=main.debug )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully added flows",
+ onfail="Failed add flows" )
+
+ # Giving ONOS time to add the flow
+ time.sleep( main.addFlowSleep )
+
+ main.step( "Check flow is in the ADDED state" )
+
+ main.log.info( "Get the flows from ONOS" )
+ flows = json.loads( main.ONOSrest.flows() )
+
+ stepResult = main.TRUE
+ for f in flows:
+ if "rest" in f.get("appId"):
+ if "ADDED" not in f.get("state"):
+ stepResult = main.FALSE
+ main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in the ADDED state",
+ onfail="All flows are NOT in the ADDED state" )
+
+ main.step( "Check flows are in Mininet's flow table" )
+
+ # get the flow IDs that were added through rest
+ main.log.info( "Getting the flow IDs from ONOS" )
+ flowIds = [ f.get("id") for f in flows if "rest" in f.get("appId") ]
+ # convert the flowIDs to ints then hex and finally back to strings
+ flowIds = [str(hex(int(x))) for x in flowIds]
+ main.log.info( "ONOS flow IDs: {}".format(flowIds) )
+
+ stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in mininet",
+ onfail="All flows are NOT in mininet" )
+
+ main.step( "Send a packet to verify the flow is correct" )
+
+ main.log.info( "Constructing packet" )
+ # No need for the MAC src dst
+ main.h1.buildEther( dst=main.h2.hostMac )
+ main.h1.buildIP( dst=main.h2.hostIp )
+ main.h1.buildUDP( dport=udpDst )
+
+ main.log.info( "Starting filter on host2" )
+ # Defaults to ip
+ main.h2.startFilter( pktFilter="udp" )
+
+ main.log.info( "Sending packet to host2" )
+ main.h1.sendPacket()
+
+ main.log.info( "Checking filter for our packet" )
+ stepResult = main.h2.checkFilter()
+ if stepResult:
+ main.log.info( "Packet: %s" % main.h2.readPackets() )
+ else: main.h2.killFilter()
+
+ main.log.info( "Clean up host components" )
+ for host in hosts:
+ host.stopScapy()
+ main.Mininet1.removeHostComponent("h1")
+ main.Mininet1.removeHostComponent("h2")
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully sent a packet",
+ onfail="Failed to send a packet" )
+
+
+ def CASE2000( self, main ):
+ import json
+
+ main.case( "Delete flows that were added through rest" )
+ main.step("Deleting flows")
+
+ main.log.info( "Getting flows" )
+ flows = json.loads( main.ONOSrest.flows() )
+
+ stepResult = main.TRUE
+ for f in flows:
+ if "rest" in f.get("appId"):
+ if main.debug: main.log.debug( "Flow to be deleted:\n{}".format( main.ONOSrest.pprint(f) ) )
+ stepResult = stepResult and main.ONOSrest.removeFlow( f.get("deviceId"), f.get("id") )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully deleting flows",
+ onfail="Failed to delete flows" )
+
+ time.sleep( main.delFlowSleep )
+
def CASE100( self, main ):
'''
Report errors/warnings/exceptions
@@ -671,4 +1085,3 @@
"ERROR",
"Except" ],
"s" )
-