Add cryptodev performance test suite. This test covers throughput
performance metrics of various crypto devices using the
dpdk-test-crypto-perf application. The results of this application will
be compared against user supplied performance metrics and fail if signs
of regression are apparent.

Signed-off-by: Andrew Bailey <[email protected]>
---
 .../tests.TestSuite_cryptodev_throughput.rst  |   8 +
 dts/tests/TestSuite_cryptodev_throughput.py   | 386 ++++++++++++++++++
 2 files changed, 394 insertions(+)
 create mode 100644 doc/api/dts/tests.TestSuite_cryptodev_throughput.rst
 create mode 100644 dts/tests/TestSuite_cryptodev_throughput.py

diff --git a/doc/api/dts/tests.TestSuite_cryptodev_throughput.rst 
b/doc/api/dts/tests.TestSuite_cryptodev_throughput.rst
new file mode 100644
index 0000000000..5df5e7547e
--- /dev/null
+++ b/doc/api/dts/tests.TestSuite_cryptodev_throughput.rst
@@ -0,0 +1,8 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+
+cryptodev_throughput Test Suite
+===============================
+
+.. automodule:: tests.TestSuite_cryptodev_throughput
+   :members:
+   :show-inheritance:
diff --git a/dts/tests/TestSuite_cryptodev_throughput.py 
b/dts/tests/TestSuite_cryptodev_throughput.py
new file mode 100644
index 0000000000..b75b41e532
--- /dev/null
+++ b/dts/tests/TestSuite_cryptodev_throughput.py
@@ -0,0 +1,386 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2025 University of New Hampshire
+
+"""DPDK cryptodev performance test suite.
+
+The main goal of this testsuite is to utilize the dpdk-test-cryptodev 
application to gather
+performance metrics for various cryptographic operations supported by DPDK 
cryptodev-pmd.
+It will then compare the results against predefined baseline defined in the 
test_config file to
+ensure performance standards are met.
+"""
+
+from api.capabilities import (
+    LinkTopology,
+    requires_link_topology,
+)
+from api.cryptodev import Cryptodev
+from api.cryptodev.config import (
+    AeadAlgName,
+    AuthenticationAlgorithm,
+    AuthenticationOpMode,
+    CipherAlgorithm,
+    DeviceType,
+    EncryptDecryptSwitch,
+    ListWrapper,
+    OperationType,
+    TestType,
+)
+from api.cryptodev.types import (
+    CryptodevResults,
+)
+from api.test import verify
+from framework.test_suite import BaseConfig, TestSuite, func_test
+
+
+class Config(BaseConfig):
+    """Performance test metrics."""
+
+    common_params: dict[str, int | float] = {
+        "Gbps Delta": 0.05,
+    }
+    throughput_test_parameters: list[dict[str, int | float | str]] = [
+        {
+            **common_params,
+            "buff_size": 64,
+            "mops": 9.85,
+            "gbps": 2.49,
+        },
+        {
+            **common_params,
+            "buff_size": 128,
+            "mops": 4.83,
+            "gbps": 4.95,
+        },
+        {
+            **common_params,
+            "buff_size": 256,
+            "mops": 4.77,
+            "gbps": 9.76,
+        },
+        {
+            **common_params,
+            "buff_size": 512,
+            "mops": 4.52,
+            "gbps": 18.52,
+        },
+        {
+            **common_params,
+            "buff_size": 1048,
+            "mops": 3.77,
+            "gbps": 30.87,
+        },
+        {
+            **common_params,
+            "buff_size": 2048,
+            "mops": 2.49,
+            "gbps": 40.86,
+        },
+    ]
+
+
+@requires_link_topology(LinkTopology.NO_LINK)
+class TestCryptodevThroughput(TestSuite):
+    """DPDK Crypto Device Testing Suite."""
+
+    config: Config
+    unsupported_cryptodevs: list[DeviceType] = []
+
+    def set_up_suite(self) -> None:
+        """Set up the test suite.
+
+        Setup: Retrieve application parameters from the configuration.
+        """
+        self.throughput_test_parameters: list[dict[str, int | float | str]] = (
+            self.config.throughput_test_parameters
+        )
+        self.buffer_sizes = ListWrapper(
+            [int(run["buff_size"]) for run in self.throughput_test_parameters]
+        )
+
+    def _print_stats(self, test_vals) -> None:
+        element_len = len("Gbps Target")
+        border_len = (element_len + 1) * (len(test_vals[0].items()))
+        print(f"{'Throughput Results'.center(border_len)}")
+        print("=" * border_len)
+        for k, v in test_vals[0].items():
+            print(f"|{k.title():<{element_len}}", end="")
+        print(f"|\n{'='*border_len}")
+        for test_val in test_vals:
+            for k, v in test_val.items():
+                print(f"|{v:<{element_len}}", end="")
+            print(f"|\n{'='*border_len}")
+
+    def _verify_throughput(
+        self, results: list[CryptodevResults]
+    ) -> list[dict[str, int | float | str]]:
+        result_list = []
+        for result in results:
+            result_dict = {}
+            parameters = list(
+                filter(
+                    lambda x: x["buff_size"] == result.buffer_size,
+                    self.throughput_test_parameters,
+                )
+            )[0]
+            test_result = True
+            for key, target_val in parameters.items():
+                if key == "buff_size" or key == "delta":
+                    result_dict[key] = target_val
+                    continue
+                if target_val > getattr(result, key):
+                    delta = round((1 - (getattr(result, key) / target_val)), 5)
+                    if delta > parameters["delta"]:
+                        test_result = False
+                else:
+                    delta = round((1 - target_val / getattr(result, key)), 5)
+                result_dict[key] = getattr(result, key)
+                result_dict[f"{key} target"] = target_val
+                result_dict[f"{key} delta"] = delta
+            result_dict["passed"] = "PASS" if test_result else "FAIL"
+            result_list.append(result_dict)
+        return result_list
+
+    @func_test
+    def qat_cipher_then_auth_aes_cbc_encrypt(self) -> None:
+        """Test throughput on crypto_qat device type with aes-cbc and 
sha2-256-hmac algorithms.
+
+        Steps:
+            * Create a Cryptodev application instance with crypto_qat devtype
+                and cipher_then_auth operation with aes-cbc and sha2-256-hmac 
algorithms
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.cipher_then_auth,
+            cipher_algo=CipherAlgorithm.aes_cbc,
+            cipher_op=EncryptDecryptSwitch.encrypt,
+            cipher_key_sz=16,
+            cipher_iv_sz=16,
+            auth_algo=AuthenticationAlgorithm.sha2_256_hmac,
+            auth_op=AuthenticationOpMode.generate,
+            auth_key_sz=64,
+            digest_sz=32,
+            total_ops=30_000_000,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=0))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"""Gbps was {result["gbps delta"]} below baseline
+                \nMOps was {result["mops delta"]} below baseline""",
+            )
+
+    @func_test
+    def qat_aead_aes_gcm_encrypt(self) -> None:
+        """Test throughput on a crypto_qat device type with aes-gcm algorithm.
+
+        Steps:
+            * Create a Cryptodev application instance with QAT device
+                and aead operation with aes-gcm algorithm
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.aead,
+            aead_aad_sz=16,
+            aead_key_sz=16,
+            aead_iv_sz=12,
+            aead_op=EncryptDecryptSwitch.encrypt,
+            aead_algo=AeadAlgName.aes_gcm,
+            digest_sz=16,
+            total_ops=30_000_000,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=1))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"Gbps and MOps were {result["gbps delta"]} below baseline",
+            )
+
+    @func_test
+    def qat_cipher_aes_docsisbpi_decrypt(self) -> None:
+        """Test throughput on a crypto_qat devtype with aes-docsibpi algorithm.
+
+        Steps:
+            * Create a Cryptodev application instance with QAT device
+                and cipher_only operation with aes-docsibpi algorithm
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.cipher_only,
+            cipher_algo=CipherAlgorithm.aes_docsisbpi,
+            cipher_op=EncryptDecryptSwitch.decrypt,
+            cipher_key_sz=32,
+            cipher_iv_sz=16,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+            total_ops=30_000_000,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=1))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"Gbps and MOps were {result["gbps delta"]} below baseline",
+            )
+
+    @func_test
+    def qat_cipher_aes_docsisbpi_encrypt(self) -> None:
+        """Test throughput on a crypto_qat device type with aes-docsibpi 
algorithm.
+
+        Steps:
+            * Create a Cryptodev application instance with crypto_qat device
+                and cipher_only operation with aes-docsibpi algorithm
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.cipher_only,
+            cipher_algo=CipherAlgorithm.aes_docsisbpi,
+            cipher_op=EncryptDecryptSwitch.encrypt,
+            cipher_key_sz=32,
+            cipher_iv_sz=16,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+            total_ops=30_000_000,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=3))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"Gbps and MOps were {result["gbps delta"]} below baseline",
+            )
+
+    @func_test
+    def qat_cipher_then_auth_kasumi_f8_encrypt(self) -> None:
+        """Test throughput on a crypto_qat device type with kasumi-f8 and 
kasumi-f9 algorithms.
+
+        Steps:
+            * Create a Cryptodev application instance with crypto_qat device
+                and cipher_then_auth operation with kasumi-f8 and kasumi-f9 
algorithms
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.cipher_then_auth,
+            cipher_algo=CipherAlgorithm.kasumi_f8,
+            cipher_op=EncryptDecryptSwitch.encrypt,
+            cipher_key_sz=16,
+            cipher_iv_sz=8,
+            auth_algo=AuthenticationAlgorithm.kasumi_f9,
+            auth_op=AuthenticationOpMode.generate,
+            auth_key_sz=16,
+            digest_sz=4,
+            total_ops=30_000_000,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=6))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"Gbps and MOps were {result["gbps delta"]} below baseline",
+            )
+
+    @func_test
+    def qat_cipher_then_auth_snow3g_uea2_encrpyt(self) -> None:
+        """Test throughput on a crypto_qat device type with snow3g-uea2 and 
snow3g-uia2 algorithms.
+
+        Steps:
+            * Create a Cryptodev application instance with crypto_qat device
+                and cipher_then_auth operation with snow3g-uea2 and 
snow3g-uia2 algorithms
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.cipher_then_auth,
+            cipher_algo=CipherAlgorithm.snow3g_uea2,
+            cipher_op=EncryptDecryptSwitch.encrypt,
+            cipher_key_sz=16,
+            cipher_iv_sz=16,
+            auth_algo=AuthenticationAlgorithm.snow3g_uia2,
+            auth_op=AuthenticationOpMode.generate,
+            auth_key_sz=16,
+            auth_iv_sz=16,
+            digest_sz=4,
+            total_ops=30_000_000,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=12))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"Gbps and MOps were {result["gbps delta"]} below baseline",
+            )
+
+    @func_test
+    def qat_cipher_then_auth_zuc_eea3_encrypt(self) -> None:
+        """Test throughput on a crypto_qat device type with zuc-eea3 and 
zuc-eia3 algorithms.
+
+        Steps:
+            * Create a Cryptodev application instance with crypto_qat device
+                and cipher_then_auth operation with zuc-eea3 and zuc-eia3 
algorithms
+            * Run the application and gather throughput statistics
+
+        Verify:
+            * Throughput results meet predefined baseline
+        """
+        app = Cryptodev(
+            ptest=TestType.throughput,
+            devtype=DeviceType.crypto_qat,
+            optype=OperationType.cipher_then_auth,
+            cipher_algo=CipherAlgorithm.zuc_eea3,
+            cipher_op=EncryptDecryptSwitch.encrypt,
+            cipher_key_sz=16,
+            cipher_iv_sz=16,
+            auth_algo=AuthenticationAlgorithm.zuc_eia3,
+            auth_op=AuthenticationOpMode.generate,
+            auth_key_sz=16,
+            auth_iv_sz=16,
+            digest_sz=4,
+            total_ops=30_000_000,
+            burst_sz=32,
+            buffer_sz=self.buffer_sizes,
+        )
+        results = self._verify_throughput(app.run_app(numvfs=12))
+        self._print_stats(results)
+        for result in results:
+            verify(
+                result["passed"] == "PASS",
+                f"Gbps and MOps were {result["gbps delta"]} below baseline",
+            )
-- 
2.50.1

Reply via email to