UPS-MIB upsSecondsOnBattery is zero whenever the UPS is on mains power, so "On battery for 0s" read as a timer that had just started. The reading gets its own unit, battery_seconds: zero says "No, on mains", anything else "for <span>". The metric key stays on_battery_for, so stored history keeps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
2.8 KiB
Python
70 lines
2.8 KiB
Python
"""What an SNMP device is asked for and how each answer reads (milestone 491)."""
|
|
import pytest
|
|
|
|
from plugins.snmp.readings import (device_readings, format_value, interface_readings, parse_custom,
|
|
parse_interfaces, stored_unit)
|
|
|
|
|
|
def test_interface_numbers_read_as_a_list():
|
|
assert parse_interfaces("1, 2 5-7,2") == [1, 2, 5, 6, 7]
|
|
assert parse_interfaces("") == []
|
|
for bad in ("eth0", "7-3", "1-100"):
|
|
with pytest.raises(ValueError):
|
|
parse_interfaces(bad)
|
|
|
|
|
|
def test_interfaces_read_64_bit_counters_except_on_v1():
|
|
v2 = {r.key: r for r in interface_readings([3], "2c")}
|
|
v1 = {r.key: r for r in interface_readings([3], "1")}
|
|
assert set(v2) == {"if3_status", "if3_in", "if3_out"}
|
|
assert v2["if3_in"].oid == "1.3.6.1.2.1.31.1.1.1.6.3" and v2["if3_in"].counter
|
|
assert v1["if3_in"].oid == "1.3.6.1.2.1.2.2.1.10.3"
|
|
assert stored_unit(v2["if3_out"]) == "bits_per_second" and not v2["if3_status"].counter
|
|
|
|
|
|
def test_a_custom_line_is_an_oid_a_name_and_a_unit():
|
|
got = parse_custom("# a comment\n.1.3.6.1.4.1.9.1.0 fan_speed\n1.3.6.1.4.1.9.2.0 inlet_temp celsius\n")
|
|
assert [(r.oid, r.key, r.name, r.unit) for r in got] == [
|
|
("1.3.6.1.4.1.9.1.0", "fan_speed", "Fan speed", "number"),
|
|
("1.3.6.1.4.1.9.2.0", "inlet_temp", "Inlet temp", "celsius")]
|
|
|
|
|
|
@pytest.mark.parametrize("line, says", [
|
|
("1.3.6.1", "OID name"),
|
|
("sysUpTime uptime", "is not an OID"),
|
|
("1.3.6.1.2 Bad-Name", "must start with a letter"),
|
|
("1.3.6.1.2 temp furlongs", "is not a unit"),
|
|
])
|
|
def test_a_custom_line_that_does_not_read_says_which_and_why(line, says):
|
|
with pytest.raises(ValueError, match="Line 1") as exc:
|
|
parse_custom(line)
|
|
assert says in str(exc.value)
|
|
|
|
|
|
def test_presets_come_in_order_and_names_may_not_repeat():
|
|
keys = [r.key for r in device_readings(["ups", "system", "interfaces"], [1], "", "2c")]
|
|
assert keys[:4] == ["uptime", "if1_status", "if1_in", "if1_out"] and "battery_charge" in keys
|
|
with pytest.raises(ValueError, match="uptime"):
|
|
device_readings(["system"], [], "1.3.6.1.2.1.1.3.0 uptime", "2c")
|
|
|
|
|
|
@pytest.mark.parametrize("unit, value, text", [
|
|
("centiseconds", 105_120_000, "12d 4h"),
|
|
("percent", 99.6, "100%"),
|
|
("volts", 121.0, "121 V"),
|
|
("decivolts", 1203, "120.3 V"),
|
|
("minutes", 45, "45m"),
|
|
("battery_seconds", 0, "No, on mains"),
|
|
("battery_seconds", 300, "for 5m"),
|
|
("kilobytes", 2048, "2.0 MiB"),
|
|
("bits_per_second", 12_345_678, "12.3 Mbit/s"),
|
|
("bits_per_second", 950, "950 bit/s"),
|
|
("if_status", 2, "down"),
|
|
("ups_battery", 3, "low"),
|
|
("if_status", 99, "code 99"),
|
|
("number", 41.25, "41.25"),
|
|
("number", None, "—"),
|
|
])
|
|
def test_a_value_reads_in_its_unit(unit, value, text):
|
|
assert format_value(unit, value) == text
|