mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
120 lines
4.6 KiB
Python
120 lines
4.6 KiB
Python
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from prowler.providers.common.builtin import (
|
|
builtin_check_module,
|
|
is_builtin_check,
|
|
is_builtin_provider,
|
|
)
|
|
|
|
|
|
class TestBuiltinCheckModule:
|
|
def test_builds_the_sdk_module_path(self):
|
|
assert (
|
|
builtin_check_module("aws", "ec2", "ec2_instance_public_ip")
|
|
== "prowler.providers.aws.services.ec2.ec2_instance_public_ip.ec2_instance_public_ip"
|
|
)
|
|
|
|
|
|
class TestIsBuiltinProvider:
|
|
def test_true_for_a_provider_shipped_with_the_sdk(self):
|
|
assert is_builtin_provider("aws") is True
|
|
|
|
def test_false_for_a_provider_that_lives_in_a_plugin(self):
|
|
# No `prowler.providers.acme` package: find_spec raises on the absent
|
|
# parent rather than returning None, and the helper absorbs it.
|
|
assert is_builtin_provider("acme") is False
|
|
|
|
|
|
class TestIsBuiltinCheck:
|
|
def test_true_for_a_check_shipped_with_the_sdk(self):
|
|
assert is_builtin_check("aws", "ec2", "ec2_instance_public_ip") is True
|
|
|
|
def test_false_for_an_external_check_on_a_builtin_provider(self):
|
|
"""The case that made every plug-in check unresolvable.
|
|
|
|
`prowler.providers.aws.services.ec2` exists, so the naive probe gets
|
|
far enough to try importing the check package as a parent — and that
|
|
package only exists inside the plug-in. find_spec raises instead of
|
|
returning None.
|
|
"""
|
|
assert (
|
|
is_builtin_check("aws", "ec2", "ec2_acme_instance_has_owner_tag") is False
|
|
)
|
|
|
|
def test_false_for_a_service_that_does_not_exist(self):
|
|
assert (
|
|
is_builtin_check("aws", "acmeservice", "acmeservice_thing_is_fine") is False
|
|
)
|
|
|
|
def test_false_for_an_external_provider(self):
|
|
assert (
|
|
is_builtin_check("acme", "inventory", "inventory_item_has_owner") is False
|
|
)
|
|
|
|
def test_reraises_when_a_builtin_checks_own_dependency_is_missing(self):
|
|
"""A broken import must not read as "the check is not built-in".
|
|
|
|
Collapsing the two would turn a missing dependency into a silent
|
|
"check not found", which is the failure mode this probe exists to
|
|
avoid.
|
|
"""
|
|
module = builtin_check_module("aws", "ec2", "ec2_instance_public_ip")
|
|
|
|
with patch(
|
|
"prowler.providers.common.builtin.importlib.util.find_spec",
|
|
side_effect=ModuleNotFoundError("No module named 'boto3'", name="boto3"),
|
|
):
|
|
with pytest.raises(ModuleNotFoundError):
|
|
is_builtin_check("aws", "ec2", "ec2_instance_public_ip")
|
|
|
|
# Sanity: the same error naming the check's own path is absorbed.
|
|
with patch(
|
|
"prowler.providers.common.builtin.importlib.util.find_spec",
|
|
side_effect=ModuleNotFoundError(f"No module named '{module}'", name=module),
|
|
):
|
|
assert is_builtin_check("aws", "ec2", "ec2_instance_public_ip") is False
|
|
|
|
def test_reraises_when_missing_module_name_is_only_a_textual_prefix(self):
|
|
"""A sibling module prefix must not read as the check's missing parent."""
|
|
sibling_prefix = "prowler.providers.aws.services.ec2.ec2"
|
|
|
|
with patch(
|
|
"prowler.providers.common.builtin.importlib.util.find_spec",
|
|
side_effect=ModuleNotFoundError(
|
|
f"No module named '{sibling_prefix}'", name=sibling_prefix
|
|
),
|
|
):
|
|
with pytest.raises(ModuleNotFoundError):
|
|
is_builtin_check("aws", "ec2", "ec2_instance_public_ip")
|
|
|
|
@pytest.mark.parametrize(
|
|
"error",
|
|
[
|
|
ValueError("namespace package edge case"),
|
|
],
|
|
ids=["value_error"],
|
|
)
|
|
def test_false_when_find_spec_raises_value_error(self, error):
|
|
"""Mirrors the guard `is_builtin_provider` already carries.
|
|
|
|
`find_spec` can fail for reasons that are not "the module is absent" —
|
|
a namespace-package edge case raises ValueError. That does not say the
|
|
check ships with the SDK, so it falls through to the entry points.
|
|
"""
|
|
with patch(
|
|
"prowler.providers.common.builtin.importlib.util.find_spec",
|
|
side_effect=error,
|
|
):
|
|
assert is_builtin_check("aws", "ec2", "ec2_instance_public_ip") is False
|
|
|
|
def test_reraises_plain_import_error(self):
|
|
"""A plain ImportError can indicate a broken built-in check import."""
|
|
with patch(
|
|
"prowler.providers.common.builtin.importlib.util.find_spec",
|
|
side_effect=ImportError("partially initialised"),
|
|
):
|
|
with pytest.raises(ImportError, match="partially initialised"):
|
|
is_builtin_check("aws", "ec2", "ec2_instance_public_ip")
|