Skip to content

Commit 9640486

Browse files
committed
Add tests for errors in Celery tasks
I noticed there were no tests for the error scenario in the Celery package. This commit adds a basic test, based on the previous test and how I see other packages test the error status on the span. Part of open-telemetry#987
1 parent d1dec92 commit 9640486

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

instrumentation/opentelemetry-instrumentation-celery/tests/celery_test_tasks.py

+4
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ class Config:
2727
@app.task
2828
def task_add(num_a, num_b):
2929
return num_a + num_b
30+
31+
@app.task
32+
def task_error():
33+
raise Exception("Test exception")

instrumentation/opentelemetry-instrumentation-celery/tests/test_tasks.py

+50-2
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
from opentelemetry.instrumentation.celery import CeleryInstrumentor
1919
from opentelemetry.semconv.trace import SpanAttributes
2020
from opentelemetry.test.test_base import TestBase
21-
from opentelemetry.trace import SpanKind
21+
from opentelemetry.trace import SpanKind, StatusCode
2222

23-
from .celery_test_tasks import app, task_add
23+
from .celery_test_tasks import app, task_add, task_error
2424

2525

2626
class TestCeleryInstrumentation(TestBase):
@@ -83,6 +83,54 @@ def test_task(self):
8383
self.assertEqual(consumer.parent.span_id, producer.context.span_id)
8484
self.assertEqual(consumer.context.trace_id, producer.context.trace_id)
8585

86+
def test_task_with_error(self):
87+
CeleryInstrumentor().instrument()
88+
89+
result = task_error.delay()
90+
91+
timeout = time.time() + 60 * 1 # 1 minutes from now
92+
while not result.ready():
93+
if time.time() > timeout:
94+
break
95+
time.sleep(0.05)
96+
97+
spans = self.sorted_spans(self.memory_exporter.get_finished_spans())
98+
self.assertEqual(len(spans), 2)
99+
100+
consumer, producer = spans
101+
102+
self.assertEqual(consumer.name, "run/tests.celery_test_tasks.task_error")
103+
self.assertEqual(consumer.kind, SpanKind.CONSUMER)
104+
self.assertSpanHasAttributes(
105+
consumer,
106+
{
107+
"celery.action": "run",
108+
"celery.state": "FAILURE",
109+
SpanAttributes.MESSAGING_DESTINATION: "celery",
110+
"celery.task_name": "tests.celery_test_tasks.task_error",
111+
},
112+
)
113+
self.assertEqual(consumer.status.status_code, StatusCode.ERROR)
114+
115+
self.assertEqual(
116+
producer.name, "apply_async/tests.celery_test_tasks.task_error"
117+
)
118+
self.assertEqual(producer.kind, SpanKind.PRODUCER)
119+
self.assertSpanHasAttributes(
120+
producer,
121+
{
122+
"celery.action": "apply_async",
123+
"celery.task_name": "tests.celery_test_tasks.task_error",
124+
SpanAttributes.MESSAGING_DESTINATION_KIND: "queue",
125+
SpanAttributes.MESSAGING_DESTINATION: "celery",
126+
},
127+
)
128+
self.assertEqual(producer.status.status_code, StatusCode.UNSET)
129+
130+
self.assertNotEqual(consumer.parent, producer.context)
131+
self.assertEqual(consumer.parent.span_id, producer.context.span_id)
132+
self.assertEqual(consumer.context.trace_id, producer.context.trace_id)
133+
86134
def test_uninstrument(self):
87135
CeleryInstrumentor().instrument()
88136
CeleryInstrumentor().uninstrument()

0 commit comments

Comments
 (0)