trace.get_current_span doesn't provide active span under test
Describe your environment
OS: Ubuntu Python version: 3.11.8 SDK version: opentelemetry-sdk=1.25.0
What happened?
Described in steps to reproduce
Steps to Reproduce
conftest.py
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry import trace
import google.auth.credentials
import pytest
@pytest.fixture
def creds():
"""
Provide test creds to unit tests so that they can run without them.
"""
yield google.auth.credentials.AnonymousCredentials()
@pytest.fixture(scope="session", autouse=True)
def set_trace_provider():
provider = TracerProvider()
trace.set_tracer_provider(provider)
@pytest.fixture(scope="function")
def span_exporter():
exporter = InMemorySpanExporter()
processor = SimpleSpanProcessor(exporter)
provider = trace.get_tracer_provider()
provider.add_span_processor(processor)
yield exporter
sample.py
from opentelemetry import trace
class Bar():
def foo(self):
tracer = trace.get_tracer("com.bar")
with tracer.start_as_current_span(name="footrace", end_on_exit=False) as _:
print("foo")
sample_test.py
import pytest
from sample import Bar
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry import trace
def test_fo(span_exporter):
b = Bar()
b.foo()
#spans = span_exporter.get_finished_spans()
#assert len(spans) == 1 -> This fails because the span hasn't ended because end_on_exit=False
span = trace.get_current_span()
assert span is not None -> Succeeds, but the contents of the span doesn't match the active span
# For example, the span.name is not footrace, but something else
Expected Result
Return the current active span
Actual Result
Returns some other span
Additional context
Understood that unfinished spans may not be exported, and hence may be unavailable, but open telemetry could provide a recommended way to test the values of active spans. This is required in scenarios where the spans are closed asynchronously in a different function / file altogether and we want to verify the contents of the active span in the unit tests of the function that creates it.
Would you like to implement a fix?
None
I think you are mixing up the started/ended state of a span with its activation state.
A call to trace.get_current_span() will always return the current active span (or an invalid span if no span is currently activated). Spans are usually activated with Tracer.start_as_current_span (or Tracer.start_span and then some time later with the trace.use_span context manager) which keeps the span active in the scope the context manager is active.
In your example the tracer.start_as_current_span(name="footrace", end_on_exit=False) context manager in Bar.foo keeps the span running but ends its activation state right after print("foo"). So when trace.get_current_span() is then later called in test_fo the isn't ended yet but it also isn't the active span anymore. Instead you'll get an invalid span since there is no other span currently active.
@xrmx My end goal here is to be able to verify the contents of the "footrace" span in test_foo(). How can I achieve this?