towerops/test/snmpkit/snmp_lib/mib/logger_test.exs
mayor 82b4dbdf28
test: add comprehensive tests for PDU.Constants and MIB.Logger
Added complete test coverage for two low-coverage modules:

**PDU.Constants (11.65% -> target 100%)**:
- Error status code accessors and conversions
- SNMPv3 constants (USM security model, max message size)
- PDU type constants and tag conversion (get, getnext, response, set, getbulk)
- Data type constants and tag conversion (all SNMP types)
- SNMP version normalization (:v1, :v2c, :v3)
- OID normalization (list and string formats)
- SNMPv3 message flags encoding/decoding
- Default message flags for security levels
- Error status code/atom conversion
- Roundtrip encoding/decoding verification
- 43 new tests

**MIB.Logger (11.11% -> target 100%)**:
- Compilation lifecycle logging (start, success, error, warning, complete)
- Batch compilation logging (start, progress, success, error)
- Parse progress and import resolution logging
- Code generation and tokenization statistics
- Dependency order and performance metrics
- Vendor quirk handling
- Warning logging with context
- Error type extraction and aggregation
- 40 new tests

Total: 83 new tests added
Test count: 1,128 -> 1,211 (all passing)
2026-02-06 08:36:20 -06:00

405 lines
11 KiB
Elixir

defmodule SnmpKit.SnmpLib.MIB.LoggerTest do
use ExUnit.Case, async: false
import ExUnit.CaptureLog
alias SnmpKit.SnmpLib.MIB.Logger, as: MibLogger
alias SnmpKit.SnmpLib.MIB.Error
describe "log_compilation_start/2" do
test "logs compilation start with options" do
opts = [
output_dir: "/tmp/mibs",
format: :binary,
optimize: true,
vendor_quirks: [:cisco]
]
capture_log(fn ->
assert :ok = MibLogger.log_compilation_start("/path/to/test.mib", opts)
end)
end
test "handles empty options" do
capture_log(fn ->
assert :ok = MibLogger.log_compilation_start("/path/to/test.mib", [])
end)
end
end
describe "log_compilation_success/2" do
test "logs successful compilation" do
capture_log(fn ->
assert :ok = MibLogger.log_compilation_success("TEST-MIB", "/tmp/mibs/TEST-MIB.bin")
end)
end
end
describe "log_compilation_error/2" do
test "logs compilation errors with error list" do
errors = [
%Error{type: :syntax_error, message: "Unexpected token"},
%Error{type: :semantic_error, message: "Undefined symbol"}
]
log =
capture_log(fn ->
assert :ok = MibLogger.log_compilation_error("TEST-MIB", errors)
end)
assert log =~ "MIB compilation failed"
end
test "logs empty error list" do
capture_log(fn ->
assert :ok = MibLogger.log_compilation_error("TEST-MIB", [])
end)
end
end
describe "log_compilation_warning/3" do
test "logs compilation with warnings" do
warnings = [
%Error{type: :deprecated_syntax, message: "Old syntax used"},
%Error{type: :naming_convention, message: "Non-standard naming"}
]
capture_log(fn ->
assert :ok =
MibLogger.log_compilation_warning("TEST-MIB", "/tmp/mibs/TEST-MIB.bin", warnings)
end)
end
test "logs with empty warnings" do
capture_log(fn ->
assert :ok = MibLogger.log_compilation_warning("TEST-MIB", "/tmp/output", [])
end)
end
end
describe "log_batch_compilation_start/1" do
test "logs batch compilation start" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_compilation_start(10)
end)
end
test "handles zero file count" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_compilation_start(0)
end)
end
end
describe "log_batch_compilation_success/1" do
test "logs batch compilation success" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_compilation_success(8)
end)
end
end
describe "log_batch_compilation_error/2" do
test "logs batch compilation with errors" do
log =
capture_log(fn ->
assert :ok = MibLogger.log_batch_compilation_error(5, 3)
end)
assert log =~ "Batch MIB compilation completed with errors"
end
test "handles all errors" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_compilation_error(0, 10)
end)
end
end
describe "log_compilation_complete/2" do
test "logs compilation complete with results" do
result = %{
objects_count: 150,
output_path: "/tmp/mibs/TEST-MIB.bin",
compilation_time: 1250
}
capture_log(fn ->
assert :ok = MibLogger.log_compilation_complete("TEST-MIB", result)
end)
end
test "handles empty result map" do
capture_log(fn ->
assert :ok = MibLogger.log_compilation_complete("TEST-MIB", %{})
end)
end
end
describe "log_compilation_failed/2" do
test "logs compilation failure with error types" do
errors = [
%Error{type: :syntax_error, message: "Error 1"},
%Error{type: :syntax_error, message: "Error 2"},
%Error{type: :semantic_error, message: "Error 3"}
]
log =
capture_log(fn ->
assert :ok = MibLogger.log_compilation_failed("/path/to/test.mib", errors)
end)
assert log =~ "MIB compilation failed"
end
test "handles errors with different formats" do
errors = [
%Error{type: :syntax_error, message: "Error"},
%{type: :custom_error},
:atom_error,
"string error"
]
capture_log(fn ->
assert :ok = MibLogger.log_compilation_failed("/path/to/test.mib", errors)
end)
end
end
describe "log_parse_progress/2" do
test "logs parsing progress" do
log =
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_parse_progress("tokenization", 1500)
end)
assert log =~ "Parse progress" or log == ""
end
test "handles zero count" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_parse_progress("parsing", 0)
end)
end
end
describe "log_import_resolution/2" do
test "logs import resolution" do
imported_mibs = ["SNMPv2-SMI", "SNMPv2-TC", "SNMPv2-CONF"]
log =
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_import_resolution("TEST-MIB", imported_mibs)
end)
assert log =~ "Resolving imports" or log == ""
end
test "handles empty imports" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_import_resolution("TEST-MIB", [])
end)
end
end
describe "log_imports_resolved/3" do
test "logs successful import resolution" do
log =
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_imports_resolved("TEST-MIB", 8, 10)
end)
assert log =~ "Imports resolved" or log == ""
end
test "handles all imports resolved" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_imports_resolved("TEST-MIB", 5, 5)
end)
end
test "handles zero total imports" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_imports_resolved("TEST-MIB", 0, 0)
end)
end
end
describe "log_codegen/3" do
test "logs code generation results" do
capture_log(fn ->
assert :ok = MibLogger.log_codegen("TEST-MIB", 100, 350)
end)
end
test "handles zero objects" do
capture_log(fn ->
assert :ok = MibLogger.log_codegen("TEST-MIB", 0, 0)
end)
end
end
describe "log_tokenization/3" do
test "logs tokenization statistics" do
log =
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_tokenization("TEST-MIB", 5000, 250)
end)
assert log =~ "Tokenization complete" or log == ""
end
test "handles zero lines" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_tokenization("TEST-MIB", 0, 0)
end)
end
end
describe "log_dependency_order/1" do
test "logs dependency resolution order" do
mib_order = ["SNMPv2-SMI", "SNMPv2-TC", "IF-MIB", "TEST-MIB"]
log =
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_dependency_order(mib_order)
end)
assert log =~ "Dependency resolution complete" or log == ""
end
test "handles empty order" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_dependency_order([])
end)
end
end
describe "log_performance/2" do
test "logs performance metrics" do
metrics = [
duration_ms: 1234,
memory_mb: 45.6,
cpu_usage: 23.5
]
log =
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_performance("compilation", metrics)
end)
assert log =~ "Performance metrics" or log == ""
end
test "handles empty metrics" do
capture_log([level: :debug], fn ->
assert :ok = MibLogger.log_performance("test_phase", [])
end)
end
end
describe "log_warning/2" do
test "logs warning with context" do
context = %{file: "test.mib", line: 42, column: 10}
capture_log(fn ->
assert :ok = MibLogger.log_warning("Deprecated syntax detected", context)
end)
end
test "logs warning without context" do
capture_log(fn ->
assert :ok = MibLogger.log_warning("Simple warning")
end)
end
test "handles empty context" do
capture_log(fn ->
assert :ok = MibLogger.log_warning("Warning message", %{})
end)
end
end
describe "log_vendor_quirk/3" do
test "logs vendor quirk handling" do
log =
capture_log([level: :debug], fn ->
assert :ok =
MibLogger.log_vendor_quirk(
"CISCO-MIB",
"Cisco",
"Non-standard SEQUENCE syntax"
)
end)
assert log =~ "Vendor quirk handled" or log == ""
end
end
describe "log_batch_progress/2" do
test "logs batch compilation progress" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_progress(7, 10)
end)
end
test "handles zero total" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_progress(0, 0)
end)
end
test "handles completion" do
capture_log(fn ->
assert :ok = MibLogger.log_batch_progress(10, 10)
end)
end
end
describe "error type extraction" do
test "extracts error types from different error formats" do
errors = [
%Error{type: :syntax_error, message: "Test"},
%Error{type: :syntax_error, message: "Test2"},
%Error{type: :semantic_error, message: "Test3"},
%{type: :custom_error},
:atom_error,
"string error",
123
]
# This tests the private extract_error_type function indirectly
log =
capture_log(fn ->
assert :ok = MibLogger.log_compilation_failed("/test.mib", errors)
end)
assert log =~ "MIB compilation failed"
end
end
describe "return values" do
test "all logging functions return :ok" do
# Verify return values without log capture
assert :ok = MibLogger.log_compilation_start("/test.mib", [])
assert :ok = MibLogger.log_compilation_success("TEST", "/output")
assert :ok = MibLogger.log_compilation_error("TEST", [])
assert :ok = MibLogger.log_compilation_warning("TEST", "/output", [])
assert :ok = MibLogger.log_batch_compilation_start(5)
assert :ok = MibLogger.log_batch_compilation_success(5)
assert :ok = MibLogger.log_batch_compilation_error(3, 2)
assert :ok = MibLogger.log_compilation_complete("TEST", %{})
assert :ok = MibLogger.log_compilation_failed("/test.mib", [])
assert :ok = MibLogger.log_parse_progress("phase", 0)
assert :ok = MibLogger.log_import_resolution("TEST", [])
assert :ok = MibLogger.log_imports_resolved("TEST", 0, 0)
assert :ok = MibLogger.log_codegen("TEST", 0, 0)
assert :ok = MibLogger.log_tokenization("TEST", 0, 0)
assert :ok = MibLogger.log_dependency_order([])
assert :ok = MibLogger.log_performance("phase", [])
assert :ok = MibLogger.log_warning("message")
assert :ok = MibLogger.log_vendor_quirk("TEST", "Vendor", "quirk")
assert :ok = MibLogger.log_batch_progress(0, 0)
end
end
end