towerops/test/snmpkit/snmp_lib/mib_test.exs
2026-06-15 11:15:46 -05:00

453 lines
12 KiB
Elixir

defmodule SnmpKit.SnmpLib.MIBTest do
use ExUnit.Case, async: true
alias SnmpKit.SnmpLib.MIB
alias SnmpKit.SnmpLib.MIB.Error
# doctest MIB
describe "compile/2" do
test "returns error for non-existent file" do
result = MIB.compile("nonexistent.mib")
assert {:error, errors} = result
refute Enum.empty?(errors)
assert %Error{type: :file_not_found} = List.first(errors)
end
test "returns error for invalid file path" do
result = MIB.compile("/invalid/path/to/mib.txt")
assert {:error, errors} = result
refute Enum.empty?(errors)
end
test "accepts empty options list" do
result = MIB.compile("test.mib", [])
assert {:error, _errors} = result
end
test "accepts output_dir option" do
result = MIB.compile("test.mib", output_dir: "/tmp/mibs")
assert {:error, _errors} = result
end
test "accepts include_dirs option" do
result = MIB.compile("test.mib", include_dirs: ["./priv/mibs", "/usr/share/mibs"])
assert {:error, _errors} = result
end
test "accepts log_level option" do
result = MIB.compile("test.mib", log_level: :debug)
assert {:error, _errors} = result
end
test "accepts format option with :elixir" do
result = MIB.compile("test.mib", format: :elixir)
assert {:error, _errors} = result
end
test "accepts format option with :erlang" do
result = MIB.compile("test.mib", format: :erlang)
assert {:error, _errors} = result
end
test "accepts format option with :both" do
result = MIB.compile("test.mib", format: :both)
assert {:error, _errors} = result
end
test "accepts optimize option" do
result = MIB.compile("test.mib", optimize: true)
assert {:error, _errors} = result
end
test "accepts warnings_as_errors option" do
result = MIB.compile("test.mib", warnings_as_errors: true)
assert {:error, _errors} = result
end
test "accepts vendor_quirks option" do
result = MIB.compile("test.mib", vendor_quirks: false)
assert {:error, _errors} = result
end
test "accepts multiple options together" do
result =
MIB.compile("test.mib",
output_dir: "/tmp",
format: :elixir,
optimize: true,
log_level: :warn
)
assert {:error, _errors} = result
end
test "returns error list with Error structs" do
result = MIB.compile("nonexistent.mib")
assert {:error, errors} = result
assert Enum.all?(errors, &match?(%Error{}, &1))
end
test "accepts relative file path" do
result = MIB.compile("./test/fixtures/test.mib")
assert {:error, _errors} = result
end
test "accepts absolute file path" do
result = MIB.compile("/absolute/path/to/mib.txt")
assert {:error, _errors} = result
end
end
describe "compile_string/2" do
@tag :yecc_required
test "returns error for empty string" do
result = MIB.compile_string("")
assert {:error, errors} = result
refute Enum.empty?(errors)
end
@tag :yecc_required
test "returns error for invalid MIB content" do
result = MIB.compile_string("invalid mib content")
assert {:error, errors} = result
refute Enum.empty?(errors)
end
@tag :yecc_required
test "accepts MIB header format" do
mib_content = """
TEST-MIB DEFINITIONS ::= BEGIN
END
"""
result = MIB.compile_string(mib_content)
# Should attempt to compile (may fail, but accepts the format)
assert is_tuple(result) and elem(result, 0) in [:ok, :error]
end
@tag :yecc_required
test "accepts empty options list" do
result = MIB.compile_string("TEST-MIB DEFINITIONS ::= BEGIN END", [])
assert is_tuple(result) and elem(result, 0) in [:ok, :error]
end
@tag :yecc_required
test "accepts output_dir option" do
result = MIB.compile_string("content", output_dir: "/tmp")
assert {:error, _errors} = result
end
@tag :yecc_required
test "accepts format option" do
result = MIB.compile_string("content", format: :elixir)
assert {:error, _errors} = result
end
@tag :yecc_required
test "accepts include_dirs option" do
result = MIB.compile_string("content", include_dirs: ["./priv/mibs"])
assert {:error, _errors} = result
end
@tag :yecc_required
test "accepts multiple options" do
result =
MIB.compile_string("content",
output_dir: "/tmp",
format: :erlang,
optimize: false
)
assert {:error, _errors} = result
end
@tag :yecc_required
test "handles binary string input" do
result = MIB.compile_string(<<65, 66, 67>>)
assert {:error, _errors} = result
end
@tag :yecc_required
test "handles long MIB content" do
long_content = String.duplicate("TEST-MIB DEFINITIONS ::= BEGIN\n", 100) <> "END"
result = MIB.compile_string(long_content)
assert is_tuple(result) and elem(result, 0) in [:ok, :error]
end
@tag :yecc_required
test "returns error list for invalid content" do
result = MIB.compile_string("invalid")
assert {:error, errors} = result
assert Enum.all?(errors, &match?(%Error{}, &1))
end
end
describe "load_compiled/1" do
test "returns error for non-existent compiled file" do
result = MIB.load_compiled("nonexistent_compiled.ex")
assert {:error, _reason} = result
end
test "returns error for invalid file path" do
result = MIB.load_compiled("/invalid/path/compiled.ex")
assert {:error, _reason} = result
end
test "accepts .ex file extension" do
result = MIB.load_compiled("lib/generated/test_mib.ex")
assert {:error, _reason} = result
end
test "accepts .beam file extension" do
result = MIB.load_compiled("lib/generated/test_mib.beam")
assert {:error, _reason} = result
end
test "accepts relative path" do
result = MIB.load_compiled("./compiled/mib.ex")
assert {:error, _reason} = result
end
test "accepts absolute path" do
result = MIB.load_compiled("/absolute/path/to/compiled.ex")
assert {:error, _reason} = result
end
test "error includes reason" do
result = MIB.load_compiled("nonexistent.ex")
assert {:error, reason} = result
valid? = is_atom(reason) or is_binary(reason) or is_tuple(reason)
assert valid?
end
end
describe "compile_all/2" do
test "returns error for empty list" do
result = MIB.compile_all([])
# Empty list might return {:ok, []} or {:error, ...} depending on implementation
assert is_tuple(result) and elem(result, 0) in [:ok, :error]
end
test "returns error for list with non-existent files" do
result = MIB.compile_all(["nonexistent1.mib", "nonexistent2.mib"])
assert {:error, errors} = result
refute Enum.empty?(errors)
end
test "accepts single file in list" do
result = MIB.compile_all(["test.mib"])
assert {:error, _errors} = result
end
test "accepts multiple files in list" do
result = MIB.compile_all(["file1.mib", "file2.mib", "file3.mib"])
assert {:error, _errors} = result
end
test "accepts empty options list" do
result = MIB.compile_all(["test.mib"], [])
assert {:error, _errors} = result
end
test "accepts output_dir option" do
result = MIB.compile_all(["test.mib"], output_dir: "/tmp")
assert {:error, _errors} = result
end
test "accepts format option" do
result = MIB.compile_all(["test.mib"], format: :elixir)
assert {:error, _errors} = result
end
test "accepts include_dirs option" do
result = MIB.compile_all(["test.mib"], include_dirs: ["./mibs"])
assert {:error, _errors} = result
end
test "accepts multiple options" do
result =
MIB.compile_all(["test.mib"],
output_dir: "/tmp",
format: :both,
optimize: true
)
assert {:error, _errors} = result
end
test "handles mix of valid and invalid file paths" do
result = MIB.compile_all(["valid.mib", "/invalid/path.mib", "another.mib"])
assert {:error, _errors} = result
end
test "error includes file associations" do
result = MIB.compile_all(["file1.mib", "file2.mib"])
assert {:error, errors} = result
# Errors should be associated with files
refute Enum.empty?(errors)
end
test "accepts list with dependency order" do
# Simulating dependency order: base MIBs first, dependent MIBs later
result = MIB.compile_all(["SNMPv2-SMI.txt", "SNMPv2-TC.txt", "RFC1213-MIB.txt"])
assert {:error, _errors} = result
end
end
describe "option validation" do
test "compile handles invalid option keys gracefully" do
result = MIB.compile("test.mib", invalid_key: "value")
# Should still attempt to compile, ignoring invalid keys
assert {:error, _errors} = result
end
@tag :yecc_required
test "compile_string handles invalid option keys gracefully" do
result = MIB.compile_string("content", invalid_key: "value")
assert {:error, _errors} = result
end
test "compile_all handles invalid option keys gracefully" do
result = MIB.compile_all(["test.mib"], invalid_key: "value")
assert {:error, _errors} = result
end
end
describe "return value structure" do
test "compile returns tuple with :error or :ok" do
result = MIB.compile("test.mib")
assert tuple_size(result) == 2
assert elem(result, 0) in [:ok, :error, :warning]
end
@tag :yecc_required
test "compile_string returns tuple with :error or :ok" do
result = MIB.compile_string("content")
assert tuple_size(result) == 2
assert elem(result, 0) in [:ok, :error, :warning]
end
test "load_compiled returns tuple with :error or :ok" do
result = MIB.load_compiled("compiled.ex")
assert tuple_size(result) == 2
assert elem(result, 0) in [:ok, :error]
end
test "compile_all returns tuple with :error or :ok" do
result = MIB.compile_all(["test.mib"])
assert tuple_size(result) == 2
assert elem(result, 0) in [:ok, :error]
end
end
describe "error handling" do
test "compile handles various file path errors gracefully" do
# These should all return errors without crashing
assert {:error, _} = MIB.compile("")
assert {:error, _} = MIB.compile("/nonexistent/path")
assert {:error, _} = MIB.compile("../../../etc/passwd")
end
@tag :yecc_required
test "compile_string handles invalid content gracefully" do
assert {:error, _} = MIB.compile_string("")
assert {:error, _} = MIB.compile_string("not valid MIB content")
assert {:error, _} = MIB.compile_string("123 456 789")
end
test "load_compiled handles invalid paths gracefully" do
assert {:error, _} = MIB.load_compiled("")
assert {:error, _} = MIB.load_compiled("/nonexistent/file.ex")
assert {:error, _} = MIB.load_compiled("../invalid/path.ex")
end
test "compile_all handles empty and invalid lists gracefully" do
# Empty list case
result = MIB.compile_all([])
assert is_tuple(result) and elem(result, 0) in [:ok, :error]
# List with invalid paths
assert {:error, _} = MIB.compile_all(["", "/nonexistent"])
end
end
describe "default options" do
test "compile uses defaults when options not provided" do
result1 = MIB.compile("test.mib")
result2 = MIB.compile("test.mib", [])
# Both should behave similarly with defaults
assert match?({:error, _}, result1)
assert match?({:error, _}, result2)
end
@tag :yecc_required
test "compile_string uses defaults when options not provided" do
result1 = MIB.compile_string("content")
result2 = MIB.compile_string("content", [])
assert match?({:error, _}, result1)
assert match?({:error, _}, result2)
end
test "compile_all uses defaults when options not provided" do
result1 = MIB.compile_all(["test.mib"])
result2 = MIB.compile_all(["test.mib"], [])
assert match?({:error, _}, result1)
assert match?({:error, _}, result2)
end
end
end