class TestGevent(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer(GeventScopeManager()) def test_main(self): # Create a Span and use it as (explicit) parent of a pair of subtasks. parent_span = self.tracer.start_span('parent') self.submit_subtasks(parent_span) gevent.wait(timeout=5.0) # Late-finish the parent Span now. parent_span.finish() spans = self.tracer.finished_spans() self.assertEqual(len(spans), 3) self.assertNamesEqual(spans, ['task1', 'task2', 'parent']) for i in range(2): self.assertSameTrace(spans[i], spans[-1]) self.assertIsChildOf(spans[i], spans[-1]) self.assertTrue(spans[i].finish_time <= spans[-1].finish_time) # Fire away a few subtasks, passing a parent Span whose lifetime # is not tied at all to the children. def submit_subtasks(self, parent_span): def task(name): with self.tracer.start_active_span(name, True, child_of=parent_span): gevent.sleep(0.1) gevent.spawn(task, 'task1') gevent.spawn(task, 'task2')
class TestTornado(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer(TornadoScopeManager()) self.loop = ioloop.IOLoop.current() def test_main(self): @gen.coroutine def main_task(): with self.tracer.start_active_span('parent', True): tasks = self.submit_callbacks() yield tasks with TracerStackContext(): self.loop.add_callback(main_task) stop_loop_when(self.loop, lambda: len(self.tracer.finished_spans()) == 4) self.loop.start() spans = self.tracer.finished_spans() self.assertEquals(len(spans), 4) self.assertNamesEqual(spans, ['task', 'task', 'task', 'parent']) for i in range(3): self.assertSameTrace(spans[i], spans[-1]) self.assertIsChildOf(spans[i], spans[-1]) @gen.coroutine def task(self, interval, parent_span): logger.info('Starting task') # NOTE: No need to reactivate the parent_span, as TracerStackContext # keeps track of it, BUT a limitation is that, yielding # upon multiple coroutines, we cannot mess with the context, # so no active span set here. with self.tracer.start_span('task'): yield gen.sleep(interval) def submit_callbacks(self): parent_span = self.tracer.scope_manager.active.span tasks = [] for i in range(3): interval = 0.1 + random.randint(200, 500) * 0.001 t = self.task(interval, parent_span) tasks.append(t) return tasks
class TestTornado(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer(TornadoScopeManager()) self.loop = ioloop.IOLoop.current() def test_main(self): # Start an isolated task and query for its result -and finish it- # in another task/thread span = self.tracer.start_span('initial') with TracerStackContext(): self.submit_another_task(span) stop_loop_when(self.loop, lambda: len(self.tracer.finished_spans()) >= 3) self.loop.start() spans = self.tracer.finished_spans() self.assertEqual(len(spans), 3) self.assertNamesEqual(spans, ['initial', 'subtask', 'task']) # task/subtask are part of the same trace, # and subtask is a child of task self.assertSameTrace(spans[1], spans[2]) self.assertIsChildOf(spans[1], spans[2]) # initial task is not related in any way to those two tasks self.assertNotSameTrace(spans[0], spans[1]) self.assertEqual(spans[0].parent_id, None) @gen.coroutine def task(self, span): # Create a new Span for this task with self.tracer.start_active_span('task', True): with self.tracer.scope_manager.activate(span, True): # Simulate work strictly related to the initial Span pass # Use the task span as parent of a new subtask with self.tracer.start_active_span('subtask', True): pass def submit_another_task(self, span): self.loop.add_callback(self.task, span)
class TestThreads(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer() self.executor = ThreadPoolExecutor(max_workers=3) def test_main(self): # Start an isolated task and query for its result -and finish it- # in another task/thread span = self.tracer.start_span('initial') self.submit_another_task(span) self.executor.shutdown(True) spans = self.tracer.finished_spans() self.assertEqual(len(spans), 3) self.assertNamesEqual(spans, ['initial', 'subtask', 'task']) # task/subtask are part of the same trace, # and subtask is a child of task self.assertSameTrace(spans[1], spans[2]) self.assertIsChildOf(spans[1], spans[2]) # initial task is not related in any way to those two tasks self.assertNotSameTrace(spans[0], spans[1]) self.assertEqual(spans[0].parent_id, None) def task(self, span): # Create a new Span for this task with self.tracer.start_active_span('task', True): with self.tracer.scope_manager.activate(span, True): # Simulate work strictly related to the initial Span pass # Use the task span as parent of a new subtask with self.tracer.start_active_span('subtask', True): pass def submit_another_task(self, span): self.executor.submit(self.task, span)
class TestTornado(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer(TornadoScopeManager()) self.loop = ioloop.IOLoop.current() def test_main(self): # Create a Span and use it as (explicit) parent of a pair of subtasks. with TracerStackContext(): parent_span = self.tracer.start_span('parent') self.submit_subtasks(parent_span) stop_loop_when(self.loop, lambda: len(self.tracer.finished_spans()) >= 2) self.loop.start() # Late-finish the parent Span now. parent_span.finish() spans = self.tracer.finished_spans() self.assertEqual(len(spans), 3) self.assertNamesEqual(spans, ['task1', 'task2', 'parent']) for i in range(2): self.assertSameTrace(spans[i], spans[-1]) self.assertIsChildOf(spans[i], spans[-1]) self.assertTrue(spans[i].finish_time <= spans[-1].finish_time) # Fire away a few subtasks, passing a parent Span whose lifetime # is not tied at all to the children. def submit_subtasks(self, parent_span): @gen.coroutine def task(name): logger.info('Running %s' % name) with self.tracer.start_active_span(name, True, child_of=parent_span): gen.sleep(0.1) self.loop.add_callback(task, 'task1') self.loop.add_callback(task, 'task2')
class TestAsyncio(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer(AsyncioScopeManager()) self.loop = asyncio.get_event_loop() def test_main(self): # Create a Span and use it as (explicit) parent of a pair of subtasks. parent_span = self.tracer.start_span('parent') self.submit_subtasks(parent_span) stop_loop_when(self.loop, lambda: len(self.tracer.finished_spans()) >= 2) self.loop.run_forever() # Late-finish the parent Span now. parent_span.finish() spans = self.tracer.finished_spans() self.assertEqual(len(spans), 3) self.assertNamesEqual(spans, ['task1', 'task2', 'parent']) for i in range(2): self.assertSameTrace(spans[i], spans[-1]) self.assertIsChildOf(spans[i], spans[-1]) self.assertTrue(spans[i].finish_time <= spans[-1].finish_time) # Fire away a few subtasks, passing a parent Span whose lifetime # is not tied at all to the children. def submit_subtasks(self, parent_span): async def task(name): logger.info('Running %s' % name) with self.tracer.start_active_span(name, True, child_of=parent_span): asyncio.sleep(0.1) self.loop.create_task(task('task1')) self.loop.create_task(task('task2'))
class TestThreads(OpenTracingTestCase): def setUp(self): self.tracer = MockTracer() self.executor = ThreadPoolExecutor(max_workers=3) def test_main(self): # Create a Span and use it as (explicit) parent of a pair of subtasks. parent_span = self.tracer.start_span('parent') self.submit_subtasks(parent_span) # Wait for the threadpool to be done. self.executor.shutdown(True) # Late-finish the parent Span now. parent_span.finish() spans = self.tracer.finished_spans() self.assertEqual(len(spans), 3) self.assertNamesEqual(spans, ['task1', 'task2', 'parent']) for i in range(2): self.assertSameTrace(spans[i], spans[-1]) self.assertIsChildOf(spans[i], spans[-1]) self.assertTrue(spans[i].finish_time <= spans[-1].finish_time) # Fire away a few subtasks, passing a parent Span whose lifetime # is not tied at all to the children. def submit_subtasks(self, parent_span): def task(name): with self.tracer.start_active_span(name, True, child_of=parent_span): time.sleep(0.1) self.executor.submit(task, 'task1') self.executor.submit(task, 'task2')