Skip to content

Commit db28135

Browse files
add tests cases for exception in atomic block
1 parent 95df407 commit db28135

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

tests/integrations/django/myapp/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ def path(path, *args, **kwargs):
8181
views.postgres_insert_orm_atomic_rollback,
8282
name="postgres_insert_orm_atomic_rollback",
8383
),
84+
path(
85+
"postgres-insert-atomic-exception",
86+
views.postgres_insert_orm_atomic_exception,
87+
name="postgres_insert_orm_atomic_exception",
88+
),
8489
path(
8590
"postgres-select-slow-from-supplement",
8691
helper_views.postgres_select_orm,

tests/integrations/django/myapp/views.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,20 @@ def postgres_insert_orm_atomic_rollback(request, *args, **kwargs):
290290
return HttpResponse("ok {}".format(user))
291291

292292

293+
@csrf_exempt
294+
def postgres_insert_orm_atomic_exception(request, *args, **kwargs):
295+
try:
296+
with transaction.atomic(using="postgres"):
297+
user = User.objects.db_manager("postgres").create_user(
298+
username="user1",
299+
)
300+
transaction.set_rollback(True, using="postgres")
301+
1 / 0
302+
except ZeroDivisionError:
303+
pass
304+
return HttpResponse("ok {}".format(user))
305+
306+
293307
@csrf_exempt
294308
def permission_denied_exc(*args, **kwargs):
295309
raise PermissionDenied("bye")

tests/integrations/django/test_db_transactions.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,3 +587,147 @@ def test_db_atomic_rollback_executemany(sentry_init, client, capture_events):
587587
# Verify queries and rollback statements are siblings
588588
for insert_span in insert_spans:
589589
assert rollback_span["parent_span_id"] == insert_span["parent_span_id"]
590+
591+
592+
@pytest.mark.forked
593+
@pytest_mark_django_db_decorator(transaction=True)
594+
def test_db_atomic_execute_exception(sentry_init, client, capture_events):
595+
sentry_init(
596+
integrations=[DjangoIntegration()],
597+
send_default_pii=True,
598+
traces_sample_rate=1.0,
599+
)
600+
601+
if "postgres" not in connections:
602+
pytest.skip("postgres tests disabled")
603+
604+
# trigger Django to open a new connection by marking the existing one as None.
605+
connections["postgres"].connection = None
606+
607+
events = capture_events()
608+
609+
client.get(reverse("postgres_insert_orm_atomic_exception"))
610+
611+
(event,) = events
612+
613+
# Ensure operation is rolled back
614+
assert not User.objects.using("postgres").exists()
615+
616+
assert event["contexts"]["trace"]["origin"] == "auto.http.django"
617+
618+
rollback_spans = [
619+
span
620+
for span in event["spans"]
621+
if span["data"].get(SPANDATA.DB_OPERATION) == DBOPERATION.ROLLBACK
622+
]
623+
assert len(rollback_spans) == 1
624+
rollback_span = rollback_spans[0]
625+
assert rollback_span["origin"] == "auto.db.django"
626+
627+
# Verify other database attributes
628+
assert rollback_span["data"].get(SPANDATA.DB_SYSTEM) == "postgresql"
629+
conn_params = connections["postgres"].get_connection_params()
630+
assert rollback_span["data"].get(SPANDATA.DB_NAME) is not None
631+
assert rollback_span["data"].get(SPANDATA.DB_NAME) == conn_params.get(
632+
"database"
633+
) or conn_params.get("dbname")
634+
assert rollback_span["data"].get(SPANDATA.SERVER_ADDRESS) == os.environ.get(
635+
"SENTRY_PYTHON_TEST_POSTGRES_HOST", "localhost"
636+
)
637+
assert rollback_span["data"].get(SPANDATA.SERVER_PORT) == os.environ.get(
638+
"SENTRY_PYTHON_TEST_POSTGRES_PORT", "5432"
639+
)
640+
641+
insert_spans = [
642+
span for span in event["spans"] if span["description"].startswith("INSERT INTO")
643+
]
644+
assert len(insert_spans) == 1
645+
insert_span = insert_spans[0]
646+
647+
# Verify query and rollback statements are siblings
648+
assert rollback_span["parent_span_id"] == insert_span["parent_span_id"]
649+
650+
651+
@pytest.mark.forked
652+
@pytest_mark_django_db_decorator(transaction=True)
653+
def test_db_atomic_executemany_exception(sentry_init, client, capture_events):
654+
sentry_init(
655+
integrations=[DjangoIntegration()],
656+
send_default_pii=True,
657+
traces_sample_rate=1.0,
658+
)
659+
660+
events = capture_events()
661+
662+
with start_transaction(name="test_transaction"):
663+
from django.db import connection, transaction
664+
665+
try:
666+
with transaction.atomic():
667+
cursor = connection.cursor()
668+
669+
query = """INSERT INTO auth_user (
670+
password,
671+
is_superuser,
672+
username,
673+
first_name,
674+
last_name,
675+
email,
676+
is_staff,
677+
is_active,
678+
date_joined
679+
)
680+
VALUES ('password', false, %s, %s, %s, %s, false, true, %s);"""
681+
682+
query_list = (
683+
(
684+
"user1",
685+
"John",
686+
"Doe",
687+
"user1@example.com",
688+
datetime(1970, 1, 1),
689+
),
690+
(
691+
"user2",
692+
"Max",
693+
"Mustermann",
694+
"user2@example.com",
695+
datetime(1970, 1, 1),
696+
),
697+
)
698+
cursor.executemany(query, query_list)
699+
1 / 0
700+
except ZeroDivisionError:
701+
pass
702+
703+
(event,) = events
704+
705+
# Ensure operation is rolled back
706+
assert not User.objects.exists()
707+
708+
assert event["contexts"]["trace"]["origin"] == "manual"
709+
710+
rollback_spans = [
711+
span
712+
for span in event["spans"]
713+
if span["data"].get(SPANDATA.DB_OPERATION) == DBOPERATION.ROLLBACK
714+
]
715+
assert len(rollback_spans) == 1
716+
rollback_span = rollback_spans[0]
717+
assert rollback_span["origin"] == "auto.db.django"
718+
719+
# Verify other database attributes
720+
assert rollback_span["data"].get(SPANDATA.DB_SYSTEM) == "sqlite"
721+
conn_params = connection.get_connection_params()
722+
assert rollback_span["data"].get(SPANDATA.DB_NAME) is not None
723+
assert rollback_span["data"].get(SPANDATA.DB_NAME) == conn_params.get(
724+
"database"
725+
) or conn_params.get("dbname")
726+
727+
insert_spans = [
728+
span for span in event["spans"] if span["description"].startswith("INSERT INTO")
729+
]
730+
731+
# Verify queries and rollback statements are siblings
732+
for insert_span in insert_spans:
733+
assert rollback_span["parent_span_id"] == insert_span["parent_span_id"]

0 commit comments

Comments
 (0)