# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2019 Mellanox Technologies, Inc. All rights reserved. See COPYING file

"""
Test module for mlx5 packet pacing entry allocation.
"""

from pyverbs.providers.mlx5.mlx5dv import Mlx5PP, Mlx5Context, Mlx5DVContextAttr
from pyverbs.pyverbs_error import PyverbsRDMAError, PyverbsUserError
from pyverbs.providers.mlx5.mlx5_enums import mlx5dv_context_attr_flags, _MLX5DV_PP_ALLOC_FLAGS_DEDICATED_INDEX
from tests.mlx5_base import Mlx5RDMATestCase
import unittest
import struct
import errno


class Mlx5PPRes:
    def __init__(self, dev_name):
        try:
            mlx5dv_attr = Mlx5DVContextAttr(mlx5dv_context_attr_flags.MLX5DV_CONTEXT_FLAGS_DEVX)
            self.ctx = Mlx5Context(mlx5dv_attr, dev_name)
        except PyverbsUserError as ex:
            raise unittest.SkipTest('Could not open mlx5 context ({})'
                                    .format(str(ex)))
        except PyverbsRDMAError:
            raise unittest.SkipTest('Opening mlx5 DevX context is not supported')
        self.pps = []


class Mlx5PPTestCase(Mlx5RDMATestCase):
    def setUp(self):
        super().setUp()
        self.pp_res = Mlx5PPRes(self.dev_name)

    def test_pp_alloc(self):
        """
        Allocate two packet pacing entries with the same configuration. One of
        the entries is allocated with a dedicated index.
        Then verify that the indexes are different and free the entries.
        """
        # An arbitrary valid rate limit value (in kbps)
        rate_limit = struct.pack('>I', 100)
        try:
            self.pp_res.pps.append(Mlx5PP(self.pp_res.ctx, rate_limit))
            # Create a dedicated entry of the same previous configuration
            # and verify that it has a different index
            self.pp_res.pps.append(Mlx5PP(self.pp_res.ctx, rate_limit,
                                          flags=_MLX5DV_PP_ALLOC_FLAGS_DEDICATED_INDEX))
            self.assertNotEqual(self.pp_res.pps[0].index, self.pp_res.pps[1].index,
                                'Dedicated PP index is not unique')
            for pp in self.pp_res.pps:
                pp.close()
        except PyverbsRDMAError as ex:
            if ex.error_code == errno.EOPNOTSUPP or ex.error_code == errno.EPROTONOSUPPORT:
                raise unittest.SkipTest('Packet pacing entry allocation is not supported')
            raise ex
        finally:
            self.pp_res.ctx.close()
