"""
Test to verify performance of PVC creation and deletion
for RBD, CephFS and RBD-Thick interfaces
"""
import time
import logging
import datetime
import pytest
import ocs_ci.ocs.exceptions as ex
import threading
import statistics
from concurrent.futures import ThreadPoolExecutor
from uuid import uuid4

from ocs_ci.framework.testlib import performance
from ocs_ci.ocs.perftests import PASTest
from ocs_ci.helpers import helpers, performance_lib
from ocs_ci.ocs import constants
from ocs_ci.helpers.helpers import get_full_test_logs_path
from ocs_ci.ocs.perfresult import PerfResult
from ocs_ci.framework import config


log = logging.getLogger(__name__)


class ResultsAnalyse(PerfResult):
    """
    This class generates results for all tests as one unit
    and saves them to an elastic search server on the cluster

    """

    def __init__(self, uuid, crd, full_log_path):
        """
        Initialize the object by reading some of the data from the CRD file and
        by connecting to the ES server and read all results from it.

        Args:
            uuid (str): the unique uid of the test
            crd (dict): dictionary with test parameters - the test yaml file
                        that modify it in the test itself.
            full_log_path (str): the path of the results files to be found

        """
        super(ResultsAnalyse, self).__init__(uuid, crd)
        self.new_index = "pvc_create_delete_fullres"
        self.full_log_path = full_log_path
        # make sure we have connection to the elastic search server
        self.es_connect()


@performance
class TestPVCCreationDeletionPerformance(PASTest):
    """
    Test to verify performance of PVC creation and deletion
    """

    def setup(self):
        """
        Setting up test parameters
        """
        log.info("Starting the test setup")
        super(TestPVCCreationDeletionPerformance, self).setup()
        self.benchmark_name = "PVC_Creation-Deletion"
        self.uuid = uuid4().hex
        self.crd_data = {
            "spec": {
                "test_user": "Homer simpson",
                "clustername": "test_cluster",
                "elasticsearch": {
                    "server": config.PERF.get("production_es_server"),
                    "port": config.PERF.get("production_es_port"),
                    "url": f"http://{config.PERF.get('production_es_server')}:{config.PERF.get('production_es_port')}",
                },
            }
        }
        if self.dev_mode:
            self.crd_data["spec"]["elasticsearch"] = {
                "server": config.PERF.get("dev_es_server"),
                "port": config.PERF.get("dev_es_port"),
                "url": f"http://{config.PERF.get('dev_es_server')}:{config.PERF.get('dev_es_port')}",
            }

    @pytest.fixture()
    def base_setup(self, interface_type, storageclass_factory, pod_factory):
        """
        A setup phase for the test

        Args:
            interface_type: A fixture to iterate over ceph interfaces
            storageclass_factory: A fixture to create everything needed for a
                storageclass
            pod_factory: A fixture to create new pod
        """
        self.interface = interface_type
        if self.interface == constants.CEPHBLOCKPOOL_THICK:
            self.sc_obj = storageclass_factory(
                interface=constants.CEPHBLOCKPOOL,
                new_rbd_pool=True,
                rbd_thick_provision=True,
            )
        else:
            self.sc_obj = storageclass_factory(self.interface)
        self.pod_factory = pod_factory

    @pytest.fixture()
    def namespace(self, project_factory):
        """
        Create a new project
        """
        proj_obj = project_factory()
        self.namespace = proj_obj.namespace

    def init_full_results(self, full_results):
        """
        Initialize the full results object which will send to the ES server

        Args:
            full_results (obj): an empty FIOResultsAnalyse object

        Returns:
            FIOResultsAnalyse (obj): the input object fill with data

        """
        for key in self.environment:
            full_results.add_key(key, self.environment[key])
        full_results.add_key("storageclass", self.sc)
        full_results.add_key("index", full_results.new_index)
        return full_results

    @pytest.mark.parametrize(
        argnames=["interface_type", "pvc_size"],
        argvalues=[
            pytest.param(
                *[constants.CEPHBLOCKPOOL, "5Gi"],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHBLOCKPOOL, "15Gi"],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHBLOCKPOOL, "25Gi"],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHFILESYSTEM, "5Gi"],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHFILESYSTEM, "15Gi"],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHFILESYSTEM, "25Gi"],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHBLOCKPOOL_THICK, "5Gi"],
                marks=[pytest.mark.performance_extended],
            ),
            pytest.param(
                *[constants.CEPHBLOCKPOOL_THICK, "15Gi"],
                marks=[pytest.mark.performance_extended],
            ),
            pytest.param(
                *[constants.CEPHBLOCKPOOL_THICK, "25Gi"],
                marks=[pytest.mark.performance_extended],
            ),
        ],
    )
    @pytest.mark.usefixtures(base_setup.__name__)
    def test_pvc_creation_deletion_measurement_performance(
        self, teardown_factory, pvc_size
    ):
        """
        Measuring PVC creation and deletion times for pvc samples
        Verifying that those times are within the required limits
        """

        # Getting the full path for the test logs
        self.full_log_path = get_full_test_logs_path(cname=self)
        if self.interface == constants.CEPHBLOCKPOOL:
            self.sc = "RBD"
        elif self.interface == constants.CEPHFILESYSTEM:
            self.sc = "CephFS"
        elif self.interface == constants.CEPHBLOCKPOOL_THICK:
            self.sc = "RBD-Thick"
        self.full_log_path += f"-{self.sc}-{pvc_size}"
        log.info(f"Logs file path name is : {self.full_log_path}")

        self.start_time = time.strftime("%Y-%m-%dT%H:%M:%SGMT", time.gmtime())

        self.get_env_info()

        # Initialize the results doc file.
        self.full_results = self.init_full_results(
            ResultsAnalyse(self.uuid, self.crd_data, self.full_log_path)
        )
        self.full_results.add_key("pvc_size", pvc_size)
        num_of_samples = 5
        accepted_creation_time = (
            600 if self.interface == constants.CEPHBLOCKPOOL_THICK else 1
        )

        # accepted deletion time for RBD is 1 sec, for CephFS is 2 secs and for RBD Thick is 5 secs
        if self.interface == constants.CEPHFILESYSTEM:
            accepted_deletion_time = 2
        elif self.interface == constants.CEPHBLOCKPOOL:
            accepted_deletion_time = 1
        else:
            accepted_deletion_time = 5

        self.full_results.add_key("samples", num_of_samples)

        accepted_creation_deviation_percent = 50
        accepted_deletion_deviation_percent = 50

        creation_time_measures = []
        deletion_time_measures = []
        msg_prefix = f"Interface: {self.interface}, PVC size: {pvc_size}."

        for i in range(num_of_samples):
            logging.info(f"{msg_prefix} Start creating PVC number {i + 1}.")
            start_time = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
            pvc_obj = helpers.create_pvc(sc_name=self.sc_obj.name, size=pvc_size)
            timeout = 600 if self.interface == constants.CEPHBLOCKPOOL_THICK else 60
            helpers.wait_for_resource_state(
                pvc_obj, constants.STATUS_BOUND, timeout=timeout
            )
            pvc_obj.reload()

            creation_time = performance_lib.measure_pvc_creation_time(
                self.interface, pvc_obj.name, start_time
            )

            logging.info(
                f"{msg_prefix} PVC number {i + 1} was created in {creation_time} seconds."
            )
            if creation_time > accepted_creation_time:
                raise ex.PerformanceException(
                    f"{msg_prefix} PVC creation time is {creation_time} and is greater than "
                    f"{accepted_creation_time} seconds."
                )
            creation_time_measures.append(creation_time)

            pv_name = pvc_obj.backed_pv
            pvc_reclaim_policy = pvc_obj.reclaim_policy

            pod_obj = self.write_file_on_pvc(pvc_obj)
            pod_obj.delete(wait=True)
            teardown_factory(pvc_obj)
            logging.info(f"{msg_prefix} Start deleting PVC number {i + 1}")
            if pvc_reclaim_policy == constants.RECLAIM_POLICY_DELETE:
                pvc_obj.delete()
                pvc_obj.ocp.wait_for_delete(pvc_obj.name)
                helpers.validate_pv_delete(pvc_obj.backed_pv)
                deletion_time = helpers.measure_pvc_deletion_time(
                    self.interface, pv_name
                )
                logging.info(
                    f"{msg_prefix} PVC number {i + 1} was deleted in {deletion_time} seconds."
                )
                if deletion_time > accepted_deletion_time:
                    raise ex.PerformanceException(
                        f"{msg_prefix} PVC deletion time is {deletion_time} and is greater than "
                        f"{accepted_deletion_time} seconds."
                    )
                deletion_time_measures.append(deletion_time)
            else:
                logging.info(
                    f"Reclaim policy of the PVC {pvc_obj.name} is not Delete;"
                    f" therefore not measuring deletion time for this PVC."
                )

        creation_average = self.process_time_measurements(
            "creation",
            creation_time_measures,
            accepted_creation_deviation_percent,
            msg_prefix,
        )
        self.full_results.add_key("creation-time", creation_average)
        deletion_average = self.process_time_measurements(
            "deletion",
            deletion_time_measures,
            accepted_deletion_deviation_percent,
            msg_prefix,
        )
        self.full_results.add_key("deletion-time", deletion_average)
        self.full_results.all_results["creation"] = creation_time_measures
        self.full_results.all_results["deletion"] = deletion_time_measures
        self.end_time = time.strftime("%Y-%m-%dT%H:%M:%SGMT", time.gmtime())
        self.full_results.add_key(
            "test_time", {"start": self.start_time, "end": self.end_time}
        )
        self.full_results.es_write()
        log.info(f"The Result can be found at : {self.full_results.results_link()}")

    def process_time_measurements(
        self, action_name, time_measures, accepted_deviation_percent, msg_prefix
    ):
        """
           Analyses the given time measured. If the standard deviation of these times is bigger than the
           provided accepted deviation percent, fails the test

        Args:
            action_name (str): Name of the action for which these measurements were collected; used for the logging
            time_measures (list of floats): A list of time measurements
            accepted_deviation_percent (int): Accepted deviation percent to which computed standard deviation may be
                    compared
            msg_prefix (str) : A string for comprehensive logging

        Returns:
            (float) The average value of the provided time measurements
        """
        average = statistics.mean(time_measures)
        log.info(
            f"{msg_prefix} The average {action_name} time for the sampled {len(time_measures)} "
            f"PVCs is {average} seconds."
        )

        if self.interface == constants.CEPHBLOCKPOOL_THICK:
            st_deviation = statistics.stdev(time_measures)
            st_deviation_percent = st_deviation / average * 100.0
            if st_deviation_percent > accepted_deviation_percent:
                log.error(
                    f"{msg_prefix} The standard deviation percent for {action_name} of {len(time_measures)} sampled "
                    f"PVCs is {st_deviation_percent}% which is bigger than accepted {accepted_deviation_percent}."
                )
            else:
                log.info(
                    f"{msg_prefix} The standard deviation percent for {action_name} of {len(time_measures)} sampled "
                    f"PVCs is {st_deviation_percent}% and is within the accepted range."
                )
            self.full_results.add_key(
                f"{action_name}_deviation_pct", st_deviation_percent
            )

        return average

    def write_file_on_pvc(self, pvc_obj, filesize=1):
        """
        Writes a file on given PVC
        Args:
            pvc_obj: PVC object to write a file on
            filesize: size of file to write (in GB - default is 1GB)

        Returns:
            Pod on this pvc on which the file was written
        """
        pod_obj = self.pod_factory(
            interface=self.interface, pvc=pvc_obj, status=constants.STATUS_RUNNING
        )

        # filesize to be written is always 1 GB
        file_size = f"{int(filesize * 1024)}M"

        log.info(f"Starting IO on the POD {pod_obj.name}")
        # Going to run only write IO
        pod_obj.fillup_fs(size=file_size, fio_filename=f"{pod_obj.name}_file")

        # Wait for the fio to finish
        fio_result = pod_obj.get_fio_results()
        err_count = fio_result.get("jobs")[0].get("error")
        assert (
            err_count == 0
        ), f"IO error on pod {pod_obj.name}. FIO result: {fio_result}"
        log.info("IO on the PVC has finished")
        return pod_obj

    @pytest.mark.parametrize(
        argnames=["interface_type"],
        argvalues=[
            pytest.param(
                *[constants.CEPHBLOCKPOOL],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHFILESYSTEM],
                marks=[pytest.mark.performance],
            ),
            pytest.param(
                *[constants.CEPHBLOCKPOOL_THICK],
                marks=[pytest.mark.performance_extended],
            ),
        ],
    )
    @pytest.mark.usefixtures(base_setup.__name__)
    @pytest.mark.usefixtures(namespace.__name__)
    @pytest.mark.polarion_id("OCS-2618")
    def test_multiple_pvc_deletion_measurement_performance(self, teardown_factory):
        """
        Measuring PVC deletion time of 120 PVCs in 180 seconds

        Args:
            teardown_factory: A fixture used when we want a new resource that was created during the tests
                               to be removed in the teardown phase.
        Returns:

        """
        number_of_pvcs = 120
        pvc_size = "1Gi"
        msg_prefix = f"Interface: {self.interface}, PVC size: {pvc_size}."

        log.info(f"{msg_prefix} Start creating new 120 PVCs")

        pvc_objs, _ = helpers.create_multiple_pvcs(
            sc_name=self.sc_obj.name,
            namespace=self.namespace,
            number_of_pvc=number_of_pvcs,
            size=pvc_size,
            burst=True,
        )

        for pvc_obj in pvc_objs:
            pvc_obj.reload()
            teardown_factory(pvc_obj)

        timeout = 600 if self.interface == constants.CEPHBLOCKPOOL_THICK else 60
        with ThreadPoolExecutor(max_workers=5) as executor:
            for pvc_obj in pvc_objs:
                executor.submit(
                    helpers.wait_for_resource_state,
                    pvc_obj,
                    constants.STATUS_BOUND,
                    timeout=timeout,
                )
                executor.submit(pvc_obj.reload)

        pod_objs = []
        for pvc_obj in pvc_objs:
            pod_obj = self.write_file_on_pvc(pvc_obj, 0.3)
            pod_objs.append(pod_obj)

        # Get pvc_name, require pvc_name to fetch deletion time data from log
        threads = list()
        for pvc_obj in pvc_objs:
            process = threading.Thread(target=pvc_obj.reload)
            process.start()
            threads.append(process)
        for process in threads:
            process.join()

        pvc_name_list, pv_name_list = ([] for i in range(2))
        threads = list()
        for pvc_obj in pvc_objs:
            process1 = threading.Thread(target=pvc_name_list.append(pvc_obj.name))
            process2 = threading.Thread(target=pv_name_list.append(pvc_obj.backed_pv))
            process1.start()
            process2.start()
            threads.append(process1)
            threads.append(process2)
        for process in threads:
            process.join()
        log.info(f"{msg_prefix} Preparing to delete 120 PVC")

        # Delete PVC
        for pvc_obj, pod_obj in zip(pvc_objs, pod_objs):
            pod_obj.delete(wait=True)
            pvc_obj.delete()
            pvc_obj.ocp.wait_for_delete(pvc_obj.name)

        # Get PVC deletion time
        pvc_deletion_time = helpers.measure_pv_deletion_time_bulk(
            interface=self.interface, pv_name_list=pv_name_list
        )
        log.info(
            f"{msg_prefix} {number_of_pvcs} bulk deletion time is {pvc_deletion_time}"
        )

        # accepted deletion time is 2 secs for each PVC
        accepted_pvc_deletion_time = number_of_pvcs * 2

        for del_time in pvc_deletion_time.values():
            if del_time > accepted_pvc_deletion_time:
                raise ex.PerformanceException(
                    f"{msg_prefix} {number_of_pvcs} PVCs deletion time is {pvc_deletion_time.values()} and is "
                    f"greater than {accepted_pvc_deletion_time} seconds"
                )

        logging.info(f"{msg_prefix} {number_of_pvcs} PVCs deletion times are:")
        for name, a_time in pvc_deletion_time.items():
            logging.info(f"{name} deletion time is: {a_time} seconds")

[((629, 656), 'logging.getLogger', 'logging.getLogger', (['__name__'], {}), '(__name__)\n', (646, 656), False, 'import logging\n'), ((2792, 2808), 'pytest.fixture', 'pytest.fixture', ([], {}), '()\n', (2806, 2808), False, 'import pytest\n'), ((3602, 3618), 'pytest.fixture', 'pytest.fixture', ([], {}), '()\n', (3616, 3618), False, 'import pytest\n'), ((5799, 5843), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['base_setup.__name__'], {}), '(base_setup.__name__)\n', (5822, 5843), False, 'import pytest\n'), ((14825, 14869), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['base_setup.__name__'], {}), '(base_setup.__name__)\n', (14848, 14869), False, 'import pytest\n'), ((14875, 14918), 'pytest.mark.usefixtures', 'pytest.mark.usefixtures', (['namespace.__name__'], {}), '(namespace.__name__)\n', (14898, 14918), False, 'import pytest\n'), ((14924, 14959), 'pytest.mark.polarion_id', 'pytest.mark.polarion_id', (['"""OCS-2618"""'], {}), "('OCS-2618')\n", (14947, 14959), False, 'import pytest\n'), ((6188, 6223), 'ocs_ci.helpers.helpers.get_full_test_logs_path', 'get_full_test_logs_path', ([], {'cname': 'self'}), '(cname=self)\n', (6211, 6223), False, 'from ocs_ci.helpers.helpers import get_full_test_logs_path\n'), ((12100, 12130), 'statistics.mean', 'statistics.mean', (['time_measures'], {}), '(time_measures)\n', (12115, 12130), False, 'import statistics\n'), ((15554, 15696), 'ocs_ci.helpers.helpers.create_multiple_pvcs', 'helpers.create_multiple_pvcs', ([], {'sc_name': 'self.sc_obj.name', 'namespace': 'self.namespace', 'number_of_pvc': 'number_of_pvcs', 'size': 'pvc_size', 'burst': '(True)'}), '(sc_name=self.sc_obj.name, namespace=self.\n    namespace, number_of_pvc=number_of_pvcs, size=pvc_size, burst=True)\n', (15582, 15696), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((17583, 17677), 'ocs_ci.helpers.helpers.measure_pv_deletion_time_bulk', 'helpers.measure_pv_deletion_time_bulk', ([], {'interface': 'self.interface', 'pv_name_list': 'pv_name_list'}), '(interface=self.interface,\n    pv_name_list=pv_name_list)\n', (17620, 17677), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((18290, 18361), 'logging.info', 'logging.info', (['f"""{msg_prefix} {number_of_pvcs} PVCs deletion times are:"""'], {}), "(f'{msg_prefix} {number_of_pvcs} PVCs deletion times are:')\n", (18302, 18361), False, 'import logging\n'), ((1984, 1991), 'uuid.uuid4', 'uuid4', ([], {}), '()\n', (1989, 1991), False, 'from uuid import uuid4\n'), ((6677, 6690), 'time.gmtime', 'time.gmtime', ([], {}), '()\n', (6688, 6690), False, 'import time\n'), ((7807, 7871), 'logging.info', 'logging.info', (['f"""{msg_prefix} Start creating PVC number {i + 1}."""'], {}), "(f'{msg_prefix} Start creating PVC number {i + 1}.')\n", (7819, 7871), False, 'import logging\n'), ((7977, 8036), 'ocs_ci.helpers.helpers.create_pvc', 'helpers.create_pvc', ([], {'sc_name': 'self.sc_obj.name', 'size': 'pvc_size'}), '(sc_name=self.sc_obj.name, size=pvc_size)\n', (7995, 8036), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((8134, 8220), 'ocs_ci.helpers.helpers.wait_for_resource_state', 'helpers.wait_for_resource_state', (['pvc_obj', 'constants.STATUS_BOUND'], {'timeout': 'timeout'}), '(pvc_obj, constants.STATUS_BOUND, timeout=\n    timeout)\n', (8165, 8220), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((8304, 8391), 'ocs_ci.helpers.performance_lib.measure_pvc_creation_time', 'performance_lib.measure_pvc_creation_time', (['self.interface', 'pvc_obj.name', 'start_time'], {}), '(self.interface, pvc_obj.name,\n    start_time)\n', (8345, 8391), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((8431, 8524), 'logging.info', 'logging.info', (['f"""{msg_prefix} PVC number {i + 1} was created in {creation_time} seconds."""'], {}), "(\n    f'{msg_prefix} PVC number {i + 1} was created in {creation_time} seconds.')\n", (8443, 8524), False, 'import logging\n'), ((9118, 9181), 'logging.info', 'logging.info', (['f"""{msg_prefix} Start deleting PVC number {i + 1}"""'], {}), "(f'{msg_prefix} Start deleting PVC number {i + 1}')\n", (9130, 9181), False, 'import logging\n'), ((11005, 11018), 'time.gmtime', 'time.gmtime', ([], {}), '()\n', (11016, 11018), False, 'import time\n'), ((12386, 12417), 'statistics.stdev', 'statistics.stdev', (['time_measures'], {}), '(time_measures)\n', (12402, 12417), False, 'import statistics\n'), ((15959, 15992), 'concurrent.futures.ThreadPoolExecutor', 'ThreadPoolExecutor', ([], {'max_workers': '(5)'}), '(max_workers=5)\n', (15977, 15992), False, 'from concurrent.futures import ThreadPoolExecutor\n'), ((16616, 16655), 'threading.Thread', 'threading.Thread', ([], {'target': 'pvc_obj.reload'}), '(target=pvc_obj.reload)\n', (16632, 16655), False, 'import threading\n'), ((18429, 18487), 'logging.info', 'logging.info', (['f"""{name} deletion time is: {a_time} seconds"""'], {}), "(f'{name} deletion time is: {a_time} seconds')\n", (18441, 18487), False, 'import logging\n'), ((2580, 2612), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""dev_es_server"""'], {}), "('dev_es_server')\n", (2595, 2612), False, 'from ocs_ci.framework import config\n'), ((2638, 2668), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""dev_es_port"""'], {}), "('dev_es_port')\n", (2653, 2668), False, 'from ocs_ci.framework import config\n'), ((8627, 8768), 'ocs_ci.ocs.exceptions.PerformanceException', 'ex.PerformanceException', (['f"""{msg_prefix} PVC creation time is {creation_time} and is greater than {accepted_creation_time} seconds."""'], {}), "(\n    f'{msg_prefix} PVC creation time is {creation_time} and is greater than {accepted_creation_time} seconds.'\n    )\n", (8650, 8768), True, 'import ocs_ci.ocs.exceptions as ex\n'), ((9359, 9404), 'ocs_ci.helpers.helpers.validate_pv_delete', 'helpers.validate_pv_delete', (['pvc_obj.backed_pv'], {}), '(pvc_obj.backed_pv)\n', (9385, 9404), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((9437, 9495), 'ocs_ci.helpers.helpers.measure_pvc_deletion_time', 'helpers.measure_pvc_deletion_time', (['self.interface', 'pv_name'], {}), '(self.interface, pv_name)\n', (9470, 9495), False, 'from ocs_ci.helpers import helpers, performance_lib\n'), ((9550, 9643), 'logging.info', 'logging.info', (['f"""{msg_prefix} PVC number {i + 1} was deleted in {deletion_time} seconds."""'], {}), "(\n    f'{msg_prefix} PVC number {i + 1} was deleted in {deletion_time} seconds.')\n", (9562, 9643), False, 'import logging\n'), ((10063, 10197), 'logging.info', 'logging.info', (['f"""Reclaim policy of the PVC {pvc_obj.name} is not Delete; therefore not measuring deletion time for this PVC."""'], {}), "(\n    f'Reclaim policy of the PVC {pvc_obj.name} is not Delete; therefore not measuring deletion time for this PVC.'\n    )\n", (10075, 10197), False, 'import logging\n'), ((4466, 4551), 'pytest.param', 'pytest.param', (["*[constants.CEPHBLOCKPOOL, '5Gi']"], {'marks': '[pytest.mark.performance]'}), "(*[constants.CEPHBLOCKPOOL, '5Gi'], marks=[pytest.mark.performance]\n    )\n", (4478, 4551), False, 'import pytest\n'), ((4607, 4693), 'pytest.param', 'pytest.param', (["*[constants.CEPHBLOCKPOOL, '15Gi']"], {'marks': '[pytest.mark.performance]'}), "(*[constants.CEPHBLOCKPOOL, '15Gi'], marks=[pytest.mark.\n    performance])\n", (4619, 4693), False, 'import pytest\n'), ((4749, 4835), 'pytest.param', 'pytest.param', (["*[constants.CEPHBLOCKPOOL, '25Gi']"], {'marks': '[pytest.mark.performance]'}), "(*[constants.CEPHBLOCKPOOL, '25Gi'], marks=[pytest.mark.\n    performance])\n", (4761, 4835), False, 'import pytest\n'), ((4891, 4977), 'pytest.param', 'pytest.param', (["*[constants.CEPHFILESYSTEM, '5Gi']"], {'marks': '[pytest.mark.performance]'}), "(*[constants.CEPHFILESYSTEM, '5Gi'], marks=[pytest.mark.\n    performance])\n", (4903, 4977), False, 'import pytest\n'), ((5033, 5120), 'pytest.param', 'pytest.param', (["*[constants.CEPHFILESYSTEM, '15Gi']"], {'marks': '[pytest.mark.performance]'}), "(*[constants.CEPHFILESYSTEM, '15Gi'], marks=[pytest.mark.\n    performance])\n", (5045, 5120), False, 'import pytest\n'), ((5176, 5263), 'pytest.param', 'pytest.param', (["*[constants.CEPHFILESYSTEM, '25Gi']"], {'marks': '[pytest.mark.performance]'}), "(*[constants.CEPHFILESYSTEM, '25Gi'], marks=[pytest.mark.\n    performance])\n", (5188, 5263), False, 'import pytest\n'), ((5319, 5419), 'pytest.param', 'pytest.param', (["*[constants.CEPHBLOCKPOOL_THICK, '5Gi']"], {'marks': '[pytest.mark.performance_extended]'}), "(*[constants.CEPHBLOCKPOOL_THICK, '5Gi'], marks=[pytest.mark.\n    performance_extended])\n", (5331, 5419), False, 'import pytest\n'), ((5475, 5576), 'pytest.param', 'pytest.param', (["*[constants.CEPHBLOCKPOOL_THICK, '15Gi']"], {'marks': '[pytest.mark.performance_extended]'}), "(*[constants.CEPHBLOCKPOOL_THICK, '15Gi'], marks=[pytest.mark.\n    performance_extended])\n", (5487, 5576), False, 'import pytest\n'), ((5632, 5733), 'pytest.param', 'pytest.param', (["*[constants.CEPHBLOCKPOOL_THICK, '25Gi']"], {'marks': '[pytest.mark.performance_extended]'}), "(*[constants.CEPHBLOCKPOOL_THICK, '25Gi'], marks=[pytest.mark.\n    performance_extended])\n", (5644, 5733), False, 'import pytest\n'), ((14397, 14470), 'pytest.param', 'pytest.param', (['*[constants.CEPHBLOCKPOOL]'], {'marks': '[pytest.mark.performance]'}), '(*[constants.CEPHBLOCKPOOL], marks=[pytest.mark.performance])\n', (14409, 14470), False, 'import pytest\n'), ((14531, 14605), 'pytest.param', 'pytest.param', (['*[constants.CEPHFILESYSTEM]'], {'marks': '[pytest.mark.performance]'}), '(*[constants.CEPHFILESYSTEM], marks=[pytest.mark.performance])\n', (14543, 14605), False, 'import pytest\n'), ((14666, 14759), 'pytest.param', 'pytest.param', (['*[constants.CEPHBLOCKPOOL_THICK]'], {'marks': '[pytest.mark.performance_extended]'}), '(*[constants.CEPHBLOCKPOOL_THICK], marks=[pytest.mark.\n    performance_extended])\n', (14678, 14759), False, 'import pytest\n'), ((2202, 2241), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""production_es_server"""'], {}), "('production_es_server')\n", (2217, 2241), False, 'from ocs_ci.framework import config\n'), ((2271, 2308), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""production_es_port"""'], {}), "('production_es_port')\n", (2286, 2308), False, 'from ocs_ci.framework import config\n'), ((7897, 7923), 'datetime.datetime.utcnow', 'datetime.datetime.utcnow', ([], {}), '()\n', (7921, 7923), False, 'import datetime\n'), ((9762, 9903), 'ocs_ci.ocs.exceptions.PerformanceException', 'ex.PerformanceException', (['f"""{msg_prefix} PVC deletion time is {deletion_time} and is greater than {accepted_deletion_time} seconds."""'], {}), "(\n    f'{msg_prefix} PVC deletion time is {deletion_time} and is greater than {accepted_deletion_time} seconds.'\n    )\n", (9785, 9903), True, 'import ocs_ci.ocs.exceptions as ex\n'), ((2703, 2735), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""dev_es_server"""'], {}), "('dev_es_server')\n", (2718, 2735), False, 'from ocs_ci.framework import config\n'), ((2738, 2768), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""dev_es_port"""'], {}), "('dev_es_port')\n", (2753, 2768), False, 'from ocs_ci.framework import config\n'), ((2347, 2386), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""production_es_server"""'], {}), "('production_es_server')\n", (2362, 2386), False, 'from ocs_ci.framework import config\n'), ((2389, 2426), 'ocs_ci.framework.config.PERF.get', 'config.PERF.get', (['"""production_es_port"""'], {}), "('production_es_port')\n", (2404, 2426), False, 'from ocs_ci.framework import config\n')]