CSIT-576 HC Test: Improve SPAN test coverage 54/6654/4
authorselias <samelias@cisco.com>
Thu, 11 May 2017 16:02:03 +0000 (18:02 +0200)
committerselias <samelias@cisco.com>
Wed, 17 May 2017 09:26:08 +0000 (11:26 +0200)
 - add test for multiple destination interfaces using one source interface
 - duplicate all existing cases using a sub-interface as the destination

Change-Id: Ifabf78bca258247a19624b2b2a0474d21d1229d3
Signed-off-by: selias <samelias@cisco.com>
resources/libraries/python/honeycomb/HcAPIKwInterfaces.py
resources/libraries/robot/honeycomb/port_mirroring.robot
resources/test_data/honeycomb/span.py [moved from resources/test_data/honeycomb/spanrx-apihc-apivat.py with 78% similarity]
tests/func/honeycomb/__init__.robot
tests/func/honeycomb/mgmt-cfg-spanrx-apihc-apivat-func.robot

index dc24858..e78696c 100644 (file)
@@ -1162,6 +1162,9 @@ class InterfaceKeywords(object):
         :rtype: bytearray
         """
 
         :rtype: bytearray
         """
 
+        super_interface = Topology.convert_interface_reference(
+            node, super_interface, "name")
+
         intf_state = {"up": "true",
                       "down": "false"}
 
         intf_state = {"up": "true",
                       "down": "false"}
 
@@ -1706,7 +1709,7 @@ class InterfaceKeywords(object):
         :param dst_interface: Interface to mirror packets to.
         :param src_interfaces: List of interfaces to mirror packets from.
         :type node: dict
         :param dst_interface: Interface to mirror packets to.
         :param src_interfaces: List of interfaces to mirror packets from.
         :type node: dict
-        :type dst_interface: str
+        :type dst_interface: str or int
         :type src_interfaces: list of dict
         :returns: Content of response.
         :rtype: bytearray
         :type src_interfaces: list of dict
         :returns: Content of response.
         :rtype: bytearray
@@ -1741,6 +1744,58 @@ class InterfaceKeywords(object):
             raise HoneycombError(
                 "Configuring SPAN failed. Status code:{0}".format(status_code))
 
             raise HoneycombError(
                 "Configuring SPAN failed. Status code:{0}".format(status_code))
 
+    @staticmethod
+    def configure_sub_interface_span(node, super_interface, dst_interface_index,
+                                     src_interfaces=None):
+        """Configure SPAN port mirroring on the specified sub-interface. If no
+         source interface is provided, SPAN will be disabled.
+
+        Note: Does not support source sub-interfaces, only destination.
+
+        :param node: Honeycomb node.
+        :param super_interface: Name, link name or sw_if_index
+        of the destination interface's super-interface.
+        :param dst_interface_index: Index of sub-interface to mirror packets to.
+        :param src_interfaces: List of interfaces to mirror packets from.
+        :type node: dict
+        :type super_interface: str or int
+        :type dst_interface_index: int
+        :type src_interfaces: list of dict
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If SPAN could not be configured.
+        """
+
+        super_interface = Topology.convert_interface_reference(
+            node, super_interface, "name")
+        super_interface = super_interface.replace("/", "%2F")
+
+        path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
+            .format(super_interface, dst_interface_index)
+
+        if not src_interfaces:
+            status_code, _ = HcUtil.delete_honeycomb_data(
+                node, "config_vpp_interfaces", path)
+        else:
+            for src_interface in src_interfaces:
+                src_interface["iface-ref"] = Topology. \
+                    convert_interface_reference(
+                    node, src_interface["iface-ref"], "name")
+            data = {
+                "span": {
+                    "mirrored-interfaces": {
+                        "mirrored-interface": src_interfaces
+                    }
+                }
+            }
+
+            status_code, _ = HcUtil.put_honeycomb_data(
+                node, "config_vpp_interfaces", data, path)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "Configuring SPAN failed. Status code:{0}".format(status_code))
+
     @staticmethod
     def add_interface_local0_to_topology(node):
         """Use Topology methods to add interface "local0" to working topology,
     @staticmethod
     def add_interface_local0_to_topology(node):
         """Use Topology methods to add interface "local0" to working topology,
index ef41c51..532b515 100644 (file)
 | | Lists should be equal | ${data} | ${src_interfaces}
 
 | Honeycomb removes interface SPAN configuration
 | | Lists should be equal | ${data} | ${src_interfaces}
 
 | Honeycomb removes interface SPAN configuration
-| | [Documentation] | Uses Honeycomb API to remove SPAN confirugation\
+| | [Documentation] | Uses Honeycomb API to remove SPAN configuration\
 | | ... | from the specified interface.
 | | ...
 | | ... | *Arguments:*
 | | ... | from the specified interface.
 | | ...
 | | ... | *Arguments:*
 | | [Arguments] | ${node} | ${dst_interface}
 | | InterfaceAPI.Configure interface SPAN | ${node} | ${dst_interface}
 
 | | [Arguments] | ${node} | ${dst_interface}
 | | InterfaceAPI.Configure interface SPAN | ${node} | ${dst_interface}
 
-| Interface SPAN configuration from Honeycomb should not exist
+| Interface SPAN Operational Data from Honeycomb should not exist
 | | [Documentation] | Retrieves interface operational data and verifies that\
 | | ... | SPAN mirroring is not configured.
 | | ...
 | | [Documentation] | Retrieves interface operational data and verifies that\
 | | ... | SPAN mirroring is not configured.
 | | ...
 | | Run keyword and expect error | *KeyError* | Set Variable
 | | ... | ${data['span']['mirrored-interfaces']['mirrored-interface']}
 
 | | Run keyword and expect error | *KeyError* | Set Variable
 | | ... | ${data['span']['mirrored-interfaces']['mirrored-interface']}
 
-| SPAN configuration from VAT should not exist
-| | [Documentation] | Attmepts to retrieve SPAN configuration from VAT dump,\
+| SPAN Operational Data from VAT should not exist
+| | [Documentation] | Attmepts to retrieve SPAN Operational Data from VAT dump,\
 | | ... | and expects to fail with no data retrieved.
 | | ...
 | | ... | *Arguments:*
 | | ... | and expects to fail with no data retrieved.
 | | ...
 | | ... | *Arguments:*
 | | ...
 | | ... | *Example:*
 | | ...
 | | ...
 | | ... | *Example:*
 | | ...
-| | ... | \| SPAN configuration from VAT should not exist \| ${nodes['DUT1']} \|
+| | ... | \| SPAN Operational Data from VAT should not exist \| ${nodes['DUT1']} \|
 | | [Arguments] | ${node}
 | | Run keyword and expect error | ValueError: No JSON object could be decoded
 | | ... | VPP get SPAN configuration by interface | ${node} | local0
 | | [Arguments] | ${node}
 | | Run keyword and expect error | ValueError: No JSON object could be decoded
 | | ... | VPP get SPAN configuration by interface | ${node} | local0
+
+| Honeycomb Configures SPAN on sub-interface
+| | [Documentation] | Uses Honeycomb API to configure SPAN on the specified\
+| | ... | sub-interface, mirroring one or more interfaces.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - dst_interface - Mirroring destination super-interface. Type: string
+| | ... | - index - Index of mirroring destination sub-interface. Type: integer
+| | ... | - src_interfaces - Mirroring source interfaces. Type: list \
+| | ... | of dictionaries
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb Configures SPAN on sub-interface \| ${nodes['DUT1']} \
+| | ... | \| GigabitEthernet0/8/0 \| ${1} \
+| | ... | \|[{'iface-ref': 'GigabitEthernet0/10/0', 'state': 'transmit'}, \
+| | ... | \| {'iface-ref': 'local0', 'state': 'both'}] \|
+| | ...
+| | [Arguments] | ${node} | ${dst_interface} | ${index} | @{src_interfaces}
+| | InterfaceAPI.Configure sub interface SPAN
+| | ... | ${node} | ${dst_interface} | ${index} | ${src_interfaces}
+
+| Sub-Interface SPAN Operational Data from Honeycomb should be
+| | [Documentation] | Retrieves sub-interface operational data and verifies\
+| | ... | that SPAN mirroring is configured with the provided interfaces.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - dst_interface - Mirroring destination super-interface. Type: string
+| | ... | - index - Index of mirroring destination sub-interface. Type: integer
+| | ... | - src_interfaces - Mirroring source interfaces. Type: Argument list -\
+| | ... | any number of strings
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Sub-Interface SPAN Operational Data from Honeycomb should be \
+| | ... | \| ${nodes['DUT1']} \| GigabitEthernet0/8/0 \| ${1} \
+| | ... | \| GigabitEthernet0/9/0 \|
+| | ...
+| | [Arguments] | ${node} | ${dst_interface} | ${index} | @{src_interfaces}
+| | ${data}= | InterfaceAPI.Get sub interface oper data
+| | ... | ${node} | ${dst_interface} | ${index}
+| | ${data}= | Set Variable
+| | ... | ${data['subinterface-span:span-state']['mirrored-interfaces']['mirrored-interface']}
+| | Sort list | ${data}
+| | Sort list | ${src_interfaces}
+| | Lists should be equal | ${data} | ${src_interfaces}
+
+| Sub-Interface SPAN Operational Data from Honeycomb should be empty
+| | [Documentation] | Checks whether SPAN Operational Data from Honeycomb is empty.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - Information about a DUT node. Type: dictionary
+| | ... | - dst_interface - Mirroring destination super-interface. Type: string
+| | ... | - index - Index of mirroring destination sub-interface. Type: integer
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Interface SPAN Operational Data from Honeycomb should be empty \
+| | ... | \| ${node} \| GigabitEthernetO/8/0 \| ${1} \|
+| | ...
+| | [Arguments] | ${node} | ${dst_interface} | ${index}
+| | ${data}= | Get sub interface oper data
+| | ... | ${node} | ${dst_interface} | ${index}
+| | Variable should not exist
+| | ... | ${data['subinterface-span:span-state']['mirrored-interfaces']['mirrored-interface']}
+
+| Honeycomb removes sub-interface SPAN configuration
+| | [Documentation] | Uses Honeycomb API to remove SPAN Operational Data\
+| | ... | from the specified sub-interface.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - dst_interface - Mirroring destination super-interface. Type: string
+| | ... | - index - Index of mirroring destination sub-interface. Type: integer
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb removes sub-interface SPAN configuration \
+| | ... | \| ${nodes['DUT1']} \| GigabitEthernet0/8/0 \| ${1} \|
+| | ...
+| | [Arguments] | ${node} | ${dst_interface} | ${index}
+| | InterfaceAPI.Configure sub interface SPAN
+| | ... | ${node} | ${dst_interface} | ${index}
+
+| Sub-Interface SPAN Operational Data from Honeycomb should not exist
+| | [Documentation] | Retrieves sub-interface operational data and verifies
+| | ... | that SPAN mirroring is not configured.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - dst_interface - Mirroring destination super-interface. Type: string
+| | ... | - index - Index of mirroring destination sub-interface. Type: integer
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Sub-Interface SPAN Operational Data from Honeycomb should not exist \
+| | ... | \| ${nodes['DUT1']} \| GigabitEthernet0/8/0 \| ${1} \|
+| | ....
+| | [Arguments] | ${node} | ${dst_interface} | ${index}
+| | ${data}= | InterfaceAPI.Get sub interface oper data
+| | ... | ${node} | ${dst_interface} | ${index}
+| | Run keyword and expect error | *KeyError* | Set Variable
+| | ... | ${data['subinterface-span:span-state']['mirrored-interfaces']['mirrored-interface']}
\ No newline at end of file
similarity index 78%
rename from resources/test_data/honeycomb/spanrx-apihc-apivat.py
rename to resources/test_data/honeycomb/span.py
index 3f6a1e6..9e1004d 100644 (file)
 """Test variables for SPAN port mirroring test suite."""
 
 
 """Test variables for SPAN port mirroring test suite."""
 
 
-def get_variables(node,
-                  interface1,
-                  interface2,
-                  interface3
-                 ):
+def get_variables(interface1, interface2, interface3):
     """Create and return a dictionary of test variables.
 
     """Create and return a dictionary of test variables.
 
-    :param node: Honeycomb node.
     :param interface1: Name of an interface.
     :param interface2: Name of an interface.
     :param interface3: Name of an interface.
     :param interface1: Name of an interface.
     :param interface2: Name of an interface.
     :param interface3: Name of an interface.
-    :type node: dict
     :type interface1: string
     :type interface2: string
     :type interface3: string
     :type interface1: string
     :type interface2: string
     :type interface3: string
@@ -38,28 +32,36 @@ def get_variables(node,
         "interface1": interface1,
         "interface2": interface2,
         "interface3": interface3,
         "interface1": interface1,
         "interface2": interface2,
         "interface3": interface3,
-        "settings_1": {
+
+        # Interface 2 - ingress
+        "settings_receive": {
             "state": "receive",
             "iface-ref": interface2,
         },
 
             "state": "receive",
             "iface-ref": interface2,
         },
 
-        "settings_2": {
+        # Interface 2 - egress
+        "settings_transmit": {
             "state": "transmit",
             "iface-ref": interface2,
         },
 
             "state": "transmit",
             "iface-ref": interface2,
         },
 
-        "settings_3": {
+        # Interface 2 - ingress/egress
+        "settings_both": {
             "state": "both",
             "iface-ref": interface2,
         },
 
             "state": "both",
             "iface-ref": interface2,
         },
 
-        "settings_4": {
+        # Interface 3 - ingress/egress
+        "settings_if2": {
             "state": "both",
             "iface-ref": interface3,
         },
 
             "state": "both",
             "iface-ref": interface3,
         },
 
+        # IP addresses for traffic test
         "tg_to_dut_if1_ip": "192.168.1.1",
         "dut_to_tg_if1_ip": "192.168.1.2",
         "tg_to_dut_if1_ip": "192.168.1.1",
         "dut_to_tg_if1_ip": "192.168.1.2",
+        "tg_to_dut_if2_ip": "192.168.2.1",
+        "dut_to_tg_if2_ip": "192.168.2.2",
         "prefix": 24,
     }
     return variables
         "prefix": 24,
     }
     return variables
index 7e9d07a..e247180 100644 (file)
@@ -40,7 +40,7 @@
 | Configure ODL Client for testing
 | | [Arguments] | ${node}
 | | ${use_odl_client}= | Get Variable Value | ${HC_ODL}
 | Configure ODL Client for testing
 | | [Arguments] | ${node}
 | | ${use_odl_client}= | Get Variable Value | ${HC_ODL}
-| | Run Keyword If | '${use_odl_client}' != ${NONE}
+| | Run Keyword If | '${use_odl_client}' != '${NONE}'
 | | ... | Run Keywords
 | | ... | Set Global Variable | ${use_odl_client} | AND
 | | ... | Setup ODL Client Service On DUT | ${node} | ${use_odl_client}
 | | ... | Run Keywords
 | | ... | Set Global Variable | ${use_odl_client} | AND
 | | ... | Setup ODL Client Service On DUT | ${node} | ${use_odl_client}
index 74c56eb..1cc385c 100644 (file)
 | Resource | resources/libraries/robot/honeycomb/port_mirroring.robot
 | Resource | resources/libraries/robot/honeycomb/interfaces.robot
 | Resource | resources/libraries/robot/honeycomb/honeycomb.robot
 | Resource | resources/libraries/robot/honeycomb/port_mirroring.robot
 | Resource | resources/libraries/robot/honeycomb/interfaces.robot
 | Resource | resources/libraries/robot/honeycomb/honeycomb.robot
+| Resource | resources/libraries/robot/honeycomb/sub_interface.robot
 | Resource | resources/libraries/robot/testing_path.robot
 | Resource | resources/libraries/robot/telemetry/span.robot
 | Resource | resources/libraries/robot/testing_path.robot
 | Resource | resources/libraries/robot/telemetry/span.robot
-| Variables | resources/test_data/honeycomb/spanrx-apihc-apivat.py
-| ... | ${node} | ${node['interfaces']['port1']['name']}
-| ... | ${node['interfaces']['port3']['name']} | local0
+| Variables | resources/test_data/honeycomb/span.py
+| ... | ${node['interfaces']['port1']['name']}
+| ... | ${node['interfaces']['port3']['name']}
+| ... | local0
+| Variables | resources/test_data/honeycomb/sub_interfaces.py
 | Force Tags | HC_FUNC
 | Suite Setup | Add Interface local0 To Topology | ${node}
 | Suite Teardown | Restart Honeycomb and VPP | ${node}
 | Documentation | *Honeycomb port mirroring test suite.*
 
 *** Test Cases ***
 | Force Tags | HC_FUNC
 | Suite Setup | Add Interface local0 To Topology | ${node}
 | Suite Teardown | Restart Honeycomb and VPP | ${node}
 | Documentation | *Honeycomb port mirroring test suite.*
 
 *** Test Cases ***
-| TC01: Honeycomb can configure SPAN on an interface receive
+| TC01: Honeycomb can configure SPAN on an interface receive
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state receive.
 | | ...
 | | When Honeycomb Configures SPAN on interface
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state receive.
 | | ...
 | | When Honeycomb Configures SPAN on interface
-| | ... | ${node} | ${interface1} | ${settings_1}
-| | Then Interface SPAN Operational Data From Honeycomb Should Be
-| | ... | ${node} | ${interface1} | ${settings_1}
+| | ... | ${node} | ${interface1} | ${settings_receive}
+| | Then Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${settings_receive}
 
 
-| TC02: Honeycomb can configure SPAN on an interface transmit
+| TC02: Honeycomb can configure SPAN on an interface transmit
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state transmit.
 | | ...
 | | When Honeycomb Configures SPAN on interface
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state transmit.
 | | ...
 | | When Honeycomb Configures SPAN on interface
-| | ... | ${node} | ${interface1} | ${settings_2}
-| | Then Interface SPAN Operational Data From Honeycomb Should Be
-| | ... | ${node} | ${interface1} | ${settings_2}
+| | ... | ${node} | ${interface1} | ${settings_transmit}
+| | Then Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${settings_transmit}
 
 
-| TC03: Honeycomb can configure SPAN on an interface both
+| TC03: Honeycomb can configure SPAN on an interface both
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state both.
 | | ...
 | | When Honeycomb Configures SPAN on interface
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state both.
 | | ...
 | | When Honeycomb Configures SPAN on interface
-| | ... | ${node} | ${interface1} | ${settings_3}
-| | Then Interface SPAN Operational Data From Honeycomb Should Be
-| | ... | ${node} | ${interface1} | ${settings_3}
+| | ... | ${node} | ${interface1} | ${settings_both}
+| | Then Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${settings_both}
 
 
-| TC04: Honeycomb can configure SPAN on two interfaces
+| TC04: Honeycomb can configure SPAN on an interface with two source interfaces
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state both.
 | | ...
 | | When Honeycomb Configures SPAN on interface
 | | [Documentation] | Honeycomb configures SPAN on interface and verifies
 | | ... | against VPP SPAN dump in state both.
 | | ...
 | | When Honeycomb Configures SPAN on interface
-| | ... | ${node} | ${interface1} | ${settings_2} | ${settings_4}
-| | Then Interface SPAN Operational Data From Honeycomb Should Be
-| | ... | ${node} | ${interface1} | ${settings_2} | ${settings_4}
+| | ... | ${node} | ${interface1} | ${settings_both} | ${settings_if2}
+| | Then Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${settings_both} | ${settings_if2}
 
 | TC05: Honeycomb can disable SPAN on interface
 | | [Documentation] | Honeycomb removes existing SPAN configuration
 
 | TC05: Honeycomb can disable SPAN on interface
 | | [Documentation] | Honeycomb removes existing SPAN configuration
-| | ... | on interface.
+| | ... | from interface.
 | | ...
 | | ...
-| | Given Interface SPAN Operational Data From Honeycomb Should Be
-| | ... | ${node} | ${interface1} | ${settings_2} | ${settings_4}
+| | Given Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${settings_both} | ${settings_if2}
 | | When Honeycomb removes interface SPAN configuration
 | | ... | ${node} | ${interface1}
 | | When Honeycomb removes interface SPAN configuration
 | | ... | ${node} | ${interface1}
-| | Then Interface SPAN Operational Data From Honeycomb Should Be empty
+| | Then Interface SPAN Operational Data from Honeycomb should be empty
 | | ... | ${node} | ${interface1}
 
 | | ... | ${node} | ${interface1}
 
-| TC06: DUT mirrors IPv4 packets from one interface to another
-| | [TearDown] | Show Packet Trace on All DUTs | ${nodes}
+| TC06: Honeycomb can configure SPAN with two destination interfaces from the same source
+| | [Documentation] | Honeycomb configures SPAN on two interfaces and verifies
+| | ... | against VPP SPAN dump.
+| | ...
+| | [Teardown] | Run Keywords
+| | ... | Honeycomb removes interface SPAN configuration
+| | ... | ${node} | ${interface1} | AND
+| | ... | Honeycomb removes interface SPAN configuration
+| | ... | ${node} | ${interface2}
+| | When Honeycomb Configures SPAN on interface
+| | ... | ${node} | ${interface1} | ${settings_if2}
+| | And Honeycomb Configures SPAN on interface
+| | ... | ${node} | ${interface2} | ${settings_if2}
+| | Then Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${settings_if2}
+| | Then Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface2} | ${settings_if2}
+
+| TC07: DUT mirrors IPv4 packets from one interface to another
 | | [Documentation]
 | | ... | [Top] TG=DUT1
 | | ... | [Cfg] (using Honeycomb) On DUT1 configure IPv4 address and set SPAN\
 | | [Documentation]
 | | ... | [Top] TG=DUT1
 | | ... | [Cfg] (using Honeycomb) On DUT1 configure IPv4 address and set SPAN\
 | | ... | then receive a copy of sent packet and of DUT's ARP reply\
 | | ... | on the second interface.
 | | ...
 | | ... | then receive a copy of sent packet and of DUT's ARP reply\
 | | ... | on the second interface.
 | | ...
-| | Path for 2-node testing is set
+| | [Teardown] | Run Keywords
+| | ... | Show Packet Trace on All DUTs | ${nodes} | AND
+| | ... | Honeycomb clears all interface ipv4 neighbors
+| | ... | ${dut_node} | ${dut_to_tg_if1} | AND
+| | ... | Honeycomb removes interface ipv4 addresses
+| | ... | ${dut_node} | ${dut_to_tg_if1} | AND
+| | ... | Honeycomb removes interface SPAN configuration
+| | ... | ${node} | ${dut_to_tg_if2}
+| | Given Path for 2-node testing is set
 | | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
 | | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
-| | Honeycomb sets interface state | ${dut_node} | ${dut_to_tg_if1} | up
-| | Honeycomb sets interface state | ${dut_node} | ${dut_to_tg_if2} | up
-| | Honeycomb sets interface ipv4 address with prefix | ${dut_node}
+| | And Honeycomb sets interface state | ${dut_node} | ${dut_to_tg_if1} | up
+| | And Honeycomb sets interface state | ${dut_node} | ${dut_to_tg_if2} | up
+| | And Honeycomb sets interface ipv4 address with prefix | ${dut_node}
 | | ... | ${dut_to_tg_if1} | ${dut_to_tg_if1_ip} | ${prefix}
 | | ... | ${dut_to_tg_if1} | ${dut_to_tg_if1_ip} | ${prefix}
-| | Add ARP on DUT
-| | ... | ${node} | ${dut_to_tg_if1} | ${tg_to_dut_if1_ip}
-| | ... | ${tg_to_dut_if1_mac}
+| | And Honeycomb adds interface ipv4 neighbor | ${dut_node} | ${dut_to_tg_if1}
+| | ... | ${tg_to_dut_if1_ip} | ${tg_to_dut_if1_mac}
 | | ${settings_5}= | create dictionary | state=both
 | | ... | iface-ref=${dut_to_tg_if1}
 | | ${settings_5}= | create dictionary | state=both
 | | ... | iface-ref=${dut_to_tg_if1}
-| | InterfaceCLI.All Vpp Interfaces Ready Wait | ${nodes}
+| | And InterfaceCLI.All Vpp Interfaces Ready Wait | ${nodes}
 | | When Honeycomb Configures SPAN on interface
 | | ... | ${node} | ${dut_to_tg_if2} | ${settings_5}
 | | Then Send Packet And Check Received Copies | ${tg_node}
 | | ... | ${tg_to_dut_if1} | ${tg_to_dut_if1_mac}
 | | ... | ${dut_to_tg_if1_mac} | ${tg_to_dut_if2}
 | | ... | ${tg_to_dut_if1_ip} | ${dut_to_tg_if1_ip} | ICMP
 | | When Honeycomb Configures SPAN on interface
 | | ... | ${node} | ${dut_to_tg_if2} | ${settings_5}
 | | Then Send Packet And Check Received Copies | ${tg_node}
 | | ... | ${tg_to_dut_if1} | ${tg_to_dut_if1_mac}
 | | ... | ${dut_to_tg_if1_mac} | ${tg_to_dut_if2}
 | | ... | ${tg_to_dut_if1_ip} | ${dut_to_tg_if1_ip} | ICMP
+
+| TC08: Honeycomb can configure SPAN on a sub-interface - receive
+| | [Documentation] | Honeycomb configures SPAN on sub-interface and verifies
+| | ... | against VPP SPAN dump in state receive.
+| | ...
+| | Given Honeycomb creates sub-interface | ${node} | ${interface1}
+| | ... | ${sub_if_1_match} | ${sub_if_1_tags} | ${sub_if_1_settings}
+| | When Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${interface1} | ${1} | ${settings_receive}
+| | Then sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | ${settings_receive}
+
+| TC09: Honeycomb can configure SPAN on a sub-interface - transmit
+| | [Documentation] | Honeycomb configures SPAN on sub-interface and verifies
+| | ... | against VPP SPAN dump in state transmit.
+| | ...
+| | Given Sub-interface state from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | down | up
+| | When Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${interface1} | ${1} | ${settings_transmit}
+| | Then sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | ${settings_transmit}
+
+| TC10: Honeycomb can configure SPAN on a sub-interface - both
+| | [Documentation] | Honeycomb configures SPAN on sub-interface and verifies
+| | ... | against VPP SPAN dump in state both.
+| | ...
+| | Given Sub-interface state from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | down | up
+| | When Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${interface1} | ${1} | ${settings_both}
+| | Then sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | ${settings_both}
+
+| TC11: Honeycomb can configure SPAN on a sub-interface with two source interfaces
+| | [Documentation] | Honeycomb configures SPAN on sub-interface and verifies
+| | ... | against VPP SPAN dump in state both.
+| | ...
+| | Given Sub-interface state from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | down | up
+| | When Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${interface1} | ${1} | ${settings_both} | ${settings_if2}
+| | Then sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | ${settings_both} | ${settings_if2}
+
+| TC12: Honeycomb can disable SPAN on interface
+| | [Documentation] | Honeycomb removes existing SPAN configuration
+| | ... | from sub-interface.
+| | ...
+| | Given Sub-interface state from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | down | up
+| | Given sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | ${settings_both} | ${settings_if2}
+| | When Honeycomb removes sub-interface SPAN configuration
+| | ... | ${node} | ${interface1} | ${1}
+| | Then sub-Interface SPAN Operational Data from Honeycomb should be empty
+| | ... | ${node} | ${interface1} | ${1}
+
+| TC13: Honeycomb can configure SPAN with two destination sub-interfaces from the same source
+| | [Documentation] | Honeycomb configures SPAN on two sub-interfaces
+| | ... | and verifies against VPP SPAN dump.
+| | ...
+| | [Teardown] | Run Keywords
+| | ... | Honeycomb removes sub-interface SPAN configuration
+| | ... | ${node} | ${interface1} | ${1} | AND
+| | ... | Honeycomb removes sub-interface SPAN configuration
+| | ... | ${node} | ${interface2} | ${1}
+| | Given Honeycomb creates sub-interface | ${node} | ${interface2}
+| | ... | ${sub_if_2_match} | ${sub_if_2_tags} | ${sub_if_2_settings}
+| | When Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${interface1} | ${1} | ${settings_if2}
+| | And Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${interface2} | ${1} | ${settings_if2}
+| | Then Sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface1} | ${1} | ${settings_if2}
+| | Then Sub-Interface SPAN Operational Data from Honeycomb should be
+| | ... | ${node} | ${interface2} | ${1} | ${settings_if2}
+
+| TC14: DUT mirrors IPv4 packets from one interface to another
+| | [Documentation]
+| | ... | [Top] TG=DUT1
+| | ... | [Cfg] (using Honeycomb) On DUT1 configure IPv4 address and set SPAN\
+| | ... | mirroring from one DUT interface to a sub-interface on the other\
+| | ... | interface.
+| | ... | [Ver] Make TG send an ARP packet to DUT through one interface,\
+| | ... | then receive a copy of sent packet and of DUT's ARP reply\
+| | ... | on the sub-interface.
+| | ...
+| | [Teardown] | Show Packet Trace on All DUTs | ${nodes}
+| | Given Path for 2-node testing is set
+| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
+| | And Sub-interface state from Honeycomb should be
+| | ... | ${dut_node} | ${interface1} | ${1} | down | up
+| | And Honeycomb sets interface state | ${dut_node} | ${dut_to_tg_if1} | up
+| | And Honeycomb sets interface state | ${dut_node} | ${dut_to_tg_if2} | up
+| | And Honeycomb sets the sub-interface up
+| | ... | ${dut_node} | ${dut_to_tg_if1} | ${1}
+| | And Honeycomb sets interface ipv4 address with prefix | ${dut_node}
+| | ... | ${dut_to_tg_if2} | ${dut_to_tg_if2_ip} | ${prefix}
+| | And And Honeycomb adds interface ipv4 neighbor
+| | ... | ${dut_node} | ${dut_to_tg_if2}
+| | ... | ${tg_to_dut_if2_ip} | ${tg_to_dut_if2_mac}
+| | ${settings_5}= | create dictionary | state=both
+| | ... | iface-ref=${dut_to_tg_if2}
+| | And InterfaceCLI.All Vpp Interfaces Ready Wait | ${nodes}
+| | When Honeycomb Configures SPAN on sub-interface
+| | ... | ${node} | ${dut_to_tg_if1} | ${1} | ${settings_5}
+| | Then Send Packet And Check Received Copies | ${tg_node}
+| | ... | ${tg_to_dut_if2} | ${tg_to_dut_if2_mac}
+| | ... | ${dut_to_tg_if2_mac} | ${tg_to_dut_if1}
+| | ... | ${tg_to_dut_if2_ip} | ${dut_to_tg_if2_ip} | ICMP