Files
hermes-agent/tests/monitoring/test_emitter.py
Teknium 7eb8ccc315 refactor(agent/runtime): monitoring — shared OTLP plumbing in otlp_exporter, event base class, EmitterStreamer, dedupe health export
- otlp_exporter hosts SDK loading (symbol table), header/endpoint/resource helpers
  shared with gateway_health_export; export module imports them instead of
  keeping copies (_otlp_config/_resolve_headers/_install_id/_safe_resource_attributes
  unified). _KEEP_BY_KIND attribute allowlist reused for diagnostic log attrs.
- events: _MonitoringEvent base supplies to_dict; field order (wire order) unchanged.
- redaction: redact_bounded() replaces 3 inline redact+truncate try/excepts.
- EmitterStreamer base owns the shared unsubscribe/flush/shutdown for
  OTLPStreamer and GatewayDiagnosticLogStreamer.
- gateway_health: metric construction helpers, _contains_any shared with
  cron_health, dead _allowed_logger/redact_gateway_message removed (0 refs).
- Comment/docstring compaction keeping every stated invariant.
2026-09-02 13:29:47 -07:00

67 lines
1.8 KiB
Python

"""Tests for the monitoring emitter: hot-path invariant + subscriber fan-out."""
from __future__ import annotations
import time
from agent.monitoring.emitter import MonitoringEmitter
def test_emit_never_raises_when_disabled():
em = MonitoringEmitter(enabled=False)
em.emit({"event": "gateway_health", "name": "gateway.health_snapshot"})
assert em.stats()["queued"] == 0
em.close()
def test_process_singleton_stays_dormant_until_subscribed():
from agent.monitoring import emitter
emitter.reset_emitter_for_tests()
try:
emitter.emit({"event": "gateway_health", "name": "gateway.lifecycle"})
singleton = emitter.get_emitter()
assert singleton.stats()["queued"] == 0
assert singleton._started is False
subscriber = lambda _batch: None # noqa: E731
singleton.subscribe(subscriber)
emitter.emit({"event": "gateway_health", "name": "gateway.lifecycle"})
assert singleton._started is True
singleton.unsubscribe(subscriber)
finally:
emitter.reset_emitter_for_tests()
def test_unsubscribe_stops_delivery():
em = MonitoringEmitter()
seen: list = []
cb = lambda batch: seen.extend(batch) # noqa: E731
em.subscribe(cb)
em.emit({"event": "gateway_health", "name": "a"})
em.flush()
em.unsubscribe(cb)
em.emit({"event": "gateway_health", "name": "b"})
em.flush()
em.close()
assert [ev["name"] for ev in seen] == ["a"]
def test_hot_path_is_fast():
em = MonitoringEmitter()
start = time.perf_counter()
for _ in range(1_000):
em.emit({"event": "gateway_health", "name": "gateway.health_snapshot"})
elapsed = time.perf_counter() - start
em.close()
# 1000 emits should be far under a second even on slow CI.
assert elapsed < 1.0