defmodule ToweropsNativeTest do use ExUnit.Case, async: false 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 oid1 = ToweropsNative.resolve_oid("SNMPv2-MIB::sysDescr") oid2 = ToweropsNative.resolve_oid("sysDescr") # Both should resolve to the same OID assert is_binary(oid1) assert is_binary(oid2) assert oid1 == oid2 assert oid1 == "1.3.6.1.2.1.1.1" end test "returns error tuple for invalid MIB names" do assert {:error, reason} = ToweropsNative.resolve_oid("nonExistentMibName") assert is_binary(reason) assert {:error, reason} = ToweropsNative.resolve_oid("invalidMibObject123") assert is_binary(reason) end test "handles empty strings" do assert {:error, reason} = ToweropsNative.resolve_oid("") assert is_binary(reason) 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