async def test_task_not_awaited(tracked_requests, tracked_request): with BackgroundTransaction("test"): await create_task(coro("short")) long = create_task(coro("long", wait=0.5)) assert len(tracked_requests) == 1 assert len(tracked_request.complete_spans) == 2 span = tracked_request.complete_spans[0] assert span.operation == "Custom/coro" assert span.tags["value"] == "short" assert tracked_request.complete_spans[1].operation == "Job/test" assert not long.done() await long assert tracked_request.complete_spans[0].tags["value"] == "short" assert tracked_request.complete_spans[1].operation == "Job/test" assert tracked_requests[0].request_id == tracked_request.request_id if sys.version_info[:2] < (3, 7): # Python 3.6 utilizes the contextvars backport which functions # slightly differently than the contextvars stdlib implementation # in 3.7+ assert len(tracked_request.complete_spans) == 2 assert len(tracked_requests) == 1 else: assert len(tracked_request.complete_spans) == 3 assert tracked_request.complete_spans[2].tags["value"] == "long" # When we await long, it will call finish again which adds it # to tracked_requests assert len(tracked_requests) == 2 assert tracked_requests[0] is tracked_requests[1]
async def test_future_not_gathered(tracked_requests, tracked_request): with BackgroundTransaction("test"): gather_future = asyncio.gather( resolving_future(0.5), coro(wait=0.5), coro(wait=0.5), coro(wait=0.5), ) assert len(tracked_request.complete_spans) == 1 assert tracked_request.complete_spans[0].operation == "Job/test" await gather_future if sys.version_info[:2] < (3, 7): # Python 3.6 utilizes the contextvars backport which functions # slightly differently than the contextvars stdlib implementation # in 3.7+ assert len(tracked_request.complete_spans) == 1 assert len(tracked_requests) == 1 else: assert len(tracked_request.complete_spans) == 5 # When the last awaitable completes, it will call finish again which # adds it to tracked_requests assert len(tracked_requests) == 2 assert tracked_requests[0].request_id == tracked_request.request_id
async def test_nested_tasks(tracked_requests, tracked_request): @instrument.async_("orchestrator") async def orchestrator(): await coro("1") await asyncio.gather( # Force this coroutine to finish later for idempotency coro("2a", wait=0.5), coro("2b"), ) with BackgroundTransaction("test"): await orchestrator() spans = tracked_request.complete_spans assert len(spans) == 5 assert [span.operation for span in spans] == [ "Custom/coro", "Custom/coro", "Custom/coro", "Custom/orchestrator", "Job/test", ] # Verify the order of the coroutines assert [span.tags.get("value") for span in spans] == [ "1", "2b", "2a", None, None, ] assert len(tracked_requests) == 1 assert tracked_requests[0].request_id == tracked_request.request_id
async def test_task_cancelled(tracked_request): ensure_installed() with BackgroundTransaction("test"): long = create_task(coro("long", wait=0.5)) long.cancel() assert len(tracked_request.complete_spans) == 1 assert tracked_request.complete_spans[0].operation == "Job/test"
async def test_coroutine_timeout(tracked_request): ensure_installed() with BackgroundTransaction("test"): with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(coro("long", wait=0.5), timeout=0.1) assert len(tracked_request.complete_spans) == 1 assert tracked_request.complete_spans[0].operation == "Job/test"
async def test_coroutine(tracked_request): ensure_installed() with BackgroundTransaction("test"): await coro() assert len(tracked_request.complete_spans) == 2 span = tracked_request.complete_spans[0] assert span.operation == "Custom/coro" assert tracked_request.complete_spans[1].operation == "Job/test"
def test_background_transaction_context_manager(tracked_request): x = 0 with BackgroundTransaction("Foo"): x = 1 assert x == 1 assert len(tracked_request.active_spans) == 0 assert len(tracked_request.complete_spans) == 1 assert tracked_request.complete_spans[0].operation == "Job/Foo"
async def test_task_awaited(tracked_requests, tracked_request): with BackgroundTransaction("test"): await create_task(coro()) assert len(tracked_request.complete_spans) == 2 span = tracked_request.complete_spans[0] assert span.operation == "Custom/coro" assert tracked_request.complete_spans[1].operation == "Job/test" assert len(tracked_requests) == 1 assert tracked_requests[0].request_id == tracked_request.request_id
def test_background_transaction_context_manager(): tr = TrackedRequest.instance() x = 0 with BackgroundTransaction("Foo"): x = 1 span = tr.complete_spans[-1] assert x == 1 assert span.operation == "Job/Foo"
async def test_future_cancelled(tracked_request): ensure_installed() with BackgroundTransaction("test"): gather_future = asyncio.gather( resolving_future(0.5), coro(wait=0.5), ) gather_future.cancel() assert len(tracked_request.complete_spans) == 1 assert tracked_request.complete_spans[0].operation == "Job/test"
async def test_future_awaited(tracked_request): ensure_installed() with BackgroundTransaction("test"): fut = get_future() create_task(set_future(fut, wait=0.5)) await fut assert len(tracked_request.complete_spans) == 1 assert tracked_request.complete_spans[0].operation == "Custom/set_future" assert len(tracked_request.complete_spans) == 2 assert tracked_request.complete_spans[1].operation == "Job/test"
async def test_future_gathered(tracked_request): ensure_installed() with BackgroundTransaction("test"): await asyncio.gather( resolving_future(0.5), coro(wait=0.5), ) assert len(tracked_request.complete_spans) == 2 # gather can run the coroutines/futures in any order. operations = {span.operation for span in tracked_request.complete_spans} assert operations == {"Custom/set_future", "Custom/coro"} assert len(tracked_request.complete_spans) == 3 assert tracked_request.complete_spans[2].operation == "Job/test"
async def test_task_not_awaited(tracked_request): ensure_installed() with BackgroundTransaction("test"): await create_task(coro("short")) long = create_task(coro("long", wait=0.5)) assert len(tracked_request.complete_spans) == 2 span = tracked_request.complete_spans[0] assert span.operation == "Custom/coro" assert span.tags["value"] == "short" assert tracked_request.complete_spans[1].operation == "Job/test" assert not long.done() await long assert len(tracked_request.complete_spans) == 3 span = tracked_request.complete_spans[2] assert span.operation == "Custom/coro" assert span.tags["value"] == "long"
def inner_func(): with BackgroundTransaction("test"): TrackedRequest.instance().tag("ignore_transaction", True)
def inner_func(): with BackgroundTransaction("test"): pass