Skip to content
Closed
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[pytest]
DJANGO_SETTINGS_MODULE = tests.integrations.django.myapp.settings
addopts = --boxed --tb=short
addopts = --tb=short
16 changes: 14 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,28 @@ def inner(event):


@pytest.fixture
def sentry_init(monkeypatch_test_transport):
def sentry_init(monkeypatch_test_transport, monkeypatch):
def inner(*a, **kw):
hub = sentry_sdk.Hub.current
client = sentry_sdk.Client(*a, **kw)
hub.bind_client(client)
monkeypatch.setattr(hub, "_stack", [(client, sentry_sdk.Scope())])
monkeypatch_test_transport(sentry_sdk.Hub.current.client)

return inner


@pytest.fixture(autouse=True)
def _assert_no_client(request, monkeypatch):
assert sentry_sdk.Hub.current.client is None
assert sentry_sdk.Hub.main.client is None

@request.addfinalizer
def _check_no_client():
monkeypatch.undo() # tear down sentry_init
assert sentry_sdk.Hub.current.client is None
assert sentry_sdk.Hub.main.client is None


class TestTransport(Transport):
def __init__(self, capture_event_callback):
Transport.__init__(self)
Expand Down
4 changes: 3 additions & 1 deletion tests/integrations/django/myapp/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
os.environ.setdefault(
"DJANGO_SETTINGS_MODULE", "tests.integrations.django.myapp.settings"
)

application = get_wsgi_application()
69 changes: 54 additions & 15 deletions tests/integrations/django/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import absolute_import

import threading

import pytest
import json

from werkzeug.test import Client
from django.contrib.auth.models import User
from django.core.management import execute_from_command_line
from django.db.utils import OperationalError, ProgrammingError, DataError

Expand All @@ -18,6 +21,34 @@
from tests.integrations.django.myapp.wsgi import application


@pytest.fixture
def django_clear_caches():
"""Invalidate the connection caches.

https://github.com/pytest-dev/pytest-django/issues/587
"""
from django.db import connections

connections._connections = threading.local()
# this will clear the cached property
connections.__dict__.pop("databases", None)


@pytest.fixture(autouse=True)
def setup_app_tables(request):
if request.node.get_closest_marker("django_db") is None:
return

# Honestly no idea why pytest-django does not do this
from django import VERSION
from django.core import management

if VERSION < (2, 0):
management.call_command("migrate", noinput=True)
else:
management.call_command("migrate", no_input=True)


@pytest.fixture
def client():
return Client(application)
Expand Down Expand Up @@ -80,9 +111,11 @@ def test_transaction_with_class_view(sentry_init, client, capture_events):
assert event["message"] == "hi"


@pytest.mark.django_db
@pytest.mark.django_db(transaction=True)
def test_user_captured(sentry_init, client, capture_events):

sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)

events = capture_events()
content, status, headers = client.get(reverse("mylogin"))
assert b"".join(content) == b"ok"
Expand All @@ -101,9 +134,12 @@ def test_user_captured(sentry_init, client, capture_events):
}


@pytest.mark.django_db
@pytest.mark.django_db(transaction=True)
def test_queryset_repr(sentry_init, capture_events):
from django.contrib.auth.models import User

sentry_init(integrations=[DjangoIntegration()])

events = capture_events()
User.objects.create_user("john", "[email protected]", "johnpassword")

Expand Down Expand Up @@ -163,28 +199,30 @@ def test_management_command_raises():
execute_from_command_line(["manage.py", "mycrash"])


@pytest.mark.django_db
def test_sql_queries(sentry_init, capture_events):
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
@pytest.mark.django_db(transaction=True)
def test_sql_queries(request, sentry_init, capture_events):
from django.db import connection
from django.db.backends.utils import CursorWrapper

sql = connection.cursor()
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)

events = capture_events()
with pytest.raises(OperationalError):
# table doesn't even exist
sql.execute("""SELECT count(*) FROM people_person WHERE foo = %s""", [123])

with connection.cursor() as sql:
assert type(sql) is CursorWrapper
with pytest.raises(OperationalError):
# table doesn't even exist
sql.execute("""SELECT count(*) FROM people_person WHERE foo = %s""", [123])

capture_message("HI")

event, = events

assert event["message"] == "HI"
crumb, = event["breadcrumbs"]

assert crumb["message"] == """SELECT count(*) FROM people_person WHERE foo = 123"""


@pytest.mark.django_db
@pytest.mark.django_db(transaction=True)
def test_sql_dict_query_params(sentry_init, capture_events):
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)

Expand Down Expand Up @@ -278,11 +316,12 @@ def test_sql_psycopg2_placeholders(sentry_init, capture_events):
)


@pytest.mark.django_db
@pytest.mark.django_db(transaction=True)
def test_sql_queries_large_params(sentry_init, capture_events):
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
from django.db import connection

sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)

sql = connection.cursor()

events = capture_events()
Expand Down
23 changes: 9 additions & 14 deletions tests/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,26 +205,21 @@ def test_breadcrumbs(sentry_init, capture_events):
assert len(event["breadcrumbs"]) == 0


def test_integration_scoping():
def test_integration_scoping(sentry_init, capture_events):
logger = logging.getLogger("test_basics")
events = []
logging_integration = LoggingIntegration(event_level=logging.WARNING)

# This client uses the logging integration
client_with_logging = Client(
transport=events.append,
default_integrations=False,
integrations=[logging_integration],
)
Hub.current.bind_client(client_with_logging)
logging_integration = LoggingIntegration(event_level=logging.WARNING)
sentry_init(default_integrations=False, integrations=[logging_integration])
events = capture_events()
logger.warning("This is a warning")
assert len(events) == 1

# This client does not
client_without_logging = Client(transport=events.append, default_integrations=False)
Hub.current.bind_client(client_without_logging)
sentry_init(default_integrations=False)
events = capture_events()
logger.warning("This is not a warning")

assert len(events) == 1
assert not events


def test_client_initialized_within_scope(sentry_init, caplog):
Expand All @@ -233,7 +228,7 @@ def test_client_initialized_within_scope(sentry_init, caplog):
sentry_init(debug=True)

with push_scope():
sentry_init()
Hub.current.bind_client(Client())

record, = (x for x in caplog.records if x.levelname == "WARNING")

Expand Down
12 changes: 2 additions & 10 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
add_breadcrumb,
capture_exception,
)
from sentry_sdk.hub import HubMeta
from sentry_sdk.transport import Transport
from sentry_sdk._compat import reraise, text_type, PY2
from sentry_sdk.utils import HAS_CHAINED_EXCEPTIONS
Expand Down Expand Up @@ -336,15 +335,8 @@ def callback(scope):
assert calls[0] is Hub.current._stack[-1][1]


@pytest.mark.parametrize("no_sdk", (True, False))
def test_configure_scope_unavailable(no_sdk, monkeypatch):
if no_sdk:
# Emulate minimal without SDK installation: callbacks are not called
monkeypatch.setattr(HubMeta, "current", None)
assert not Hub.current
else:
# Still, no client configured
assert Hub.current
def test_configure_scope_unavailable(monkeypatch):
assert Hub.current

calls = []

Expand Down