Skip to content

Commit 11180e6

Browse files
committed
tests
1 parent aefbc18 commit 11180e6

File tree

1 file changed

+228
-0
lines changed

1 file changed

+228
-0
lines changed
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
import pytest
2+
3+
import sentry_sdk
4+
from sentry_sdk import start_span
5+
from sentry_sdk.integrations.django import DjangoIntegration
6+
from sentry_sdk.consts import OP
7+
8+
9+
try:
10+
from django.tasks import task
11+
12+
HAS_DJANGO_TASKS = True
13+
except ImportError:
14+
HAS_DJANGO_TASKS = False
15+
16+
17+
@pytest.fixture
18+
def immediate_backend(settings):
19+
"""Configure Django to use the immediate task backend for synchronous testing."""
20+
settings.TASKS = {
21+
"default": {"BACKEND": "django.tasks.backends.immediate.ImmediateBackend"}
22+
}
23+
24+
25+
if HAS_DJANGO_TASKS:
26+
27+
@task
28+
def simple_task():
29+
return "result"
30+
31+
@task
32+
def add_numbers(a, b):
33+
return a + b
34+
35+
@task
36+
def greet(name, greeting="Hello"):
37+
return f"{greeting}, {name}!"
38+
39+
@task
40+
def failing_task():
41+
raise ValueError("Task failed!")
42+
43+
@task
44+
def task_one():
45+
return 1
46+
47+
@task
48+
def task_two():
49+
return 2
50+
51+
52+
@pytest.mark.skipif(
53+
not HAS_DJANGO_TASKS,
54+
reason="Django tasks are only available in Django 6.0+",
55+
)
56+
def test_task_span_is_created(sentry_init, capture_events, immediate_backend):
57+
"""Test that the queue.submit.django span is created when a task is enqueued."""
58+
sentry_init(
59+
integrations=[DjangoIntegration()],
60+
traces_sample_rate=1.0,
61+
)
62+
events = capture_events()
63+
64+
with sentry_sdk.start_transaction(name="test_transaction"):
65+
simple_task.enqueue()
66+
67+
(event,) = events
68+
assert event["type"] == "transaction"
69+
70+
queue_submit_spans = [
71+
span for span in event["spans"] if span["op"] == OP.QUEUE_SUBMIT_DJANGO
72+
]
73+
assert len(queue_submit_spans) == 1
74+
assert queue_submit_spans[0]["description"] == "simple_task"
75+
assert queue_submit_spans[0]["origin"] == "auto.http.django"
76+
77+
78+
@pytest.mark.skipif(
79+
not HAS_DJANGO_TASKS,
80+
reason="Django tasks are only available in Django 6.0+",
81+
)
82+
def test_task_enqueue_returns_result(sentry_init, immediate_backend):
83+
"""Test that the task enqueuing behavior is unchanged from the user perspective."""
84+
sentry_init(
85+
integrations=[DjangoIntegration()],
86+
traces_sample_rate=1.0,
87+
)
88+
89+
result = add_numbers.enqueue(3, 5)
90+
91+
assert result is not None
92+
assert result.return_value == 8
93+
94+
95+
@pytest.mark.skipif(
96+
not HAS_DJANGO_TASKS,
97+
reason="Django tasks are only available in Django 6.0+",
98+
)
99+
def test_task_enqueue_with_kwargs(sentry_init, immediate_backend, capture_events):
100+
"""Test that task enqueuing works correctly with keyword arguments."""
101+
sentry_init(
102+
integrations=[DjangoIntegration()],
103+
traces_sample_rate=1.0,
104+
)
105+
events = capture_events()
106+
107+
with sentry_sdk.start_transaction(name="test_transaction"):
108+
result = greet.enqueue(name="World", greeting="Hi")
109+
110+
assert result.return_value == "Hi, World!"
111+
112+
(event,) = events
113+
queue_submit_spans = [
114+
span for span in event["spans"] if span["op"] == OP.QUEUE_SUBMIT_DJANGO
115+
]
116+
assert len(queue_submit_spans) == 1
117+
assert queue_submit_spans[0]["description"] == "greet"
118+
119+
120+
@pytest.mark.skipif(
121+
not HAS_DJANGO_TASKS,
122+
reason="Django tasks are only available in Django 6.0+",
123+
)
124+
def test_task_error_reporting(sentry_init, immediate_backend, capture_events):
125+
"""Test that errors in tasks are correctly reported and don't break the span."""
126+
sentry_init(
127+
integrations=[DjangoIntegration()],
128+
traces_sample_rate=1.0,
129+
)
130+
events = capture_events()
131+
132+
with sentry_sdk.start_transaction(name="test_transaction"):
133+
result = failing_task.enqueue()
134+
135+
with pytest.raises(ValueError, match="Task failed"):
136+
_ = result.return_value
137+
138+
assert len(events) >= 1
139+
transaction_event = events[-1]
140+
assert transaction_event["type"] == "transaction"
141+
142+
queue_submit_spans = [
143+
span
144+
for span in transaction_event["spans"]
145+
if span["op"] == OP.QUEUE_SUBMIT_DJANGO
146+
]
147+
assert len(queue_submit_spans) == 1
148+
assert queue_submit_spans[0]["description"] == "failing_task"
149+
150+
151+
@pytest.mark.skipif(
152+
not HAS_DJANGO_TASKS,
153+
reason="Django tasks are only available in Django 6.0+",
154+
)
155+
def test_task_span_not_created_without_integration(
156+
sentry_init, capture_events, immediate_backend
157+
):
158+
"""Test that no span is created when DjangoIntegration is not enabled."""
159+
sentry_init(traces_sample_rate=1.0, default_integrations=False)
160+
events = capture_events()
161+
162+
with sentry_sdk.start_transaction(name="test_transaction"):
163+
simple_task.enqueue()
164+
165+
(event,) = events
166+
queue_submit_spans = [
167+
span for span in event["spans"] if span["op"] == OP.QUEUE_SUBMIT_DJANGO
168+
]
169+
assert len(queue_submit_spans) == 0
170+
171+
172+
@pytest.mark.skipif(
173+
not HAS_DJANGO_TASKS,
174+
reason="Django tasks are only available in Django 6.0+",
175+
)
176+
def test_multiple_task_enqueues_create_multiple_spans(
177+
sentry_init, capture_events, immediate_backend
178+
):
179+
"""Test that enqueueing multiple tasks creates multiple spans."""
180+
sentry_init(
181+
integrations=[DjangoIntegration()],
182+
traces_sample_rate=1.0,
183+
)
184+
events = capture_events()
185+
186+
with sentry_sdk.start_transaction(name="test_transaction"):
187+
task_one.enqueue()
188+
task_two.enqueue()
189+
task_one.enqueue()
190+
191+
(event,) = events
192+
queue_submit_spans = [
193+
span for span in event["spans"] if span["op"] == OP.QUEUE_SUBMIT_DJANGO
194+
]
195+
assert len(queue_submit_spans) == 3
196+
197+
span_names = [span["description"] for span in queue_submit_spans]
198+
assert span_names.count("task_one") == 2
199+
assert span_names.count("task_two") == 1
200+
201+
202+
@pytest.mark.skipif(
203+
not HAS_DJANGO_TASKS,
204+
reason="Django tasks are only available in Django 6.0+",
205+
)
206+
def test_nested_task_enqueue_spans(sentry_init, capture_events, immediate_backend):
207+
"""Test that task spans are properly nested under parent spans."""
208+
sentry_init(
209+
integrations=[DjangoIntegration()],
210+
traces_sample_rate=1.0,
211+
)
212+
events = capture_events()
213+
214+
with sentry_sdk.start_transaction(name="test_transaction"):
215+
with start_span(op="custom.operation", name="parent_span"):
216+
simple_task.enqueue()
217+
218+
(event,) = events
219+
220+
custom_spans = [span for span in event["spans"] if span["op"] == "custom.operation"]
221+
queue_submit_spans = [
222+
span for span in event["spans"] if span["op"] == OP.QUEUE_SUBMIT_DJANGO
223+
]
224+
225+
assert len(custom_spans) == 1
226+
assert len(queue_submit_spans) == 1
227+
228+
assert queue_submit_spans[0]["parent_span_id"] == custom_spans[0]["span_id"]

0 commit comments

Comments
 (0)