def check()

in bugbug/models/component.py [0:0]


    def check(self):
        success = super().check()

        # Get the number of bugs per full component to fasten up the check
        bugs_number = get_product_component_count()

        # Check number 1, check that the most meaningful product components
        # still have at least a bug in this component. If the check is failing
        # that could mean that:
        # - A component has been renamed / removed
        # - A component is not used anymore by developers

        for product, component in self.meaningful_product_components:
            full_comp = f"{product}::{component}"

            if full_comp not in bugs_number.keys():
                logger.warning(
                    "Component %r of product %r doesn't exists, failure",
                    component,
                    product,
                )
                success = False

            elif bugs_number[full_comp] <= 0:
                logger.warning(
                    "Component %r of product %r have 0 bugs or less in it, failure",
                    component,
                    product,
                )
                success = False

        # Check number 2, check that conflated components in
        # CONFLATED_COMPONENTS match at least one component which has more
        # than 0 bugs

        for conflated_component in self.CONFLATED_COMPONENTS:
            matching_components = [
                full_comp
                for full_comp in bugs_number
                if full_comp.startswith(conflated_component)
            ]

            if not matching_components:
                logger.warning("%s doesn't match any component", conflated_component)
                success = False
                continue

            matching_components_values = [
                bugs_number[full_comp]
                for full_comp in matching_components
                if bugs_number[full_comp] > 0
            ]

            if not matching_components_values:
                logger.warning(
                    "%s should match at least one component with more than 0 bugs",
                    conflated_component,
                )
                success = False

        # Check number 3, check that values of CONFLATED_COMPONENTS_MAPPING
        # still exist as components and have more than 0 bugs

        for full_comp in self.CONFLATED_COMPONENTS_MAPPING.values():
            if full_comp not in bugs_number:
                logger.warning(
                    "%s from conflated component mapping doesn't exists, failure",
                    full_comp,
                )
                success = False
            elif bugs_number[full_comp] <= 0:
                logger.warning(
                    "%s from conflated component mapping have less than 1 bug, failure",
                    full_comp,
                )
                success = False

        # Check number 4, conflated components in CONFLATED_COMPONENTS either
        # exist as components or are in CONFLATED_COMPONENTS_MAPPING

        for conflated_component in self.CONFLATED_COMPONENTS:
            in_mapping = conflated_component in self.CONFLATED_COMPONENTS_MAPPING

            matching_components = [
                full_comp
                for full_comp in bugs_number
                if full_comp.startswith(conflated_component)
            ]

            if not (matching_components or in_mapping):
                logger.warning("It should be possible to map %s", conflated_component)
                success = False
                continue

        # Check number 5, there is no component with many bugs that is not in
        # meaningful_product_components

        # Recompute the meaningful components

        def generate_meaningful_tuples():
            for full_comp, count in bugs_number.items():
                product, component = full_comp.split("::", 1)

                if not self.is_meaningful(product, component):
                    continue

                if count > 0:
                    for i in range(count):
                        yield (product, component)

        meaningful_product_components = self.get_meaningful_product_components(
            generate_meaningful_tuples(), threshold_ratio=10
        )

        if not meaningful_product_components.issubset(
            self.meaningful_product_components
        ):
            logger.warning("Meaningful product components mismatch")

            new_meaningful_product_components = (
                meaningful_product_components.difference(
                    self.meaningful_product_components
                )
            )
            logger.info(
                "New meaningful product components %r",
                new_meaningful_product_components,
            )

            success = False

        return success