Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Make import-related tests stable #3548

Merged
merged 3 commits into from
Sep 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 27 additions & 23 deletions tests/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from sentry_sdk.integrations import (
_AUTO_ENABLING_INTEGRATIONS,
_DEFAULT_INTEGRATIONS,
DidNotEnable,
Integration,
setup_integrations,
)
Expand All @@ -40,18 +41,6 @@
from sentry_sdk.tracing_utils import has_tracing_enabled


def _redis_installed(): # type: () -> bool
"""
Determines whether Redis is installed.
"""
try:
import redis # noqa: F401
except ImportError:
return False

return True


class NoOpIntegration(Integration):
"""
A simple no-op integration for testing purposes.
Expand Down Expand Up @@ -90,20 +79,35 @@ def error_processor(event, exc_info):
assert event["exception"]["values"][0]["value"] == "aha! whatever"


class ModuleImportErrorSimulator:
def __init__(self, modules, error_cls=DidNotEnable):
self.modules = modules
self.error_cls = error_cls
for sys_module in list(sys.modules.keys()):
if any(sys_module.startswith(module) for module in modules):
del sys.modules[sys_module]

def find_spec(self, fullname, _path, _target=None):
if fullname in self.modules:
raise self.error_cls("Test import failure for %s" % fullname)

def __enter__(self):
# WARNING: We need to be first to avoid pytest messing with local imports
sys.meta_path.insert(0, self)

def __exit__(self, *_args):
sys.meta_path.remove(self)


def test_auto_enabling_integrations_catches_import_error(sentry_init, caplog):
caplog.set_level(logging.DEBUG)
redis_index = _AUTO_ENABLING_INTEGRATIONS.index(
"sentry_sdk.integrations.redis.RedisIntegration"
) # noqa: N806

sentry_init(auto_enabling_integrations=True, debug=True)
with ModuleImportErrorSimulator(
[i.rsplit(".", 1)[0] for i in _AUTO_ENABLING_INTEGRATIONS]
):
sentry_init(auto_enabling_integrations=True, debug=True)
sentrivana marked this conversation as resolved.
Show resolved Hide resolved

for import_string in _AUTO_ENABLING_INTEGRATIONS:
# Ignore redis in the test case, because it does not raise a DidNotEnable
# exception on import; rather, it raises the exception upon enabling.
if _AUTO_ENABLING_INTEGRATIONS[redis_index] == import_string:
continue

assert any(
record.message.startswith(
"Did not import default integration {}:".format(import_string)
Expand Down Expand Up @@ -883,9 +887,9 @@ def test_functions_to_trace_with_class(sentry_init, capture_events):
assert event["spans"][1]["description"] == "tests.test_basics.WorldGreeter.greet"


@pytest.mark.skipif(_redis_installed(), reason="skipping because redis is installed")
def test_redis_disabled_when_not_installed(sentry_init):
sentry_init()
with ModuleImportErrorSimulator(["redis"], ImportError):
sentry_init()

assert sentry_sdk.get_client().get_integration(RedisIntegration) is None

Expand Down
Loading