test: Profiles.Dynamic vendor post-processing + debug data branches
This commit is contained in:
parent
587e81bdad
commit
910298b6eb
1 changed files with 248 additions and 0 deletions
248
test/towerops/snmp/profiles/dynamic_extra_test.exs
Normal file
248
test/towerops/snmp/profiles/dynamic_extra_test.exs
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
defmodule Towerops.Snmp.Profiles.DynamicExtraTest do
|
||||
@moduledoc """
|
||||
Targets uncovered branches in `Towerops.Snmp.Profiles.Dynamic`:
|
||||
|
||||
* `collect_vendor_debug_data/2` — debug data with state sensors
|
||||
(state_descr branch) and wireless OID error/value paths
|
||||
* `walk_descr_oid/2` empty walk fallback (no descr map)
|
||||
* `apply_vendor_post_processing` for `arista_eos`, `arista-mos`,
|
||||
`dell-powervault` profile names (delegates to vendor modules)
|
||||
* `get_vendor_wireless_oids/1` no-name fallback path via
|
||||
`collect_vendor_debug_data` on profile without vendor module
|
||||
* `has_mib_symbolic_name?/1` non-binary clause (e.g. `nil` description)
|
||||
"""
|
||||
|
||||
use Towerops.DataCase, async: true
|
||||
|
||||
import Mox
|
||||
|
||||
alias Towerops.Snmp.Profiles.Dynamic
|
||||
alias Towerops.Snmp.SnmpMock
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
@client_opts [
|
||||
ip: "192.168.1.1",
|
||||
community: "public",
|
||||
version: "2c",
|
||||
port: 161,
|
||||
timeout: 5000
|
||||
]
|
||||
|
||||
defp base_profile(overrides \\ %{}) do
|
||||
Map.merge(
|
||||
%{
|
||||
name: "test_device",
|
||||
vendor: "TestVendor",
|
||||
type: "router",
|
||||
device_oids: %{},
|
||||
sensor_oids: [],
|
||||
table_sensor_oids: [],
|
||||
processor_oids: [],
|
||||
count_sensor_oids: [],
|
||||
state_sensor_oids: []
|
||||
},
|
||||
overrides
|
||||
)
|
||||
end
|
||||
|
||||
describe "collect_vendor_debug_data/2" do
|
||||
test "includes state sensors with state_descr in discovered_sensors" do
|
||||
profile =
|
||||
base_profile(%{
|
||||
state_sensor_oids: [
|
||||
%{
|
||||
base_oid: "1.3.6.1.4.1.99999.4.1",
|
||||
oid_name: "gps_status",
|
||||
sensor_type: "state",
|
||||
sensor_descr: "GPS Status",
|
||||
states: %{0 => "No Fix", 2 => "3D Fix"}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
|
||||
stub(SnmpMock, :walk, fn _, oid, _ ->
|
||||
case oid do
|
||||
"1.3.6.1.4.1.99999.4.1" ->
|
||||
{:ok, [%{oid: "1.3.6.1.4.1.99999.4.1.0", value: {:integer, 2}}]}
|
||||
|
||||
_ ->
|
||||
{:ok, []}
|
||||
end
|
||||
end)
|
||||
|
||||
result = Dynamic.collect_vendor_debug_data(profile, @client_opts)
|
||||
|
||||
assert is_list(result.discovered_sensors)
|
||||
assert is_map(result.wireless_sensors)
|
||||
|
||||
# State sensor adds state_descr field to debug entry
|
||||
state_entry = Enum.find(result.discovered_sensors, fn s -> Map.has_key?(s, :state_descr) end)
|
||||
assert state_entry, "expected at least one entry with :state_descr key"
|
||||
assert state_entry.state_descr == "3D Fix"
|
||||
assert state_entry.type == "state"
|
||||
end
|
||||
|
||||
test "returns empty wireless_sensors map for profile with no vendor module" do
|
||||
# `nonexistent_vendor` has no module in VendorRegistry, so
|
||||
# get_vendor_wireless_oids returns []. wireless_sensors stays %{}.
|
||||
profile = base_profile(%{name: "nonexistent_vendor_zzz"})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
stub(SnmpMock, :walk, fn _, _, _ -> {:ok, []} end)
|
||||
|
||||
result = Dynamic.collect_vendor_debug_data(profile, @client_opts)
|
||||
|
||||
assert result.wireless_sensors == %{}
|
||||
assert is_list(result.discovered_sensors)
|
||||
end
|
||||
|
||||
test "handles profile without :name key in get_vendor_wireless_oids" do
|
||||
# When profile has no :name key, get_vendor_wireless_oids returns []
|
||||
# (the function-clause fallback). We need to provide all keys that
|
||||
# discover_sensors reads via Map.get.
|
||||
profile = %{
|
||||
vendor: "Anon",
|
||||
type: "router",
|
||||
device_oids: %{},
|
||||
sensor_oids: [],
|
||||
table_sensor_oids: [],
|
||||
processor_oids: [],
|
||||
count_sensor_oids: [],
|
||||
state_sensor_oids: []
|
||||
}
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
stub(SnmpMock, :walk, fn _, _, _ -> {:ok, []} end)
|
||||
|
||||
result = Dynamic.collect_vendor_debug_data(profile, @client_opts)
|
||||
|
||||
assert result.wireless_sensors == %{}
|
||||
assert result.discovered_sensors == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "discover_sensors/2 descr_oid empty walk fallback" do
|
||||
test "uses default sensor description when descr_oid walk returns error" do
|
||||
# descr_oid returns error -> walk_descr_oid returns %{} -> default desc used
|
||||
profile =
|
||||
base_profile(%{
|
||||
table_sensor_oids: [
|
||||
%{
|
||||
base_oid: "1.3.6.1.4.1.99999.3.1",
|
||||
descr_oid: "1.3.6.1.4.1.99999.3.2",
|
||||
sensor_type: "temperature",
|
||||
sensor_descr: "Temp",
|
||||
sensor_unit: "C",
|
||||
sensor_divisor: 1
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
|
||||
stub(SnmpMock, :walk, fn _, oid, _ ->
|
||||
case oid do
|
||||
"1.3.6.1.4.1.99999.3.1" ->
|
||||
{:ok, [%{oid: "1.3.6.1.4.1.99999.3.1.1", value: {:integer, 42}}]}
|
||||
|
||||
"1.3.6.1.4.1.99999.3.2" ->
|
||||
# Errored descr walk - hits walk_descr_oid catch-all returning %{}
|
||||
{:error, :timeout}
|
||||
|
||||
_ ->
|
||||
{:ok, []}
|
||||
end
|
||||
end)
|
||||
|
||||
assert {:ok, sensors} = Dynamic.discover_sensors(profile, @client_opts)
|
||||
|
||||
sensor = Enum.find(sensors, &(&1.sensor_type == "temperature"))
|
||||
assert sensor.sensor_descr == "Temp"
|
||||
end
|
||||
end
|
||||
|
||||
describe "discover_sensors/2 vendor post-processing" do
|
||||
test "arista_eos profile delegates to Arista.post_process_sensors" do
|
||||
profile =
|
||||
Map.merge(base_profile(), %{
|
||||
name: "arista_eos",
|
||||
vendor: "Arista"
|
||||
})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
stub(SnmpMock, :walk, fn _, _, _ -> {:ok, []} end)
|
||||
|
||||
assert {:ok, sensors} = Dynamic.discover_sensors(profile, @client_opts)
|
||||
# No sensors discovered - post_process_sensors is called with empty list
|
||||
# and returns it unchanged.
|
||||
assert is_list(sensors)
|
||||
end
|
||||
|
||||
test "arista-mos profile delegates to Arista.post_process_sensors" do
|
||||
profile =
|
||||
Map.merge(base_profile(), %{
|
||||
name: "arista-mos",
|
||||
vendor: "Arista"
|
||||
})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
stub(SnmpMock, :walk, fn _, _, _ -> {:ok, []} end)
|
||||
|
||||
assert {:ok, sensors} = Dynamic.discover_sensors(profile, @client_opts)
|
||||
assert is_list(sensors)
|
||||
end
|
||||
|
||||
test "dell-powervault profile delegates to Powervault.post_process_sensors" do
|
||||
profile =
|
||||
Map.merge(base_profile(), %{
|
||||
name: "dell-powervault",
|
||||
vendor: "Dell"
|
||||
})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
stub(SnmpMock, :walk, fn _, _, _ -> {:ok, []} end)
|
||||
|
||||
assert {:ok, sensors} = Dynamic.discover_sensors(profile, @client_opts)
|
||||
assert is_list(sensors)
|
||||
end
|
||||
end
|
||||
|
||||
describe "discover_sensors/2 deduplication with non-binary description" do
|
||||
test "does not crash when sensor description is nil" do
|
||||
# has_mib_symbolic_name? must handle non-binary (nil) values without
|
||||
# crashing — covered by the catch-all clause `defp has_mib_symbolic_name?(_)`.
|
||||
# Discover sensors so that one ends up with no sensor_descr.
|
||||
profile =
|
||||
base_profile(%{
|
||||
table_sensor_oids: [
|
||||
%{
|
||||
base_oid: "1.3.6.1.4.1.99999.3.1",
|
||||
sensor_type: nil,
|
||||
# No sensor_descr, no oid_name -> falls back to sensor_type which is nil
|
||||
sensor_unit: "",
|
||||
sensor_divisor: 1,
|
||||
descr_oid: nil
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
stub(SnmpMock, :get, fn _, _, _ -> {:error, :no_such_object} end)
|
||||
|
||||
stub(SnmpMock, :walk, fn _, oid, _ ->
|
||||
case oid do
|
||||
"1.3.6.1.4.1.99999.3.1" ->
|
||||
{:ok, [%{oid: "1.3.6.1.4.1.99999.3.1.1", value: {:integer, 42}}]}
|
||||
|
||||
_ ->
|
||||
{:ok, []}
|
||||
end
|
||||
end)
|
||||
|
||||
# Just verifying no crash occurs
|
||||
assert {:ok, _sensors} = Dynamic.discover_sensors(profile, @client_opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue