103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
SDK_SRC = PROJECT_ROOT / "packages" / "jwebot-sdk" / "src"
|
|
KERNEL_SRC = PROJECT_ROOT / "packages" / "jwebot-kernel" / "src"
|
|
sys.path[:0] = [str(SDK_SRC), str(KERNEL_SRC)]
|
|
|
|
from jwebot_kernel.telemetry import RuntimeTelemetry # noqa: E402
|
|
|
|
|
|
class TelemetryTests(unittest.TestCase):
|
|
def test_event_hashes_identifiers_and_drops_unknown_fields(self):
|
|
observed = []
|
|
logger = mock.Mock()
|
|
telemetry = RuntimeTelemetry(
|
|
component="edge",
|
|
observer=observed.append,
|
|
logger=logger,
|
|
)
|
|
|
|
value = telemetry.emit(
|
|
"edge.route.classified",
|
|
event_id="private-event-id",
|
|
group_id="private-group",
|
|
route="local",
|
|
reason="local_coin",
|
|
component="attacker",
|
|
message_body="must-not-appear",
|
|
)
|
|
|
|
self.assertNotIn("private-event-id", str(dict(value)))
|
|
self.assertNotIn("private-group", str(dict(value)))
|
|
self.assertNotIn("message_body", value)
|
|
self.assertEqual(value["route"], "local")
|
|
self.assertEqual(value["component"], "edge")
|
|
self.assertEqual(len(observed), 1)
|
|
logger.info.assert_called_once()
|
|
|
|
def test_elapsed_updates_low_cardinality_snapshot(self):
|
|
values = iter((10.0, 10.025))
|
|
telemetry = RuntimeTelemetry(
|
|
component="host-client",
|
|
logger=mock.Mock(),
|
|
monotonic=lambda: next(values),
|
|
)
|
|
started = telemetry.monotonic()
|
|
telemetry.elapsed(
|
|
"host.invoke",
|
|
started,
|
|
status="ok",
|
|
plugin_id="coin",
|
|
)
|
|
|
|
snapshot = telemetry.snapshot()
|
|
self.assertEqual(snapshot["counts"]["host.invoke:ok"], 1)
|
|
self.assertEqual(
|
|
snapshot["latencies"]["host.invoke"]["average_ms"],
|
|
25.0,
|
|
)
|
|
|
|
def test_span_records_error_type_without_swallowing(self):
|
|
observed = []
|
|
values = iter((1.0, 1.01))
|
|
telemetry = RuntimeTelemetry(
|
|
component="edge",
|
|
observer=observed.append,
|
|
logger=mock.Mock(),
|
|
monotonic=lambda: next(values),
|
|
)
|
|
|
|
with self.assertRaisesRegex(RuntimeError, "failed"):
|
|
with telemetry.span("edge.local.execute", route="local"):
|
|
raise RuntimeError("failed")
|
|
|
|
self.assertEqual(observed[0]["status"], "error")
|
|
self.assertEqual(observed[0]["error_type"], "RuntimeError")
|
|
self.assertNotIn("failed", str(dict(observed[0])))
|
|
|
|
def test_disabled_telemetry_has_no_side_effects(self):
|
|
observer = mock.Mock()
|
|
logger = mock.Mock()
|
|
telemetry = RuntimeTelemetry(
|
|
component="edge",
|
|
enabled=False,
|
|
observer=observer,
|
|
logger=logger,
|
|
)
|
|
|
|
self.assertEqual(dict(telemetry.emit("edge.test")), {})
|
|
observer.assert_not_called()
|
|
logger.info.assert_not_called()
|
|
self.assertEqual(telemetry.snapshot()["counts"], {})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|