|
10 | 10 | from tests.opentracer.utils import init_tracer |
11 | 11 |
|
12 | 12 |
|
| 13 | +class MyException(Exception): |
| 14 | + pass |
| 15 | + |
| 16 | + |
13 | 17 | class CeleryIntegrationTask(CeleryBaseTestCase): |
14 | 18 | """Ensures that the tracer works properly with a real Celery application |
15 | 19 | without breaking the Application or Task API. |
16 | 20 | """ |
| 21 | + |
17 | 22 | def test_concurrent_delays(self): |
18 | 23 | # it should create one trace for each delayed execution |
19 | 24 | @self.app.task |
@@ -196,6 +201,28 @@ def fn_exception(): |
196 | 201 | ok_('Traceback (most recent call last)' in span.get_tag('error.stack')) |
197 | 202 | ok_('Task class is failing' in span.get_tag('error.stack')) |
198 | 203 |
|
| 204 | + def test_fn_exception_expected(self): |
| 205 | + # it should catch exceptions in task functions |
| 206 | + @self.app.task(throws=(MyException,)) |
| 207 | + def fn_exception(): |
| 208 | + raise MyException('Task class is failing') |
| 209 | + |
| 210 | + t = fn_exception.apply() |
| 211 | + ok_(t.failed()) |
| 212 | + ok_('Task class is failing' in t.traceback) |
| 213 | + |
| 214 | + traces = self.tracer.writer.pop_traces() |
| 215 | + eq_(1, len(traces)) |
| 216 | + eq_(1, len(traces[0])) |
| 217 | + span = traces[0][0] |
| 218 | + eq_(span.name, 'celery.run') |
| 219 | + eq_(span.resource, 'tests.contrib.celery.test_integration.fn_exception') |
| 220 | + eq_(span.service, 'celery-worker') |
| 221 | + eq_(span.get_tag('celery.id'), t.task_id) |
| 222 | + eq_(span.get_tag('celery.action'), 'run') |
| 223 | + eq_(span.get_tag('celery.state'), 'FAILURE') |
| 224 | + eq_(span.error, 0) |
| 225 | + |
199 | 226 | def test_fn_retry_exception(self): |
200 | 227 | # it should not catch retry exceptions in task functions |
201 | 228 | @self.app.task |
@@ -282,6 +309,36 @@ def run(self): |
282 | 309 | ok_('Traceback (most recent call last)' in span.get_tag('error.stack')) |
283 | 310 | ok_('Task class is failing' in span.get_tag('error.stack')) |
284 | 311 |
|
| 312 | + def test_class_task_exception_expected(self): |
| 313 | + # it should catch exceptions in class based tasks |
| 314 | + class BaseTask(self.app.Task): |
| 315 | + throws = (MyException,) |
| 316 | + |
| 317 | + def run(self): |
| 318 | + raise MyException('Task class is failing') |
| 319 | + |
| 320 | + t = BaseTask() |
| 321 | + # register the Task class if it's available (required in Celery 4.0+) |
| 322 | + register_task = getattr(self.app, 'register_task', None) |
| 323 | + if register_task is not None: |
| 324 | + register_task(t) |
| 325 | + |
| 326 | + r = t.apply() |
| 327 | + ok_(r.failed()) |
| 328 | + ok_('Task class is failing' in r.traceback) |
| 329 | + |
| 330 | + traces = self.tracer.writer.pop_traces() |
| 331 | + eq_(1, len(traces)) |
| 332 | + eq_(1, len(traces[0])) |
| 333 | + span = traces[0][0] |
| 334 | + eq_(span.name, 'celery.run') |
| 335 | + eq_(span.resource, 'tests.contrib.celery.test_integration.BaseTask') |
| 336 | + eq_(span.service, 'celery-worker') |
| 337 | + eq_(span.get_tag('celery.id'), r.task_id) |
| 338 | + eq_(span.get_tag('celery.action'), 'run') |
| 339 | + eq_(span.get_tag('celery.state'), 'FAILURE') |
| 340 | + eq_(span.error, 0) |
| 341 | + |
285 | 342 | def test_shared_task(self): |
286 | 343 | # Ensure Django Shared Task are supported |
287 | 344 | @celery.shared_task |
|
0 commit comments