|
9 | 9 | from langchain_core.outputs import ChatGeneration, ChatResult, Generation, LLMResult |
10 | 10 | from langchain_core.prompts import ChatPromptTemplate |
11 | 11 | from langchain_openai import ChatOpenAI, OpenAI |
| 12 | +from opentelemetry import context as otel_context |
12 | 13 |
|
13 | 14 | from langfuse._client.attributes import LangfuseOtelSpanAttributes |
14 | 15 | from langfuse.langchain import CallbackHandler |
@@ -338,6 +339,7 @@ def test_control_flow_resume_reuses_trace_until_terminal_completion( |
338 | 339 | class DummyControlFlowError(RuntimeError): |
339 | 340 | pass |
340 | 341 |
|
| 342 | + context_token = otel_context.attach(otel_context.Context()) |
341 | 343 | original_control_flow_types = set(CONTROL_FLOW_EXCEPTION_TYPES) |
342 | 344 | CONTROL_FLOW_EXCEPTION_TYPES.clear() |
343 | 345 | CONTROL_FLOW_EXCEPTION_TYPES.add(DummyControlFlowError) |
@@ -388,10 +390,22 @@ class DummyControlFlowError(RuntimeError): |
388 | 390 | ] |
389 | 391 |
|
390 | 392 | assert len(root_spans) == 3 |
391 | | - assert root_spans[0].context.trace_id == root_spans[1].context.trace_id |
392 | | - assert root_spans[1].parent is not None |
393 | | - assert root_spans[1].parent.span_id == root_spans[0].context.span_id |
394 | | - assert root_spans[2].context.trace_id != root_spans[1].context.trace_id |
| 393 | + spans_by_trace_id = {} |
| 394 | + for span in root_spans: |
| 395 | + spans_by_trace_id.setdefault(span.context.trace_id, []).append(span) |
| 396 | + |
| 397 | + assert sorted(len(spans) for spans in spans_by_trace_id.values()) == [1, 2] |
| 398 | + |
| 399 | + resumed_trace_spans = next( |
| 400 | + spans for spans in spans_by_trace_id.values() if len(spans) == 2 |
| 401 | + ) |
| 402 | + initial_span = next(span for span in resumed_trace_spans if span.parent is None) |
| 403 | + resumed_span = next(span for span in resumed_trace_spans if span.parent is not None) |
| 404 | + fresh_span = next(span for span in root_spans if span.context.trace_id != initial_span.context.trace_id) |
| 405 | + |
| 406 | + assert resumed_span.parent.span_id == initial_span.context.span_id |
| 407 | + assert fresh_span.parent is None |
395 | 408 | finally: |
396 | 409 | CONTROL_FLOW_EXCEPTION_TYPES.clear() |
397 | 410 | CONTROL_FLOW_EXCEPTION_TYPES.update(original_control_flow_types) |
| 411 | + otel_context.detach(context_token) |
0 commit comments