CSIT-534 HC Test: policer tests 18/6218/9
authorjan.hradil <jan.hradil@pantheon.tech>
Tue, 11 Apr 2017 07:28:07 +0000 (09:28 +0200)
committerTibor Frank <tifrank@cisco.com>
Tue, 25 Apr 2017 09:31:18 +0000 (09:31 +0000)
Added empty lines where needed
Repaired Phrasese "Given" --> "And" where necessary in mgmt-cfg-policer-apihc-func.robot
Corrected English in mgmt-cfg-policer-apihc-func.robot - in TC07 Documentation

Change-Id: Id99d7fd04d8f2dcae1820baa208ce338fad3a290
Signed-off-by: jan.hradil <jan.hradil@pantheon.tech>
resources/libraries/python/honeycomb/HcAPIKwInterfaces.py
resources/libraries/python/honeycomb/Routing.py
resources/libraries/robot/honeycomb/policer.robot [new file with mode: 0644]
resources/templates/honeycomb/config_policer.url [new file with mode: 0644]
resources/templates/honeycomb/oper_policer.url [new file with mode: 0644]
resources/test_data/honeycomb/policer_variables.py [new file with mode: 0644]
tests/func/honeycomb/mgmt-cfg-acl-apihc-apivat-func.robot
tests/func/honeycomb/mgmt-cfg-policer-apihc-func.robot [new file with mode: 0644]

index 19ce8f2..d57f939 100644 (file)
@@ -1511,6 +1511,69 @@ class InterfaceKeywords(object):
                 "Status code: {1}.".format(interface, status_code))
         return resp
 
+    @staticmethod
+    def enable_policer_on_interface(node, interface, table_name):
+        """Enable Policer on the given interface.
+
+        :param node: Honeycomb node.
+        :param interface: The interface where policer will be enabled.
+        :param table_name: Name of the classify table.
+        :type node: dict
+        :type interface: str
+        :type table_name: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+        successful.
+        """
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+        interface = interface.replace("/", "%2F")
+
+        data = {
+                    "interface-policer:policer": {
+                        "ip4-table": table_name
+                    }
+                }
+
+        path = "/interface/" + interface + "/interface-policer:policer"
+        status_code, resp = HcUtil.\
+            put_honeycomb_data(node, "config_vpp_interfaces", data, path,
+                               data_representation=DataRepresentation.JSON)
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
+
+    @staticmethod
+    def disable_policer_on_interface(node, interface):
+        """Disable Policer on the given interface.
+
+        :param node: Honeycomb node.
+        :param interface: The interface where policer will be disabled.
+        :param table_name: Name of the classify table.
+        :type node: dict
+        :type interface: str
+        :type table_name: str
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+        successful.
+        """
+        interface = Topology.convert_interface_reference(
+            node, interface, "name")
+        interface = interface.replace("/", "%2F")
+
+        path = "/interface/" + interface + "/interface-policer:policer"
+        status_code, resp = HcUtil.\
+            delete_honeycomb_data(node, "config_vpp_interfaces", path)
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "The configuration of interface '{0}' was not successful. "
+                "Status code: {1}.".format(interface, status_code))
+        return resp
+
     @staticmethod
     def disable_acl_on_interface(node, interface):
         """Disable ACL on the given interface.
index c39031d..a4d606b 100644 (file)
@@ -273,3 +273,60 @@ class RoutingKeywords(object):
             return {k: str(v) for k, v in dict_of_str.items()}
         except (KeyError, TypeError):
             return {}
+
+    @staticmethod
+    def configure_policer(node, policy_name, policer_data=None):
+        """Configure Policer on the specified node.
+
+        :param node: Honeycomb node.
+        :param policer_data: Dictionary of configurations to apply. \
+        If it is None then the existing configuration is removed.
+        :type node: dict
+        :type policer_data: dict
+        :returns: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If policer could not be configured.
+        """
+
+        path = '/' + policy_name
+
+        if not policer_data:
+            status_code, _ = HcUtil.delete_honeycomb_data(
+                node, 'config_policer', path)
+        else:
+            data = {
+                'policer': policer_data
+            }
+
+            status_code, _ = HcUtil.put_honeycomb_data(
+                node, 'config_policer', data, path)
+
+        if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+            raise HoneycombError(
+                'Configuring policer failed. Status code:{0}'\
+                    .format(status_code))
+
+    @staticmethod
+    def get_policer_oper_data(node, policy_name):
+        """Get operational data about Policer on the node.
+
+        :param node: Honeycomb node.
+        :type node: dict
+        :returns: dict of Policer operational data.
+        :rtype: dict
+        :raises HoneycombError: If status code differs from successful.
+        """
+
+        path = '/' + policy_name
+
+        status_code, resp = HcUtil.\
+            get_honeycomb_data(node, "oper_policer", path)
+
+        if status_code != HTTPCodes.OK:
+            raise HoneycombError(
+                "Not possible to get operational information about Policer. "
+                "Status code: {0}.".format(status_code))
+        try:
+            return resp['policer']
+        except (KeyError, TypeError):
+            return {}
diff --git a/resources/libraries/robot/honeycomb/policer.robot b/resources/libraries/robot/honeycomb/policer.robot
new file mode 100644 (file)
index 0000000..65ef319
--- /dev/null
@@ -0,0 +1,163 @@
+# Copyright (c) 2017 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+*** Settings ***
+| Resource | resources/libraries/robot/traffic.robot
+| Library | resources.libraries.python.honeycomb.Routing.RoutingKeywords
+| ...     | WITH NAME | RoutingKeywordsAPI
+| Variables | resources/test_data/honeycomb/policer_variables.py
+| Documentation | Keywords used to test Policer using Honeycomb.
+
+*** Keywords ***
+| Honeycomb Configures Policer
+| | [Documentation] | Uses Honeycomb API to configure Policer on the specified\
+| | ... | interface.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - policer_data - data needed to configure Policer. Type: dictionary
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb Configures Policer \| ${node} \
+| | ... | \| ${policer_data} \|
+| | ...
+| | [Arguments] | ${node} | ${policer_data}
+| | Configure Policer
+| | ... | ${node} | ${policer_data['name']} | ${policer_data}
+
+| Policer configuration from Honeycomb should be
+| | [Documentation] | Retrieves Policer operational data and verifies if\
+| | ... | Policer is configured correctly.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - policer_data - data to compare configuration Policer with.\
+| | ... | Type: dictionary
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Policer configuration from Honeycomb should be \
+| | ... | \| ${node} \| ${policer_data} \|
+| | ...
+| | [Arguments] | ${node} | ${policer_data}
+| | ${data}= | Get Policer oper data | ${node} | ${policer_data['name']}
+| | Compare data structures | ${data[0]} | ${policer_data}
+
+| Policer configuration from Honeycomb should be empty
+| | [Documentation] | Checks whether Policer configuration from Honeycomb \
+| | ... | is empty.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - Information about a DUT node. Type: dictionary
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Policer configuration from Honeycomb should be empty \
+| | ... | \| ${node} \|
+| | ...
+| | [Arguments] | ${node}
+| | Run keyword and expect error | HoneycombError*404*
+| | ... | Get Policer oper data | ${node} | ${policer_data['name']}
+
+| Honeycomb removes Policer configuration
+| | [Documentation] | Uses Honeycomb API to remove Policer configuration\
+| | ... | from the specified interface.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb removes Policer configuration \
+| | ... | \| ${nodes['DUT1']} \| GigabitEthernet0/8/0 \|
+| | ...
+| | [Arguments] | ${node}
+| | Configure Policer | ${node} | ${policer_data['name']}
+
+| Policer test teardown
+| | [Documentation] | Uses Honeycomb API to remove Policer configuration\
+| | ... | and reset interface state.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb removes Policer configuration \
+| | ... | \| ${nodes['DUT1']} \| GigabitEthernet0/8/0 \|
+| | ...
+| | [Arguments] | ${node}
+| | Honeycomb removes Policer configuration | ${node}
+
+| Honeycomb enables Policer on interface
+| | [Documentation] | Uses Honeycomb API to enable Policer on an interface.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - interface - name of an interface on the specified node. Type: string
+| | ... | - table_name - name of an ACL table. Type: string
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb enables ACL on interface \| ${nodes['DUT1']} \
+| | ... | \| GigabithEthernet0/8/0 \| table0 \|
+| | ...
+| | [Arguments] | ${node} | ${interface} | ${table_name}
+| | Enable Policer on interface
+| | ... | ${node} | ${interface} | ${table_name}
+
+| Honeycomb disables Policer on interface
+| | [Documentation] | Uses Honeycomb API to disable Policer on an interface.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - information about a DUT node. Type: dictionary
+| | ... | - interface - name of an interface on the specified node. Type: string
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| Honeycomb disables Policer on interface \| ${nodes['DUT1']} \
+| | ... | \| GigabithEthernet0/8/0 \|
+| | ...
+| | [Arguments] | ${node} | ${interface}
+| | Disable Policer on interface
+| | ... | ${node} | ${interface}
+
+| Honeycomb Send Packet and Verify Marking
+| | [Documentation] | Send packet and verify DSCP of the received packet.
+| | ...
+| | ... | *Arguments:*
+| | ... | - node - TG node. Type: dictionary
+| | ... | - tx_if - TG transmit interface. Type: string
+| | ... | - rx_if - TG receive interface. Type: string
+| | ... | - src_mac - Packet source MAC. Type: string
+| | ... | - dst_mac - Packet destination MAC. Type: string
+| | ... | - src_ip - Packet source IP address. Type: string
+| | ... | - dst_ip - Packet destination IP address. Type: string
+| | ... | - dscp_num - DSCP value to verify. Type: integer
+| | ...
+| | ... | *Example:*
+| | ...
+| | ... | \| ${dscp}= \| DSCP AF22 \|
+| | ... | \| Send Packet and Verify Marking \| ${nodes['TG']} \| eth1 \| eth2 \
+| | ... | \| 08:00:27:87:4d:f7 \| 52:54:00:d4:d8:22 \| 192.168.122.2 \
+| | ... | \| 192.168.122.1 \| ${dscp} \|
+| | ...
+| | [Arguments] | ${node} | ${tx_if} | ${rx_if} | ${src_mac} | ${dst_mac}
+| | ...         | ${src_ip} | ${dst_ip} | ${dscp_num}
+| | ${tx_if_name}= | Get Interface Name | ${node} | ${tx_if}
+| | ${rx_if_name}= | Get Interface Name | ${node} | ${rx_if}
+| | ${args}= | Traffic Script Gen Arg | ${rx_if_name} | ${tx_if_name}
+| | ...      | ${src_mac} | ${dst_mac} | ${src_ip} | ${dst_ip}
+| | ${args}= | Set Variable | ${args} --dscp ${dscp_num}
+| | Run Traffic Script On Node | policer.py | ${node} | ${args}
diff --git a/resources/templates/honeycomb/config_policer.url b/resources/templates/honeycomb/config_policer.url
new file mode 100644 (file)
index 0000000..ed840e1
--- /dev/null
@@ -0,0 +1 @@
+/restconf/config{odl_url_part}/policer:policers/policer
\ No newline at end of file
diff --git a/resources/templates/honeycomb/oper_policer.url b/resources/templates/honeycomb/oper_policer.url
new file mode 100644 (file)
index 0000000..fe42bc1
--- /dev/null
@@ -0,0 +1 @@
+/restconf/operational{odl_url_part}/policer:policers-state/policer
\ No newline at end of file
diff --git a/resources/test_data/honeycomb/policer_variables.py b/resources/test_data/honeycomb/policer_variables.py
new file mode 100644 (file)
index 0000000..6c6c9a5
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright (c) 2017 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Test variables for Policer test suite."""
+
+
+def get_variables():
+    """Create and return a dictionary of test variables for the specified
+    test case.
+
+    :returns: Dictionary of test variables - settings for Honeycomb's Policer.
+    :rtype: dict
+    """
+    policer_data = {
+        "policer_data": {
+            "name": "policy1",
+            "cir": 450,
+            "cb": 50000,
+            "rate-type": "kbps",
+            "round-type": "closest",
+            "type": "1r2c",
+            "conform-action": {
+                "meter-action-type": "meter-action-transmit"
+            },
+            "exceed-action": {
+                "meter-action-type": "meter-action-drop"
+            }
+        },
+        "policer_data_oper": {
+            "name": "policy1",
+            "cir": 450,
+            "cb": 50000,
+            "rate-type": "kbps",
+            "round-type": "closest",
+            "type": "1r2c",
+            "conform-action": {
+                "meter-action-type": "policer:meter-action-transmit"
+            },
+            "exceed-action": {
+                "meter-action-type": "policer:meter-action-drop"
+            }
+        },
+        "policer_data_2": {
+            "name": "policy1",
+            "cir": 900,
+            "cb": 50000,
+            "rate-type": "kbps",
+            "round-type": "closest",
+            "type": "1r2c",
+            "conform-action": {
+                "meter-action-type": "meter-action-transmit"
+            },
+            "exceed-action": {
+                "meter-action-type": "meter-action-drop"
+            }
+        },
+        "policer_data_oper_2": {
+            "name": "policy1",
+            "cir": 900,
+            "cb": 50000,
+            "rate-type": "kbps",
+            "round-type": "closest",
+            "type": "1r2c",
+            "conform-action": {
+                "meter-action-type": "policer:meter-action-transmit"
+            },
+            "exceed-action": {
+                "meter-action-type": "policer:meter-action-drop"
+            }
+        },
+        "policer_data_3": {
+            "name": "policy1",
+            "cir": 100,
+            "eir": 150,
+            "cb": 200,
+            "eb": 300,
+            "rate-type": "pps",
+            "round-type": "closest",
+            "type": "2r3c-2698",
+            "conform-action": {
+                "meter-action-type": "meter-action-transmit"
+            },
+            "exceed-action": {
+                "meter-action-type": "meter-action-mark-dscp",
+                "dscp": "AF22"
+            },
+            "violate-action": {
+                "meter-action-type": "meter-action-drop"
+            },
+            "color-aware": True
+            },
+        "policer_data_oper_3": {
+            "name": "policy1",
+            "cir": 100,
+            "eir": 150,
+            "cb": 200,
+            "eb": 300,
+            "rate-type": "pps",
+            "round-type": "closest",
+            "type": "2r3c-2698",
+            "conform-action": {
+                "meter-action-type": "policer:meter-action-transmit"
+            },
+            "exceed-action": {
+                "meter-action-type": "policer:meter-action-mark-dscp",
+            },
+            "violate-action": {
+                "meter-action-type": "policer:meter-action-drop"
+            },
+            "color-aware": True
+        },
+
+        "acl_tables": {
+            # settings for policer tables
+            "hc_acl_table": {
+                "name": "table0",
+                "nbuckets": 2,
+                "memory_size": 1048576,
+                "skip_n_vectors": 12,
+                "miss_next": "permit",
+                "mask": "00:00:00:00:00:00:00:00:00:00:00:00:ff:ff:ff:ff"
+            },
+            # setting for acl sessions
+            "hc_acl_session": {
+                "match": "00:00:00:00:00:00:00:00:00:00:00:00:C0:A8:7A:01",
+                "policer_hit_next": "policy1",
+                "color_classfier": "exceed-color",
+            },
+            "hc_acl_session2": {
+                "match": "00:00:00:00:00:00:00:00:00:00:00:00:C0:A8:7A:02",
+                "policer_hit_next": "policy1",
+                "color_classfier": "exceed-color",
+            },
+        },
+    }
+    return policer_data
index 4dad038..1dac598 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Cisco and/or its affiliates.
+# Copyright (c) 2017 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
diff --git a/tests/func/honeycomb/mgmt-cfg-policer-apihc-func.robot b/tests/func/honeycomb/mgmt-cfg-policer-apihc-func.robot
new file mode 100644 (file)
index 0000000..f7d8e99
--- /dev/null
@@ -0,0 +1,128 @@
+# Copyright (c) 2017 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+*** Variables ***
+| ${interface}= | ${node['interfaces']['port1']['name']}
+| ${tg_to_dut_if1_ip}= | 192.168.122.1
+| ${dut_to_tg_if1_ip}= | 192.168.122.2
+| ${dut_to_tg_if2_ip}= | 192.168.123.1
+| ${tg_to_dut_if2_ip}= | 192.168.123.2
+| ${prefix_length}= | ${24}
+| ${dscp_number}= | ${20}
+
+*** Settings ***
+| Resource | resources/libraries/robot/default.robot
+| Resource | resources/libraries/robot/honeycomb/honeycomb.robot
+| Resource | resources/libraries/robot/honeycomb/interfaces.robot
+| Resource | resources/libraries/robot/honeycomb/policer.robot
+| Resource | resources/libraries/robot/honeycomb/access_control_lists.robot
+| Resource | resources/libraries/robot/testing_path.robot
+| Library | resources.libraries.python.Trace
+| Variables | resources/test_data/honeycomb/policer_variables.py
+| Suite Teardown
+| ... | Run Keyword If Any Tests Failed
+| ... | Restart Honeycomb and VPP | ${node}
+| Force Tags | honeycomb_sanity | honeycomb_odl
+| Documentation | *Honeycomb Policer management test suite.*
+
+*** Test Cases ***
+| TC01: Honeycomb can configure Policer
+| | [Documentation] | Checks if Honeycomb can configure Policer.
+| | Given Policer configuration from Honeycomb should be empty | ${node}
+| | When Honeycomb configures Policer | ${node} | ${policer_data}
+| | Then Policer configuration from Honeycomb should be | ${node}
+| | ... | ${policer_data_oper}
+
+| TC02: Honeycomb can disable Policer
+| | [Documentation] | Checks if Honeycomb can disable Policer.
+| | Given Policer configuration from Honeycomb should be | ${node}
+| | ... | ${policer_data_oper}
+| | When Honeycomb removes Policer configuration | ${node}
+| | Then Policer configuration from Honeycomb should be empty | ${node}
+
+| TC03: Honeycomb can configure Policer with increased values of CIR (900kbps)
+| | [Documentation] | Checks if Honeycomb can configure Policer\
+| | ... | with increased values of CIR.
+| | [Teardown] | Policer test teardown | ${node}
+| | Given Policer configuration from Honeycomb should be empty | ${node}
+| | When Honeycomb configures Policer | ${node} | ${policer_data_2}
+| | Then Policer configuration from Honeycomb should be | ${node}
+| | ... | ${policer_data_oper_2}
+
+| TC04: Honeycomb can configure Packets-Per-Second Based Policer
+| | [Documentation] | Checks if Honeycomb can configure Policer\
+| | ... | based on rate-type measured in pps.
+| | [Teardown] | Policer test teardown | ${node}
+| | Given Policer configuration from Honeycomb should be empty | ${node}
+| | When Honeycomb configures Policer | ${node} | ${policer_data_3}
+| | Then Policer configuration from Honeycomb should be | ${node}
+| | ... | ${policer_data_oper_3}
+
+| TC05: Configure Policer on Interface
+| | [Documentation] | Honeycomb can configure Policer\
+| | ... | on a given interface.
+| | [Teardown] | Run Keywords
+| | ... | Honeycomb disables Policer on interface | ${node} | ${interface} | AND
+| | ... | Honeycomb removes ACL session
+| | ... | ${node} | ${acl_tables['hc_acl_table']['name']}
+| | ... | ${acl_tables['hc_acl_session']['match']} | AND
+| | ... | Honeycomb removes ACL table | ${node}
+| | ... | ${acl_tables['hc_acl_table']['name']} | AND
+| | ... | Policer test teardown | ${node}
+| | Given Honeycomb configures Policer | ${node} | ${policer_data}
+| | And ACL table from Honeycomb should not exist
+| | ... | ${node} | ${acl_tables['hc_acl_table']['name']}
+| | When Honeycomb creates ACL table
+| | ... | ${node} | ${acl_tables['hc_acl_table']}
+| | And Honeycomb adds ACL session
+| | ... | ${node} | ${acl_tables['hc_acl_table']['name']}
+| | ... | ${acl_tables['hc_acl_session']}
+| | Then Honeycomb enables policer on interface
+| | ... | ${node} | ${interface} | ${acl_tables['hc_acl_table']['name']}
+
+| TC06: VPP policer 2R3C Color-aware marks packet
+| | [Documentation]
+| | ... | [Top] TG=DUT1.
+| | ... | [Ref] RFC2474, RFC2698.
+| | ... | [Cfg] Configure 2R3C color-aware policer on DUT1 on the first\
+| | ... | interface.
+| | ... | [Ver] TG sends IPv4 TCP packet on the first link to DUT1.\
+| | ... | Packet on DUT1 is marked with DSCP tag. Verifies if DUT1 sends\
+| | ... | correct IPv4 TCP packet with correct DSCP on the second link to TG.
+| | [Teardown] | Show Packet Trace on All DUTs | ${nodes}
+| | Given Path for 2-node testing is set
+| | ... | ${nodes['TG']} | ${nodes['DUT1']} | ${nodes['TG']}
+| | And Honeycomb configures Policer | ${dut_node} | ${policer_data_3}
+| | And ACL table from Honeycomb should not exist
+| | ... | ${dut_node} | ${acl_tables['hc_acl_table']['name']}
+| | When Honeycomb creates ACL table
+| | ... | ${dut_node} | ${acl_tables['hc_acl_table']}
+| | And Honeycomb adds ACL session
+| | ... | ${dut_node} | ${acl_tables['hc_acl_table']['name']}
+| | ... | ${acl_tables['hc_acl_session']}
+| | And Honeycomb enables policer on interface
+| | ... | ${dut_node} | ${dut_to_tg_if1} | ${acl_tables['hc_acl_table']['name']}
+| | 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_length}
+| | And Honeycomb sets interface ipv4 address with prefix | ${dut_node}
+| | ... | ${dut_to_tg_if2} | ${dut_to_tg_if2_ip} | ${prefix_length}
+| | And Honeycomb adds interface ipv4 neighbor
+| | ... | ${dut_node} | ${dut_to_tg_if2} | ${tg_to_dut_if2_ip}
+| | ... | ${tg_to_dut_if2_mac}
+| | And interfaceCLI.VPP Node Interfaces Ready Wait | ${dut_node}
+| | Then Honeycomb Send Packet and Verify Marking | ${tg_node}
+| | ... | ${tg_to_dut_if1}
+| | ... | ${tg_to_dut_if2} | ${tg_to_dut_if1_mac} | ${dut_to_tg_if1_mac}
+| | ... | ${tg_to_dut_if1_ip} | ${tg_to_dut_if2_ip} | ${dscp_number}