dify/api/tests/unit_tests/services/test_knowledge_fs_observability.py

94 lines
3.5 KiB
Python

from __future__ import annotations
from unittest.mock import MagicMock
from services.knowledge_fs.observability import (
KnowledgeFSBatchStatusMetric,
KnowledgeFSCapabilityIssuanceMetric,
KnowledgeFSControlSpaceStateMetric,
KnowledgeFSLifecycleTaskMetric,
OpenTelemetryKnowledgeFSOperationalMetrics,
)
def test_operational_metrics_use_only_bounded_labels_and_numeric_measurements() -> None:
meter = MagicMock()
counters: dict[str, MagicMock] = {}
histograms: dict[str, MagicMock] = {}
meter.create_counter.side_effect = lambda name, **_: counters.setdefault(name, MagicMock())
meter.create_histogram.side_effect = lambda name, **_: histograms.setdefault(name, MagicMock())
metrics = OpenTelemetryKnowledgeFSOperationalMetrics(meter=meter)
metrics.record_capability_issuance(
KnowledgeFSCapabilityIssuanceMetric(
caller_kind="interactive",
operation_id="getKnowledgeSpace",
outcome="issued",
reason="success",
)
)
metrics.record_batch_status(
KnowledgeFSBatchStatusMetric(
duration_seconds=0.25,
missing_spaces=1,
outcome="degraded",
requested_spaces=3,
returned_spaces=2,
)
)
metrics.record_control_space_state(
KnowledgeFSControlSpaceStateMetric(
duration_seconds=12.0,
from_state="provisioning",
to_state="active",
)
)
metrics.record_lifecycle_task(
KnowledgeFSLifecycleTaskMetric(
duration_seconds=3.5,
operation="revoke",
status="succeeded",
)
)
capability_counter = counters["dify.knowledge_fs.capability_issuance"]
assert capability_counter.add.call_args.args == (1,)
assert capability_counter.add.call_args.kwargs == {
"attributes": {
"caller_kind": "interactive",
"operation_id": "getKnowledgeSpace",
"outcome": "issued",
"reason": "success",
}
}
all_calls = str(meter.mock_calls)
assert "tenant_id" not in all_calls
assert "control_space_id" not in all_calls
assert "jti" not in all_calls
assert "token" not in all_calls
def test_control_space_current_state_gauge_uses_bounded_states_and_is_best_effort() -> None:
meter = MagicMock()
metrics = OpenTelemetryKnowledgeFSOperationalMetrics(meter=meter)
read_counts = MagicMock(return_value={"deleting": 2, "error": 1, "provisioning": 3})
metrics.register_control_space_state_gauge(read_counts)
gauge_call = meter.create_observable_gauge.call_args
assert gauge_call.args == ("dify.knowledge_fs.control_spaces",)
assert gauge_call.kwargs["unit"] == "{space}"
callback = gauge_call.kwargs["callbacks"][0]
observations = tuple(callback(MagicMock()))
assert [(observation.value, observation.attributes) for observation in observations] == [
(3, {"aggregation_scope": "global_database_snapshot", "state": "provisioning"}),
(2, {"aggregation_scope": "global_database_snapshot", "state": "deleting"}),
(1, {"aggregation_scope": "global_database_snapshot", "state": "error"}),
]
assert "aggregate replica series with max, never sum" in gauge_call.kwargs["description"]
read_counts.side_effect = RuntimeError("database unavailable")
assert tuple(callback(MagicMock())) == ()
metrics.register_control_space_state_gauge(read_counts)
assert meter.create_observable_gauge.call_count == 1