Files
wehub-resource-sync c889a57b6b
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:02:24 +08:00

375 lines
11 KiB
Python

"""Unit tests for the cognee tracing / observability module."""
import os
import pytest
from cognee.modules.observability.tracing import (
CogneeSpanExporter,
CogneeTrace,
redact_secrets,
setup_tracing,
shutdown_tracing,
get_tracer,
get_exporter,
)
from cognee.modules.observability.trace_context import (
enable_tracing,
disable_tracing,
is_tracing_enabled,
get_last_trace,
get_all_traces,
clear_traces,
)
# ---------------------------------------------------------------------------
# Redaction tests
# ---------------------------------------------------------------------------
class TestRedactSecrets:
def test_redacts_openai_key(self):
text = "key is sk-abcdefghijklmnopqrstuvwxyz"
result = redact_secrets(text)
assert "sk-abc" in result
assert "REDACTED" in result
assert "abcdefghijklmnopqrstuvwxyz" not in result
def test_redacts_bearer_token(self):
text = "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.long_token"
result = redact_secrets(text)
assert "REDACTED" in result
def test_preserves_normal_text(self):
text = "SELECT * FROM users WHERE name = 'Alice'"
assert redact_secrets(text) == text
def test_handles_empty_string(self):
assert redact_secrets("") == ""
def test_handles_none(self):
assert redact_secrets(None) is None
# ---------------------------------------------------------------------------
# CogneeSpanExporter tests
# ---------------------------------------------------------------------------
class TestCogneeSpanExporter:
def test_export_and_retrieve(self):
"""Test that spans are collected and retrievable."""
try:
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
exporter = CogneeSpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
tracer = provider.get_tracer("test")
with tracer.start_as_current_span("test_span") as span:
span.set_attribute("key", "value")
provider.force_flush()
spans = exporter.get_last_trace_spans()
assert spans is not None
assert len(spans) == 1
assert spans[0]["name"] == "test_span"
assert spans[0]["attributes"]["key"] == "value"
assert spans[0]["duration_ms"] >= 0
provider.shutdown()
def test_clear(self):
try:
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
exporter = CogneeSpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
tracer = provider.get_tracer("test")
with tracer.start_as_current_span("span1"):
pass
provider.force_flush()
assert exporter.get_last_trace_spans() is not None
exporter.clear()
assert exporter.get_last_trace_spans() is None
provider.shutdown()
def test_multiple_traces(self):
try:
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry import context as otel_context
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
exporter = CogneeSpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
tracer = provider.get_tracer("test")
# Create two separate root spans (separate traces)
with tracer.start_as_current_span("trace1_root"):
pass
# Detach context to start fresh trace
token = otel_context.attach(otel_context.Context())
try:
with tracer.start_as_current_span("trace2_root"):
pass
finally:
otel_context.detach(token)
provider.force_flush()
all_traces = exporter.get_all_traces()
assert len(all_traces) >= 1 # At least one trace
provider.shutdown()
# ---------------------------------------------------------------------------
# CogneeTrace tests
# ---------------------------------------------------------------------------
class TestCogneeTrace:
def test_summary_empty(self):
trace = CogneeTrace([])
summary = trace.summary()
assert summary["operation"] == ""
assert summary["total_duration_ms"] == 0.0
assert summary["span_count"] == 0
def test_summary_with_spans(self):
spans = [
{
"name": "cognee.search",
"trace_id": "abc123",
"span_id": "span1",
"parent_span_id": None,
"start_time_ns": 1000000000,
"end_time_ns": 2000000000,
"duration_ms": 1000.0,
"status": "OK",
"attributes": {},
},
{
"name": "cognee.graph.query",
"trace_id": "abc123",
"span_id": "span2",
"parent_span_id": "span1",
"start_time_ns": 1100000000,
"end_time_ns": 1200000000,
"duration_ms": 100.0,
"status": "OK",
"attributes": {"cognee.db.system": "ladybug"},
},
]
trace = CogneeTrace(spans)
summary = trace.summary()
assert summary["operation"] == "cognee.search"
assert summary["total_duration_ms"] == 1000.0
assert summary["span_count"] == 2
assert "cognee.graph.query" in summary["breakdown"]
assert summary["breakdown"]["cognee.graph.query"]["count"] == 1
def test_spans_sorted(self):
spans = [
{
"name": "b",
"span_id": "s2",
"parent_span_id": None,
"start_time_ns": 2000,
"end_time_ns": 3000,
"duration_ms": 1.0,
"status": "OK",
"attributes": {},
"trace_id": "t1",
},
{
"name": "a",
"span_id": "s1",
"parent_span_id": None,
"start_time_ns": 1000,
"end_time_ns": 2000,
"duration_ms": 1.0,
"status": "OK",
"attributes": {},
"trace_id": "t1",
},
]
trace = CogneeTrace(spans)
sorted_spans = trace.spans()
assert sorted_spans[0]["name"] == "a"
assert sorted_spans[1]["name"] == "b"
def test_tree(self):
spans = [
{
"name": "root",
"span_id": "s1",
"parent_span_id": None,
"start_time_ns": 1000,
"end_time_ns": 3000,
"duration_ms": 2.0,
"status": "OK",
"attributes": {},
"trace_id": "t1",
},
{
"name": "child",
"span_id": "s2",
"parent_span_id": "s1",
"start_time_ns": 1500,
"end_time_ns": 2500,
"duration_ms": 1.0,
"status": "OK",
"attributes": {},
"trace_id": "t1",
},
]
trace = CogneeTrace(spans)
tree = trace.tree()
assert tree["name"] == "root"
assert len(tree["children"]) == 1
assert tree["children"][0]["name"] == "child"
def test_summary_errors(self):
spans = [
{
"name": "failed_op",
"span_id": "s1",
"parent_span_id": None,
"start_time_ns": 1000,
"end_time_ns": 2000,
"duration_ms": 1.0,
"status": "ERROR",
"attributes": {},
"trace_id": "t1",
},
]
trace = CogneeTrace(spans)
summary = trace.summary()
assert len(summary["errors"]) == 1
# ---------------------------------------------------------------------------
# Enable/disable lifecycle
# ---------------------------------------------------------------------------
class TestTracingLifecycle:
def setup_method(self):
"""Ensure clean state before each test."""
disable_tracing()
os.environ.pop("COGNEE_TRACING_ENABLED", None)
def teardown_method(self):
disable_tracing()
os.environ.pop("COGNEE_TRACING_ENABLED", None)
def test_disabled_by_default(self):
assert not is_tracing_enabled()
def test_enable_disable(self):
try:
import opentelemetry # noqa: F401
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
enable_tracing()
assert is_tracing_enabled()
disable_tracing()
assert not is_tracing_enabled()
def test_env_var_enables(self):
os.environ["COGNEE_TRACING_ENABLED"] = "true"
assert is_tracing_enabled()
def test_get_last_trace_when_disabled(self):
assert get_last_trace() is None
def test_get_all_traces_when_disabled(self):
assert get_all_traces() == []
def test_clear_traces_when_disabled(self):
# Should not raise
clear_traces()
def test_full_lifecycle(self):
try:
import opentelemetry # noqa: F401
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
enable_tracing()
tracer = get_tracer()
assert tracer is not None
with tracer.start_as_current_span("test_op") as span:
span.set_attribute("test_key", "test_val")
trace = get_last_trace()
assert trace is not None
summary = trace.summary()
assert summary["operation"] == "test_op"
assert summary["span_count"] == 1
clear_traces()
assert get_last_trace() is None
disable_tracing()
assert get_tracer() is None
# ---------------------------------------------------------------------------
# Setup/shutdown
# ---------------------------------------------------------------------------
class TestSetupTracing:
def teardown_method(self):
shutdown_tracing()
def test_setup_returns_tracer(self):
try:
import opentelemetry # noqa: F401
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
tracer = setup_tracing()
assert tracer is not None
def test_setup_with_console(self):
try:
import opentelemetry # noqa: F401
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
tracer = setup_tracing(console_output=True)
assert tracer is not None
def test_exporter_available_after_setup(self):
try:
import opentelemetry # noqa: F401
except ImportError:
pytest.skip("opentelemetry-sdk not installed")
setup_tracing()
assert get_exporter() is not None