|
| 1 | +import pytest |
| 2 | +from opentelemetry.trace import SpanKind |
| 3 | + |
| 4 | +import vllm_router.experimental.otel.tracing as tracing_module |
| 5 | +from vllm_router.experimental.otel.tracing import ( |
| 6 | + end_span, |
| 7 | + extract_context, |
| 8 | + initialize_tracing, |
| 9 | + inject_context, |
| 10 | + is_tracing_enabled, |
| 11 | + shutdown_tracing, |
| 12 | + start_span, |
| 13 | +) |
| 14 | + |
| 15 | + |
| 16 | +@pytest.fixture(autouse=True) |
| 17 | +def reset_tracing_state(): |
| 18 | + """Reset global tracing state before each test.""" |
| 19 | + tracing_module._tracer = None |
| 20 | + tracing_module._provider = None |
| 21 | + tracing_module._tracing_enabled = False |
| 22 | + yield |
| 23 | + # Cleanup after test |
| 24 | + if tracing_module._tracing_enabled: |
| 25 | + shutdown_tracing() |
| 26 | + |
| 27 | + |
| 28 | +class TestTracingIntegration: |
| 29 | + def test_full_request_flow(self): |
| 30 | + """Test a complete request tracing flow.""" |
| 31 | + initialize_tracing(service_name="vllm-router", otlp_endpoint="localhost:4317") |
| 32 | + |
| 33 | + # Simulate incoming request with trace context |
| 34 | + incoming_headers = { |
| 35 | + "traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01", |
| 36 | + } |
| 37 | + incoming_context = extract_context(incoming_headers) |
| 38 | + |
| 39 | + # Create parent span (router) |
| 40 | + parent_span, parent_context = start_span( |
| 41 | + name="router /v1/chat/completions", |
| 42 | + parent_context=incoming_context, |
| 43 | + kind=SpanKind.SERVER, |
| 44 | + attributes={ |
| 45 | + "http.method": "POST", |
| 46 | + "vllm.model": "Qwen/Qwen2.5-7B-Instruct", |
| 47 | + }, |
| 48 | + ) |
| 49 | + |
| 50 | + # Create child span (backend request) |
| 51 | + child_span, child_context = start_span( |
| 52 | + name="backend_request", |
| 53 | + parent_context=parent_context, |
| 54 | + kind=SpanKind.CLIENT, |
| 55 | + attributes={ |
| 56 | + "http.url": "http://backend:8000/v1/chat/completions", |
| 57 | + }, |
| 58 | + ) |
| 59 | + |
| 60 | + # Inject context into outgoing headers |
| 61 | + outgoing_headers = {} |
| 62 | + inject_context(outgoing_headers, child_context) |
| 63 | + |
| 64 | + assert "traceparent" in outgoing_headers |
| 65 | + |
| 66 | + # End spans in reverse order |
| 67 | + end_span(child_span, status_code=200) |
| 68 | + end_span(parent_span, status_code=200) |
| 69 | + |
| 70 | + def test_tracing_disabled_flow(self): |
| 71 | + """Test that operations handle disabled tracing gracefully.""" |
| 72 | + assert is_tracing_enabled() is False |
| 73 | + |
| 74 | + # These should not raise even when tracing is disabled |
| 75 | + headers = {} |
| 76 | + inject_context(headers) |
| 77 | + end_span(None) |
| 78 | + |
| 79 | + |
| 80 | +if __name__ == "__main__": |
| 81 | + pytest.main([__file__, "-v"]) |
0 commit comments