453 lines
12 KiB
Elixir
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
|