2025-11-28 14:35:21 +08:00

133 lines
4.2 KiB
Python

import time
from exporter.metrics import TransceiverCollector
from exporter.models import (
DeviceHealthState,
DeviceMetricsSnapshot,
TransceiverChannelRecord,
TransceiverRecord,
)
def _collect_metrics(collector: TransceiverCollector):
return list(collector.collect())
def test_collector_exports_transceiver_and_info_with_component_name():
snapshot = DeviceMetricsSnapshot(
device="dev1",
collected_at=time.time(),
transceivers=(
TransceiverRecord(
device="dev1",
component_name="comp1",
logical_port="1/0/1",
present="PRESENT",
oper_status="ACTIVE",
temperature_c=40.0,
supply_voltage_v=3.3,
vendor="H3C",
serial="SN1",
part_number="PN",
hardware_rev="1.0",
),
),
channels=(),
)
cache = {"dev1": snapshot}
health = {
"dev1": DeviceHealthState(
last_scrape_success=True,
last_scrape_duration=0.1,
last_scrape_timestamp=time.time(),
last_error_type=None,
)
}
collector = TransceiverCollector(cache, health)
metrics = _collect_metrics(collector)
temp_metric = [m for m in metrics if m.name == "transceiver_temperature_celsius"][0]
sample = temp_metric.samples[0]
assert sample.value == 40.0
assert sample.labels["device"] == "dev1"
assert sample.labels["port"] == "1/0/1"
assert sample.labels["component_name"] == "comp1"
info_metric = [m for m in metrics if m.name == "transceiver_info"][0]
info_labels = info_metric.samples[0].labels
assert info_labels["device"] == "dev1"
assert info_labels["component_name"] == "comp1"
assert info_labels["vendor"] == "H3C"
assert info_labels["serial"] == "SN1"
def test_collector_channel_metrics_include_component_name():
snapshot = DeviceMetricsSnapshot(
device="dev1",
collected_at=time.time(),
transceivers=(),
channels=(
TransceiverChannelRecord(
device="dev1",
component_name="comp1",
logical_port="1/0/1",
channel_index=0,
logical_channel="1/0/1:1",
rx_power_dbm=-3.0,
tx_power_dbm=-1.0,
bias_current_ma=10.0,
laser_temperature_c=25.0,
),
),
)
cache = {"dev1": snapshot}
health = {
"dev1": DeviceHealthState(
last_scrape_success=True,
last_scrape_duration=0.1,
last_scrape_timestamp=time.time(),
last_error_type=None,
)
}
collector = TransceiverCollector(cache, health)
metrics = _collect_metrics(collector)
tx_metric = [m for m in metrics if m.name == "transceiver_channel_tx_power_dbm"][0]
sample = tx_metric.samples[0]
assert sample.labels["device"] == "dev1"
assert sample.labels["port"] == "1/0/1"
assert sample.labels["channel"] == "1/0/1:1"
assert sample.labels["component_name"] == "comp1"
info_metric = [m for m in metrics if m.name == "transceiver_channel_info"][0]
info_labels = info_metric.samples[0].labels
assert info_labels["device"] == "dev1"
assert info_labels["channel"] == "1/0/1:1"
assert info_labels["component_name"] == "comp1"
def test_collector_no_business_metrics_on_failure():
cache = {} # 没有成功快照
health = {
"dev1": DeviceHealthState(
last_scrape_success=False,
last_scrape_duration=0.2,
last_scrape_timestamp=time.time(),
last_error_type="TimeoutError",
)
}
collector = TransceiverCollector(cache, health)
metrics = _collect_metrics(collector)
# 有健康指标
success_metric = [m for m in metrics if m.name == "netconf_scrape_success"][0]
assert any(s.labels["device"] == "dev1" and s.value == 0 for s in success_metric.samples)
# 不应有 transceiver_temperature_celsius
temp_metrics = [m for m in metrics if m.name == "transceiver_temperature_celsius"]
assert not temp_metrics or not temp_metrics[0].samples