208 lines
5 KiB
Elixir
208 lines
5 KiB
Elixir
defmodule SnmpKit.SnmpLib.MIB.ParserTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias SnmpKit.SnmpLib.MIB.Parser
|
|
|
|
doctest Parser
|
|
|
|
@moduletag :parsing_edge_cases
|
|
@moduletag :yecc_required
|
|
|
|
describe "basic MIB parsing" do
|
|
test "parses minimal MIB structure" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
|
|
testRoot OBJECT IDENTIFIER ::= { iso 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
|
|
assert %{__type__: :mib, name: "TEST-MIB"} = mib
|
|
assert mib.imports == []
|
|
assert length(mib.definitions) == 1
|
|
end
|
|
|
|
test "parses MIB with imports" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
IMPORTS
|
|
DisplayString FROM SNMPv2-TC;
|
|
|
|
testRoot OBJECT IDENTIFIER ::= { iso 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
|
|
assert %{__type__: :mib, name: "TEST-MIB"} = mib
|
|
assert length(mib.imports) == 1
|
|
assert length(mib.definitions) >= 1
|
|
end
|
|
|
|
test "parses simple object identifier assignment" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
|
|
testObjects OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
|
|
assert %{__type__: :mib, name: "TEST-MIB"} = mib
|
|
assert length(mib.definitions) == 1
|
|
|
|
[definition] = mib.definitions
|
|
assert definition.name == "testObjects"
|
|
end
|
|
|
|
test "parses basic OBJECT-TYPE definition" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
|
|
testObjects OBJECT IDENTIFIER ::= { iso 1 }
|
|
|
|
testObject OBJECT-TYPE
|
|
SYNTAX INTEGER
|
|
MAX-ACCESS read-only
|
|
STATUS current
|
|
DESCRIPTION "A test object"
|
|
::= { testObjects 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
|
|
assert %{__type__: :mib, name: "TEST-MIB"} = mib
|
|
assert length(mib.definitions) == 2
|
|
|
|
object_type_def = Enum.find(mib.definitions, fn def -> def.name == "testObject" end)
|
|
assert object_type_def
|
|
assert object_type_def.name == "testObject"
|
|
assert object_type_def.description == "A test object"
|
|
end
|
|
end
|
|
|
|
describe "error handling" do
|
|
test "reports syntax errors with position" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
invalid syntax here
|
|
END
|
|
"""
|
|
|
|
assert {:error, error} = Parser.parse(mib_content)
|
|
assert is_tuple(error)
|
|
end
|
|
|
|
test "handles missing required clauses" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
testObject OBJECT-TYPE
|
|
SYNTAX INTEGER
|
|
::= { testObjects 1 }
|
|
END
|
|
"""
|
|
|
|
# Should fail due to missing MAX-ACCESS and STATUS
|
|
assert {:error, error} = Parser.parse(mib_content)
|
|
assert is_tuple(error)
|
|
end
|
|
|
|
test "handles unterminated MIB" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
testObject OBJECT-TYPE
|
|
SYNTAX INTEGER
|
|
"""
|
|
|
|
assert {:error, error} = Parser.parse(mib_content)
|
|
assert is_tuple(error)
|
|
end
|
|
end
|
|
|
|
describe "complex parsing" do
|
|
test "parses MIB with multiple imports" do
|
|
mib_content = """
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
IMPORTS
|
|
DisplayString, TimeStamp
|
|
FROM SNMPv2-TC
|
|
Counter32, Gauge32
|
|
FROM SNMPv2-SMI;
|
|
|
|
testRoot OBJECT IDENTIFIER ::= { iso 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
|
|
assert %{__type__: :mib, name: "TEST-MIB"} = mib
|
|
assert length(mib.imports) >= 1
|
|
assert length(mib.definitions) >= 1
|
|
end
|
|
|
|
test "handles comments in MIB content" do
|
|
mib_content = """
|
|
-- This is a test MIB
|
|
TEST-MIB DEFINITIONS ::= BEGIN
|
|
-- Comment before imports
|
|
IMPORTS
|
|
DisplayString FROM SNMPv2-TC; -- Inline comment
|
|
|
|
-- Comment before definition
|
|
testRoot OBJECT IDENTIFIER ::= { iso 1 }
|
|
|
|
-- Comment before end
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
|
|
assert %{__type__: :mib, name: "TEST-MIB"} = mib
|
|
end
|
|
end
|
|
|
|
describe "full parsing integration" do
|
|
test "parses MIB content with OBJECT-TYPE definitions" do
|
|
mib_content = """
|
|
SIMPLE-MIB DEFINITIONS ::= BEGIN
|
|
|
|
simpleObject OBJECT-TYPE
|
|
SYNTAX DisplayString
|
|
MAX-ACCESS read-only
|
|
STATUS current
|
|
DESCRIPTION "Simple test object"
|
|
::= { iso 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
assert %{__type__: :mib, name: "SIMPLE-MIB"} = mib
|
|
assert length(mib.definitions) == 1
|
|
end
|
|
|
|
test "handles simple MIB gracefully" do
|
|
mib_content = """
|
|
EMPTY-MIB DEFINITIONS ::= BEGIN
|
|
|
|
testRoot OBJECT IDENTIFIER ::= { iso 1 }
|
|
|
|
END
|
|
"""
|
|
|
|
assert {:ok, mib} = Parser.parse(mib_content)
|
|
assert %{__type__: :mib, name: "EMPTY-MIB"} = mib
|
|
assert length(mib.definitions) == 1
|
|
assert mib.imports == []
|
|
end
|
|
end
|
|
end
|