[v3,4/4] dts: dynamic config test suite

Message ID 20240708193012.5465-4-dmarx@iol.unh.edu (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v3,1/4] dts: add multicast set function to shell |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/github-robot: build success github build: passed
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-compile-amd64-testing success Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS

Commit Message

Dean Marx July 8, 2024, 7:30 p.m. UTC
Suite for testing ability of Poll Mode Driver to turn promiscuous
mode on/off, allmulticast mode on/off, and show expected behavior
when sending packets with known, unknown, broadcast, and multicast
destination MAC addresses.

Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
---
 dts/tests/TestSuite_dynamic_config.py | 149 ++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)
 create mode 100644 dts/tests/TestSuite_dynamic_config.py
  

Comments

Jeremy Spewock July 10, 2024, 4:45 p.m. UTC | #1
On Mon, Jul 8, 2024 at 3:30 PM Dean Marx <dmarx@iol.unh.edu> wrote:
>
> Suite for testing ability of Poll Mode Driver to turn promiscuous
> mode on/off, allmulticast mode on/off, and show expected behavior
> when sending packets with known, unknown, broadcast, and multicast
> destination MAC addresses.
>
> Signed-off-by: Dean Marx <dmarx@iol.unh.edu>
> ---
>  dts/tests/TestSuite_dynamic_config.py | 149 ++++++++++++++++++++++++++
>  1 file changed, 149 insertions(+)
>  create mode 100644 dts/tests/TestSuite_dynamic_config.py
>
> diff --git a/dts/tests/TestSuite_dynamic_config.py b/dts/tests/TestSuite_dynamic_config.py
> new file mode 100644
> index 0000000000..a6e5384c50
> --- /dev/null
> +++ b/dts/tests/TestSuite_dynamic_config.py
> @@ -0,0 +1,149 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 University of New Hampshire
> +
> +"""Dynamic configuration capabilities test suite.
> +
> +This suite checks that it is possible to change the configuration of a port
> +dynamically. The Poll Mode Driver should be able to enable and disable
> +promiscuous mode on each port, as well as check the Rx and Tx packets of
> +each port

It might be worth explaining here more of what specifically is being
checked by the PMD. It seems like there is different expected output
based on whether promisc mode is on or not as well as different
behaviors with different MAC addresses.
.
> +
> +If packets should be received and forwarded, or received and not forwarded,
> +depending on the configuration, the port info should match the expected behavior.
> +"""
<snip>
> +    def test_default_mode(self) -> None:
> +        """Tests default configuration.
> +
> +        Creates a testpmd shell, verifies that promiscuous mode is enabled by default,
> +        and sends two packets; one matching source MAC address and one unknown.
> +        Verifies that both are received.
> +        """
> +        testpmd = TestPmdShell(node=self.sut_node)
> +        isPromisc = testpmd.show_port_info(0).is_promiscuous_mode_enabled
> +        self.verify(isPromisc, "Promiscuous mode was not enabled by default.")
> +        testpmd.start()
> +        mac = testpmd.show_port_info(0).mac_address
> +        # send a packet with Rx port mac address
> +        self.send_packet_and_verify(should_receive=True, mac_address=str(mac))
> +        # send a packet with mismatched mac address
> +        self.send_packet_and_verify(should_receive=True, mac_address="00:00:00:00:00:00")

We should be careful using the MAC address that is all 0s as that is a
special address that is reserved for localhost. I think it would still
work in this case since it wouldn't match the address of the tester's
port anyway, but it might be safer to just make the last digit of this
a 1 regardless.

> +        testpmd.close()
> +        sleep(6)
> +
<snip>
> 2.44.0
>
  

Patch

diff --git a/dts/tests/TestSuite_dynamic_config.py b/dts/tests/TestSuite_dynamic_config.py
new file mode 100644
index 0000000000..a6e5384c50
--- /dev/null
+++ b/dts/tests/TestSuite_dynamic_config.py
@@ -0,0 +1,149 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2024 University of New Hampshire
+
+"""Dynamic configuration capabilities test suite.
+
+This suite checks that it is possible to change the configuration of a port
+dynamically. The Poll Mode Driver should be able to enable and disable
+promiscuous mode on each port, as well as check the Rx and Tx packets of
+each port.
+
+If packets should be received and forwarded, or received and not forwarded,
+depending on the configuration, the port info should match the expected behavior.
+"""
+
+from time import sleep
+
+from scapy.layers.inet import IP  # type: ignore[import-untyped]
+from scapy.layers.l2 import Ether  # type: ignore[import-untyped]
+from scapy.packet import Raw  # type: ignore[import-untyped]
+
+from framework.params.testpmd import SimpleForwardingModes
+from framework.remote_session.testpmd_shell import TestPmdShell
+from framework.test_suite import TestSuite
+
+
+class TestDynamicConfig(TestSuite):
+    """Dynamic config suite.
+
+    Use the show port commands to see the MAC address and promisc mode status
+    of the Rx port on the DUT. The suite will check the Rx and Tx packets
+    of each port after configuring promiscuous, multicast, and default mode
+    on the DUT to verify the expected behavior. It consists of four test cases:
+
+    1. Default mode: verify packets are received and forwarded.
+    2. Disable promiscuous mode: verify that packets are received
+    only for the packet with destination address matching the port address.
+    3. Disable promiscuous mode broadcast: verify that packets with destination
+    MAC address not matching the port are received and not forwarded, and verify
+    that broadcast packets are received and forwarded.
+    4. Disable promiscuous mode multicast: verify that packets with destination
+    MAC address not matching the port are received and not forwarded, and verify
+    that multicast packets are received and forwarded.
+    """
+
+    def set_up_suite(self) -> None:
+        """Set up the test suite.
+
+        Setup:
+            Verify that at least two ports are open for session.
+        """
+        self.verify(len(self._port_links) > 1, "Not enough ports")
+
+    def send_packet_and_verify(self, should_receive: bool, mac_address: str) -> None:
+        """Generate, send and verify packets.
+
+        Generate a packet and send to the DUT, verify that packet is forwarded from DUT to
+        traffic generator if that behavior is expected.
+
+        Args:
+            should_receive: Indicate whether the packet should be received.
+            mac_address: Destination MAC address to generate in packet.
+        """
+        packet = Ether(dst=mac_address) / IP() / Raw(load="xxxxx")
+        received = self.send_packet_and_capture(packet=packet, adjust_addresses=False)
+        contains_packet = any(
+            packet.haslayer(Raw) and b"xxxxx" in packet.load for packet in received
+        )
+        self.verify(
+            should_receive == contains_packet,
+            f"Packet was {'dropped' if should_receive else 'received'}",
+        )
+
+    def disable_promisc_setup(self, port_id: int) -> TestPmdShell:
+        """Sets up testpmd shell config for cases where promisc mode is disabled.
+
+        Args:
+            port_id: Port number to disable promisc mode on.
+
+        Returns:
+            shell: interactive testpmd shell object.
+        """
+        shell = TestPmdShell(node=self.sut_node)
+        shell.start()
+        shell.set_promisc(port=port_id, on=False)
+        shell.set_forward_mode(SimpleForwardingModes.io)
+        return shell
+
+    def test_default_mode(self) -> None:
+        """Tests default configuration.
+
+        Creates a testpmd shell, verifies that promiscuous mode is enabled by default,
+        and sends two packets; one matching source MAC address and one unknown.
+        Verifies that both are received.
+        """
+        testpmd = TestPmdShell(node=self.sut_node)
+        isPromisc = testpmd.show_port_info(0).is_promiscuous_mode_enabled
+        self.verify(isPromisc, "Promiscuous mode was not enabled by default.")
+        testpmd.start()
+        mac = testpmd.show_port_info(0).mac_address
+        # send a packet with Rx port mac address
+        self.send_packet_and_verify(should_receive=True, mac_address=str(mac))
+        # send a packet with mismatched mac address
+        self.send_packet_and_verify(should_receive=True, mac_address="00:00:00:00:00:00")
+        testpmd.close()
+        sleep(6)
+
+    def test_disable_promisc(self) -> None:
+        """Tests disabled promiscuous mode configuration.
+
+        Creates an interactive testpmd shell, disables promiscuous mode,
+        and sends two packets; one matching source MAC address and one unknown.
+        Verifies that only the matching address packet is received.
+        """
+        testpmd = self.disable_promisc_setup(port_id=0)
+        mac = testpmd.show_port_info(0).mac_address
+        self.send_packet_and_verify(should_receive=True, mac_address=str(mac))
+        self.send_packet_and_verify(should_receive=False, mac_address="00:00:00:00:00:00")
+        testpmd.close()
+        sleep(6)
+
+    def test_disable_promisc_broadcast(self) -> None:
+        """Tests broadcast reception with disabled promisc mode config.
+
+        Creates an interactive testpmd shell, disables promiscuous mode,
+        and sends two packets; one matching source MAC address and one broadcast.
+        Verifies that both packets are received.
+        """
+        testpmd = self.disable_promisc_setup(port_id=0)
+        mac = testpmd.show_port_info(0).mac_address
+        self.send_packet_and_verify(should_receive=True, mac_address=str(mac))
+        self.send_packet_and_verify(should_receive=True, mac_address="ff:ff:ff:ff:ff:ff")
+        testpmd.close()
+        sleep(6)
+
+    def test_disable_promisc_multicast(self) -> None:
+        """Tests allmulticast mode with disabled promisc config.
+
+        Creates an interactive testpmd shell, disables promiscuous mode,
+        and sends two packets; one matching source MAC address and one multicast.
+        Verifies that the multicast packet is only received once allmulticast mode is enabled.
+        """
+        testpmd = self.disable_promisc_setup(port_id=0)
+        testpmd.set_multicast_all(on=False)
+        # 01:00:5E:00:00:01 is the first of the multicast MAC range of addresses
+        self.send_packet_and_verify(should_receive=False, mac_address="01:00:5E:00:00:01")
+        testpmd.set_multicast_all(on=True)
+        self.send_packet_and_verify(should_receive=True, mac_address="01:00:05E:00:00:01")
+        testpmd.close()
+        sleep(6)