263 lines
9 KiB
Elixir
263 lines
9 KiB
Elixir
defmodule SnmpKit.SnmpMgr.FormatTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias SnmpKit.SnmpMgr.Format
|
|
|
|
doctest Format
|
|
|
|
describe "pretty_print/1 - new functionality" do
|
|
test "formats 3-tuple results with type-aware formatting" do
|
|
# Test timeticks formatting (delegates to SnmpKit.SnmpLib.Types)
|
|
result = {"1.3.6.1.2.1.1.3.0", :timeticks, 12_345_678}
|
|
{oid, type, formatted} = Format.pretty_print(result)
|
|
|
|
assert oid == "1.3.6.1.2.1.1.3.0"
|
|
assert type == :timeticks
|
|
assert String.contains?(formatted, "day")
|
|
end
|
|
|
|
test "formats large counter types as speed" do
|
|
# Counter32 values > 1,000,000 are formatted as speed
|
|
result = {"1.3.6.1.2.1.2.2.1.10.1", :counter32, 42_000_000}
|
|
{_oid, _type, formatted} = Format.pretty_print(result)
|
|
|
|
assert formatted == "42.0 Mbps"
|
|
end
|
|
|
|
test "formats small counter types as integers" do
|
|
# Counter32 values <= 1,000,000 are formatted as plain integers
|
|
result = {"1.3.6.1.2.1.2.2.1.10.1", :counter32, 500_000}
|
|
{_oid, _type, formatted} = Format.pretty_print(result)
|
|
|
|
assert formatted == "500000"
|
|
end
|
|
|
|
test "formats large gauge types as bytes" do
|
|
# Gauge32 values > 1,000,000 are formatted as bytes
|
|
result = {"1.3.6.1.2.1.2.2.1.5.1", :gauge32, 100_000_000}
|
|
{_oid, _type, formatted} = Format.pretty_print(result)
|
|
|
|
assert formatted == "95.4 MB"
|
|
end
|
|
|
|
test "formats small gauge types as integers" do
|
|
# Gauge32 values <= 1,000,000 are formatted as plain integers
|
|
result = {"1.3.6.1.2.1.2.2.1.5.1", :gauge32, 500_000}
|
|
{_oid, _type, formatted} = Format.pretty_print(result)
|
|
|
|
assert formatted == "500000"
|
|
end
|
|
|
|
test "formats object identifiers" do
|
|
# Test with OID list
|
|
result = {"1.3.6.1.2.1.1.2.0", :object_identifier, [1, 3, 6, 1, 4, 1, 9]}
|
|
{_oid, _type, formatted} = Format.pretty_print(result)
|
|
|
|
assert formatted == "1.3.6.1.4.1.9"
|
|
|
|
# Test with OID string
|
|
result2 = {"1.3.6.1.2.1.1.2.0", :object_identifier, "1.3.6.1.4.1.9"}
|
|
{_oid, _type, formatted2} = Format.pretty_print(result2)
|
|
|
|
assert formatted2 == "1.3.6.1.4.1.9"
|
|
end
|
|
|
|
test "handles unknown types gracefully" do
|
|
result = {"1.3.6.1.2.1.1.1.0", :unknown_type, "test value"}
|
|
{_oid, _type, formatted} = Format.pretty_print(result)
|
|
|
|
# Unknown types with printable binary values are returned as-is
|
|
assert formatted == "test value"
|
|
end
|
|
end
|
|
|
|
describe "pretty_print_all/1 - new functionality" do
|
|
test "formats list of SNMP results" do
|
|
results = [
|
|
{"1.3.6.1.2.1.1.3.0", :timeticks, 12_345},
|
|
{"1.3.6.1.2.1.2.2.1.10.1", :counter32, 42_000_000}
|
|
]
|
|
|
|
formatted = Format.pretty_print_all(results)
|
|
|
|
assert length(formatted) == 2
|
|
assert Enum.all?(formatted, fn {_oid, _type, value} -> is_binary(value) end)
|
|
end
|
|
end
|
|
|
|
describe "bytes/1 - new functionality" do
|
|
test "formats byte counts into human-readable sizes" do
|
|
assert Format.bytes(512) == "512 bytes"
|
|
assert Format.bytes(1024) == "1.0 KB"
|
|
assert Format.bytes(1_048_576) == "1.0 MB"
|
|
assert Format.bytes(1_073_741_824) == "1.0 GB"
|
|
assert Format.bytes(1_099_511_627_776) == "1.0 TB"
|
|
end
|
|
|
|
test "handles edge cases" do
|
|
assert Format.bytes(0) == "0 bytes"
|
|
assert Format.bytes(1023) == "1023 bytes"
|
|
assert Format.bytes(1536) == "1.5 KB"
|
|
end
|
|
|
|
test "handles non-integer input gracefully" do
|
|
result = Format.bytes("not a number")
|
|
assert String.contains?(result, "not a number")
|
|
end
|
|
end
|
|
|
|
describe "speed/1 - new functionality" do
|
|
test "formats network speeds into human-readable rates" do
|
|
assert Format.speed(100) == "100 bps"
|
|
assert Format.speed(1000) == "1.0 Kbps"
|
|
assert Format.speed(1_000_000) == "1.0 Mbps"
|
|
assert Format.speed(1_000_000_000) == "1.0 Gbps"
|
|
assert Format.speed(1_000_000_000_000) == "1.0 Tbps"
|
|
end
|
|
|
|
test "handles common network speeds" do
|
|
assert Format.speed(10_000_000) == "10.0 Mbps"
|
|
assert Format.speed(100_000_000) == "100.0 Mbps"
|
|
assert Format.speed(1_000_000_000) == "1.0 Gbps"
|
|
end
|
|
|
|
test "handles non-integer input gracefully" do
|
|
result = Format.speed("fast")
|
|
assert String.contains?(result, "fast")
|
|
end
|
|
end
|
|
|
|
describe "interface_status/1 - new functionality" do
|
|
test "formats standard interface status codes" do
|
|
assert Format.interface_status(1) == "up"
|
|
assert Format.interface_status(2) == "down"
|
|
assert Format.interface_status(3) == "testing"
|
|
assert Format.interface_status(4) == "unknown"
|
|
assert Format.interface_status(5) == "dormant"
|
|
assert Format.interface_status(6) == "notPresent"
|
|
assert Format.interface_status(7) == "lowerLayerDown"
|
|
end
|
|
|
|
test "handles unknown status codes" do
|
|
assert Format.interface_status(99) == "unknown(99)"
|
|
assert Format.interface_status(0) == "unknown(0)"
|
|
end
|
|
end
|
|
|
|
describe "interface_type/1 - new functionality" do
|
|
test "formats common interface types" do
|
|
assert Format.interface_type(1) == "other"
|
|
assert Format.interface_type(6) == "ethernetCsmacd"
|
|
assert Format.interface_type(24) == "softwareLoopback"
|
|
assert Format.interface_type(131) == "tunnel"
|
|
assert Format.interface_type(161) == "ieee80211"
|
|
end
|
|
|
|
test "handles unknown interface types" do
|
|
assert Format.interface_type(999) == "type999"
|
|
assert Format.interface_type(42) == "type42"
|
|
end
|
|
end
|
|
|
|
describe "mac_address/1" do
|
|
test "formats binary MAC address" do
|
|
mac_binary = <<0x00, 0x1B, 0x21, 0x3C, 0x4D, 0x5E>>
|
|
result = Format.mac_address(mac_binary)
|
|
assert result == "00:1b:21:3c:4d:5e"
|
|
end
|
|
|
|
test "formats list MAC address" do
|
|
mac_list = [0, 27, 33, 60, 77, 94]
|
|
result = Format.mac_address(mac_list)
|
|
assert result == "00:1b:21:3c:4d:5e"
|
|
end
|
|
|
|
test "handles uppercase hex values" do
|
|
mac_list = [255, 255, 255, 255, 255, 255]
|
|
result = Format.mac_address(mac_list)
|
|
assert result == "ff:ff:ff:ff:ff:ff"
|
|
end
|
|
|
|
test "handles all zeros" do
|
|
mac_binary = <<0, 0, 0, 0, 0, 0>>
|
|
result = Format.mac_address(mac_binary)
|
|
assert result == "00:00:00:00:00:00"
|
|
end
|
|
|
|
test "handles invalid input gracefully" do
|
|
result = Format.mac_address("invalid")
|
|
assert byte_size(result) > 0
|
|
end
|
|
end
|
|
|
|
describe "format_by_type/2 with MAC addresses" do
|
|
test "formats explicit MAC address type correctly" do
|
|
mac_binary = <<0x00, 0x1B, 0x21, 0x3C, 0x4D, 0x5E>>
|
|
result = Format.format_by_type(:mac_address, mac_binary)
|
|
assert result == "00:1b:21:3c:4d:5e"
|
|
end
|
|
|
|
test "formats non-printable octet strings as spaced hex with hex: prefix" do
|
|
short_binary = <<0x00, 0x1B>>
|
|
result = Format.format_by_type(:octet_string, short_binary)
|
|
assert result == "hex:00 1B"
|
|
|
|
six_byte_binary = <<0x00, 0x1B, 0x21, 0x3C, 0x4D, 0x5E>>
|
|
result2 = Format.format_by_type(:octet_string, six_byte_binary)
|
|
assert result2 == "hex:00 1B 21 3C 4D 5E"
|
|
end
|
|
|
|
test "formats explicit MAC addresses correctly" do
|
|
mac_string = "00:1b:21:3c:4d:5e"
|
|
result = Format.mac_address(mac_string)
|
|
assert result == "00:1b:21:3c:4d:5e"
|
|
end
|
|
end
|
|
|
|
describe "format_by_type/2 object identifier formatting" do
|
|
test "formats object identifier list as dotted decimal string" do
|
|
result = Format.format_by_type(:object_identifier, [1, 3, 6, 1, 4, 1, 14_988, 1])
|
|
assert result == "1.3.6.1.4.1.14988.1"
|
|
end
|
|
|
|
test "passes through object identifier string unchanged" do
|
|
result = Format.format_by_type(:object_identifier, "1.3.6.1.4.1.14988.1")
|
|
assert result == "1.3.6.1.4.1.14988.1"
|
|
end
|
|
|
|
test "handles single element object identifier" do
|
|
result = Format.format_by_type(:object_identifier, [1])
|
|
assert result == "1"
|
|
end
|
|
|
|
test "handles empty object identifier" do
|
|
result = Format.format_by_type(:object_identifier, [])
|
|
assert result == ""
|
|
end
|
|
end
|
|
|
|
describe "format_by_type/2 explicit type handling" do
|
|
test "formats explicit MAC address type as MAC" do
|
|
# Explicit MAC address type
|
|
mac_bytes = <<0x00, 0x1B, 0x21, 0x3C, 0x4D, 0x5E>>
|
|
result = Format.format_by_type(:mac_address, mac_bytes)
|
|
assert result == "00:1b:21:3c:4d:5e"
|
|
end
|
|
|
|
test "keeps octet strings as strings regardless of length" do
|
|
# Interface names should remain as strings
|
|
assert Format.format_by_type(:octet_string, "ether1") == "ether1"
|
|
assert Format.format_by_type(:octet_string, "ether2") == "ether2"
|
|
assert Format.format_by_type(:octet_string, "wifi1 ") == "wifi1 "
|
|
assert Format.format_by_type(:octet_string, "bridge") == "bridge"
|
|
assert Format.format_by_type(:octet_string, "wlan01") == "wlan01"
|
|
end
|
|
|
|
test "formats binary octet strings as spaced hex when non-printable" do
|
|
# Even 6-byte binary data should render as hex when not printable UTF-8
|
|
binary_data = <<0x00, 0x1B, 0x21, 0x3C, 0x4D, 0x5E>>
|
|
result = Format.format_by_type(:octet_string, binary_data)
|
|
assert result == "hex:00 1B 21 3C 4D 5E"
|
|
end
|
|
end
|
|
end
|