145 lines
4.7 KiB
Elixir
145 lines
4.7 KiB
Elixir
defmodule ToweropsNativeTest do
|
|
use ExUnit.Case, async: false
|
|
|
|
doctest ToweropsNative
|
|
|
|
# Suppress false positive dialyzer warnings for NIF return types
|
|
@dialyzer :no_match
|
|
|
|
# NIF not compiled in this worktree — skip all tests
|
|
@moduletag :skip
|
|
|
|
setup do
|
|
# Initialize MIB library (auto-initializes on first resolve_oid call anyway)
|
|
result = ToweropsNative.init_mib_library()
|
|
assert result in ["initialized", "already_initialized"]
|
|
|
|
# Load MIBs before tests run
|
|
mib_dir = Application.app_dir(:towerops, "priv/mibs")
|
|
assert :ok = ToweropsNative.load_mib_directory(mib_dir)
|
|
|
|
:ok
|
|
end
|
|
|
|
describe "init_mib_library/0" do
|
|
test "initializes successfully and returns status" do
|
|
# Should return "initialized" or "already_initialized"
|
|
result = ToweropsNative.init_mib_library()
|
|
assert result in ["initialized", "already_initialized"]
|
|
end
|
|
|
|
test "returns already_initialized on subsequent calls" do
|
|
# First call
|
|
ToweropsNative.init_mib_library()
|
|
|
|
# Second call should return already_initialized
|
|
result = ToweropsNative.init_mib_library()
|
|
assert result == "already_initialized"
|
|
end
|
|
end
|
|
|
|
describe "load_mib_directory/1" do
|
|
test "returns ok for valid directory path" do
|
|
mib_dir = Application.app_dir(:towerops, "priv/mibs")
|
|
assert :ok = ToweropsNative.load_mib_directory(mib_dir)
|
|
end
|
|
|
|
test "handles paths with spaces" do
|
|
# Create a temporary directory with spaces
|
|
temp_dir = System.tmp_dir!()
|
|
dir_with_spaces = Path.join(temp_dir, "test dir with spaces")
|
|
File.mkdir_p!(dir_with_spaces)
|
|
|
|
# Should not crash and return :ok
|
|
assert :ok = ToweropsNative.load_mib_directory(dir_with_spaces)
|
|
|
|
# Cleanup
|
|
File.rm_rf!(dir_with_spaces)
|
|
end
|
|
end
|
|
|
|
describe "resolve_oid/1" do
|
|
test "resolves standard MIB names to exact OIDs" do
|
|
# sysDescr = 1.3.6.1.2.1.1.1
|
|
assert "1.3.6.1.2.1.1.1" = ToweropsNative.resolve_oid("sysDescr")
|
|
|
|
# sysObjectID = 1.3.6.1.2.1.1.2
|
|
assert "1.3.6.1.2.1.1.2" = ToweropsNative.resolve_oid("sysObjectID")
|
|
|
|
# sysUpTime = 1.3.6.1.2.1.1.3
|
|
assert "1.3.6.1.2.1.1.3" = ToweropsNative.resolve_oid("sysUpTime")
|
|
|
|
# sysContact = 1.3.6.1.2.1.1.4
|
|
assert "1.3.6.1.2.1.1.4" = ToweropsNative.resolve_oid("sysContact")
|
|
|
|
# sysName = 1.3.6.1.2.1.1.5
|
|
assert "1.3.6.1.2.1.1.5" = ToweropsNative.resolve_oid("sysName")
|
|
|
|
# sysLocation = 1.3.6.1.2.1.1.6
|
|
assert "1.3.6.1.2.1.1.6" = ToweropsNative.resolve_oid("sysLocation")
|
|
end
|
|
|
|
test "resolves vendor MIB names if available" do
|
|
# IEEE802dot11-MIB::dot11manufacturerProductName
|
|
# = 1.2.840.10036.3.1.2.1.3
|
|
# Note: This MIB may not be available on all systems
|
|
case ToweropsNative.resolve_oid("dot11manufacturerProductName") do
|
|
oid when is_binary(oid) ->
|
|
assert String.starts_with?(oid, "1.2.840.10036")
|
|
|
|
{:error, _reason} ->
|
|
# Vendor MIB not installed - that's OK, skip this test
|
|
:ok
|
|
end
|
|
|
|
# IEEE802dot11-MIB::dot11manufacturerProductVersion
|
|
# = 1.2.840.10036.3.1.2.1.4
|
|
case ToweropsNative.resolve_oid("dot11manufacturerProductVersion") do
|
|
oid when is_binary(oid) ->
|
|
assert String.starts_with?(oid, "1.2.840.10036")
|
|
|
|
{:error, _reason} ->
|
|
# Vendor MIB not installed - that's OK, skip this test
|
|
:ok
|
|
end
|
|
end
|
|
|
|
test "handles MODULE::name format" do
|
|
# net-snmp natively supports MODULE::name format
|
|
assert "1.3.6.1.2.1.1.1" = ToweropsNative.resolve_oid("SNMPv2-MIB::sysDescr")
|
|
assert "1.3.6.1.2.1.1.1" = ToweropsNative.resolve_oid("sysDescr")
|
|
end
|
|
|
|
test "returns error tuple for invalid MIB names" do
|
|
assert {:error, reason} = ToweropsNative.resolve_oid("nonExistentMibName")
|
|
assert is_binary(reason) and byte_size(reason) > 0
|
|
|
|
assert {:error, reason} = ToweropsNative.resolve_oid("invalidMibObject123")
|
|
assert is_binary(reason) and byte_size(reason) > 0
|
|
end
|
|
|
|
test "handles empty strings" do
|
|
assert {:error, reason} = ToweropsNative.resolve_oid("")
|
|
assert is_binary(reason) and byte_size(reason) > 0
|
|
end
|
|
|
|
test "performance is fast after initial load" do
|
|
# Warm up cache with first call
|
|
ToweropsNative.resolve_oid("sysDescr")
|
|
|
|
# Measure 100 resolutions
|
|
{time_microseconds, _result} =
|
|
:timer.tc(fn ->
|
|
for _ <- 1..100 do
|
|
ToweropsNative.resolve_oid("sysDescr")
|
|
end
|
|
end)
|
|
|
|
avg_time_per_resolution = time_microseconds / 100
|
|
|
|
# Should be under 100µs per resolution on average
|
|
assert avg_time_per_resolution < 100,
|
|
"Average resolution time was #{avg_time_per_resolution}µs, expected < 100µs"
|
|
end
|
|
end
|
|
end
|