From 82b4dbdf288ac1b81373496e3339a9177bc4fce4 Mon Sep 17 00:00:00 2001 From: mayor Date: Fri, 6 Feb 2026 08:36:20 -0600 Subject: [PATCH] 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) --- test/snmpkit/snmp_lib/mib/logger_test.exs | 405 +++++++++++++++++++ test/snmpkit/snmp_lib/pdu/constants_test.exs | 396 ++++++++++++++++++ 2 files changed, 801 insertions(+) create mode 100644 test/snmpkit/snmp_lib/mib/logger_test.exs create mode 100644 test/snmpkit/snmp_lib/pdu/constants_test.exs diff --git a/test/snmpkit/snmp_lib/mib/logger_test.exs b/test/snmpkit/snmp_lib/mib/logger_test.exs new file mode 100644 index 00000000..4331e960 --- /dev/null +++ b/test/snmpkit/snmp_lib/mib/logger_test.exs @@ -0,0 +1,405 @@ +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 diff --git a/test/snmpkit/snmp_lib/pdu/constants_test.exs b/test/snmpkit/snmp_lib/pdu/constants_test.exs new file mode 100644 index 00000000..e3ca50c5 --- /dev/null +++ b/test/snmpkit/snmp_lib/pdu/constants_test.exs @@ -0,0 +1,396 @@ +defmodule SnmpKit.SnmpLib.PDU.ConstantsTest do + use ExUnit.Case, async: true + + alias SnmpKit.SnmpLib.PDU.Constants + + describe "error status code accessors" do + test "returns correct error codes" do + assert Constants.no_error() == 0 + assert Constants.too_big() == 1 + assert Constants.no_such_name() == 2 + assert Constants.bad_value() == 3 + assert Constants.read_only() == 4 + assert Constants.gen_err() == 5 + end + end + + describe "SNMPv3 constants" do + test "returns USM security model constant" do + assert Constants.usm_security_model() == 3 + end + + test "returns default max message size" do + assert Constants.default_max_message_size() == 65_507 + end + end + + describe "PDU type constants accessors" do + test "returns correct PDU type tags" do + assert Constants.get_request() == 0xA0 + assert Constants.getnext_request() == 0xA1 + assert Constants.get_response() == 0xA2 + assert Constants.set_request() == 0xA3 + assert Constants.getbulk_request() == 0xA5 + end + end + + describe "data type constants accessors" do + test "returns correct data type tags" do + assert Constants.integer() == 0x02 + assert Constants.octet_string() == 0x04 + assert Constants.null() == 0x05 + assert Constants.object_identifier() == 0x06 + assert Constants.counter32() == 0x41 + assert Constants.gauge32() == 0x42 + assert Constants.timeticks() == 0x43 + assert Constants.counter64() == 0x46 + assert Constants.ip_address() == 0x40 + assert Constants.opaque_type() == 0x44 + assert Constants.no_such_object() == 0x80 + assert Constants.no_such_instance() == 0x81 + assert Constants.end_of_mib_view() == 0x82 + end + end + + describe "normalize_version/1" do + test "normalizes SNMP version atoms to integers" do + assert Constants.normalize_version(:v1) == 0 + assert Constants.normalize_version(:v2c) == 1 + assert Constants.normalize_version(:v2) == 1 + assert Constants.normalize_version(:v3) == 3 + end + + test "passes through integer versions" do + assert Constants.normalize_version(0) == 0 + assert Constants.normalize_version(1) == 1 + assert Constants.normalize_version(3) == 3 + end + + test "returns 0 for invalid versions" do + assert Constants.normalize_version(:invalid) == 0 + assert Constants.normalize_version("v1") == 0 + assert Constants.normalize_version(nil) == 0 + end + end + + describe "normalize_oid/1" do + test "passes through list OIDs unchanged" do + oid = [1, 3, 6, 1, 2, 1, 1, 1, 0] + assert Constants.normalize_oid(oid) == oid + end + + test "converts string OIDs to list format" do + assert Constants.normalize_oid("1.3.6.1.2.1.1.1.0") == [1, 3, 6, 1, 2, 1, 1, 1, 0] + assert Constants.normalize_oid("1.3.6.1") == [1, 3, 6, 1] + assert Constants.normalize_oid("0.0") == [0, 0] + end + + test "returns default OID for invalid string OIDs" do + assert Constants.normalize_oid("invalid.oid") == [1, 3, 6, 1] + assert Constants.normalize_oid("1.2.abc.4") == [1, 3, 6, 1] + assert Constants.normalize_oid("1.-2.3") == [1, 3, 6, 1] + end + + test "returns default OID for non-list, non-string types" do + assert Constants.normalize_oid(nil) == [1, 3, 6, 1] + assert Constants.normalize_oid(123) == [1, 3, 6, 1] + assert Constants.normalize_oid(%{}) == [1, 3, 6, 1] + end + end + + describe "pdu_type_to_tag/1" do + test "converts PDU type atoms to tag values" do + assert Constants.pdu_type_to_tag(:get_request) == 0xA0 + assert Constants.pdu_type_to_tag(:get_next_request) == 0xA1 + assert Constants.pdu_type_to_tag(:get_response) == 0xA2 + assert Constants.pdu_type_to_tag(:set_request) == 0xA3 + assert Constants.pdu_type_to_tag(:get_bulk_request) == 0xA5 + end + end + + describe "tag_to_pdu_type/1" do + test "converts tag values to PDU type atoms" do + assert Constants.tag_to_pdu_type(0xA0) == :get_request + assert Constants.tag_to_pdu_type(0xA1) == :get_next_request + assert Constants.tag_to_pdu_type(0xA2) == :get_response + assert Constants.tag_to_pdu_type(0xA3) == :set_request + assert Constants.tag_to_pdu_type(0xA5) == :get_bulk_request + end + + test "returns nil for invalid tags" do + assert Constants.tag_to_pdu_type(0xFF) == nil + assert Constants.tag_to_pdu_type(0x00) == nil + end + end + + describe "data_type_to_tag/1" do + test "converts data type atoms to tag values" do + assert Constants.data_type_to_tag(:integer) == 0x02 + assert Constants.data_type_to_tag(:octet_string) == 0x04 + assert Constants.data_type_to_tag(:null) == 0x05 + assert Constants.data_type_to_tag(:object_identifier) == 0x06 + assert Constants.data_type_to_tag(:counter32) == 0x41 + assert Constants.data_type_to_tag(:gauge32) == 0x42 + assert Constants.data_type_to_tag(:timeticks) == 0x43 + assert Constants.data_type_to_tag(:counter64) == 0x46 + assert Constants.data_type_to_tag(:ip_address) == 0x40 + assert Constants.data_type_to_tag(:opaque) == 0x44 + assert Constants.data_type_to_tag(:no_such_object) == 0x80 + assert Constants.data_type_to_tag(:no_such_instance) == 0x81 + assert Constants.data_type_to_tag(:end_of_mib_view) == 0x82 + end + end + + describe "tag_to_data_type/1" do + test "converts tag values to data type atoms" do + assert Constants.tag_to_data_type(0x02) == :integer + assert Constants.tag_to_data_type(0x04) == :octet_string + assert Constants.tag_to_data_type(0x05) == :null + assert Constants.tag_to_data_type(0x06) == :object_identifier + assert Constants.tag_to_data_type(0x41) == :counter32 + assert Constants.tag_to_data_type(0x42) == :gauge32 + assert Constants.tag_to_data_type(0x43) == :timeticks + assert Constants.tag_to_data_type(0x46) == :counter64 + assert Constants.tag_to_data_type(0x40) == :ip_address + assert Constants.tag_to_data_type(0x44) == :opaque + assert Constants.tag_to_data_type(0x80) == :no_such_object + assert Constants.tag_to_data_type(0x81) == :no_such_instance + assert Constants.tag_to_data_type(0x82) == :end_of_mib_view + end + + test "returns nil for invalid tags" do + assert Constants.tag_to_data_type(0xFF) == nil + assert Constants.tag_to_data_type(0x00) == nil + end + end + + describe "normalize_type/1" do + test "normalizes string type to octet_string" do + assert Constants.normalize_type(:string) == :octet_string + end + + test "passes through other types unchanged" do + assert Constants.normalize_type(:integer) == :integer + assert Constants.normalize_type(:counter32) == :counter32 + assert Constants.normalize_type(:gauge32) == :gauge32 + assert Constants.normalize_type(:null) == :null + end + end + + describe "error_status_to_code/1" do + test "converts error status atoms to numeric codes" do + assert Constants.error_status_to_code(:no_error) == 0 + assert Constants.error_status_to_code(:too_big) == 1 + assert Constants.error_status_to_code(:no_such_name) == 2 + assert Constants.error_status_to_code(:bad_value) == 3 + assert Constants.error_status_to_code(:read_only) == 4 + assert Constants.error_status_to_code(:gen_err) == 5 + end + + test "passes through integer codes unchanged" do + assert Constants.error_status_to_code(0) == 0 + assert Constants.error_status_to_code(1) == 1 + assert Constants.error_status_to_code(5) == 5 + assert Constants.error_status_to_code(99) == 99 + end + end + + describe "error_status_to_atom/1" do + test "converts error status codes to atoms" do + assert Constants.error_status_to_atom(0) == :no_error + assert Constants.error_status_to_atom(1) == :too_big + assert Constants.error_status_to_atom(2) == :no_such_name + assert Constants.error_status_to_atom(3) == :bad_value + assert Constants.error_status_to_atom(4) == :read_only + assert Constants.error_status_to_atom(5) == :gen_err + end + + test "passes through unknown codes unchanged" do + assert Constants.error_status_to_atom(99) == 99 + assert Constants.error_status_to_atom(100) == 100 + end + end + + describe "encode_msg_flags/1" do + test "encodes message flags with no security" do + flags = %{auth: false, priv: false, reportable: false} + assert Constants.encode_msg_flags(flags) == <<0>> + end + + test "encodes message flags with auth only" do + flags = %{auth: true, priv: false, reportable: false} + assert Constants.encode_msg_flags(flags) == <<0x01>> + end + + test "encodes message flags with priv only" do + flags = %{auth: false, priv: true, reportable: false} + assert Constants.encode_msg_flags(flags) == <<0x02>> + end + + test "encodes message flags with reportable only" do + flags = %{auth: false, priv: false, reportable: true} + assert Constants.encode_msg_flags(flags) == <<0x04>> + end + + test "encodes message flags with auth and priv" do + flags = %{auth: true, priv: true, reportable: false} + assert Constants.encode_msg_flags(flags) == <<0x03>> + end + + test "encodes message flags with all flags set" do + flags = %{auth: true, priv: true, reportable: true} + assert Constants.encode_msg_flags(flags) == <<0x07>> + end + end + + describe "decode_msg_flags/1" do + test "decodes message flags with no security" do + assert Constants.decode_msg_flags(<<0>>) == %{ + auth: false, + priv: false, + reportable: false + } + end + + test "decodes message flags with auth only" do + assert Constants.decode_msg_flags(<<0x01>>) == %{ + auth: true, + priv: false, + reportable: false + } + end + + test "decodes message flags with priv only" do + assert Constants.decode_msg_flags(<<0x02>>) == %{ + auth: false, + priv: true, + reportable: false + } + end + + test "decodes message flags with reportable only" do + assert Constants.decode_msg_flags(<<0x04>>) == %{ + auth: false, + priv: false, + reportable: true + } + end + + test "decodes message flags with auth and priv" do + assert Constants.decode_msg_flags(<<0x03>>) == %{ + auth: true, + priv: true, + reportable: false + } + end + + test "decodes message flags with all flags set" do + assert Constants.decode_msg_flags(<<0x07>>) == %{ + auth: true, + priv: true, + reportable: true + } + end + end + + describe "default_msg_flags/1" do + test "returns correct flags for no_auth_no_priv" do + assert Constants.default_msg_flags(:no_auth_no_priv) == %{ + auth: false, + priv: false, + reportable: true + } + end + + test "returns correct flags for auth_no_priv" do + assert Constants.default_msg_flags(:auth_no_priv) == %{ + auth: true, + priv: false, + reportable: true + } + end + + test "returns correct flags for auth_priv" do + assert Constants.default_msg_flags(:auth_priv) == %{ + auth: true, + priv: true, + reportable: true + } + end + end + + describe "roundtrip encoding/decoding" do + test "message flags roundtrip correctly" do + test_cases = [ + %{auth: false, priv: false, reportable: false}, + %{auth: true, priv: false, reportable: false}, + %{auth: false, priv: true, reportable: false}, + %{auth: false, priv: false, reportable: true}, + %{auth: true, priv: true, reportable: false}, + %{auth: true, priv: false, reportable: true}, + %{auth: false, priv: true, reportable: true}, + %{auth: true, priv: true, reportable: true} + ] + + for original_flags <- test_cases do + encoded = Constants.encode_msg_flags(original_flags) + decoded = Constants.decode_msg_flags(encoded) + assert decoded == original_flags + end + end + + test "PDU type tags roundtrip correctly" do + pdu_types = [ + :get_request, + :get_next_request, + :get_response, + :set_request, + :get_bulk_request + ] + + for pdu_type <- pdu_types do + tag = Constants.pdu_type_to_tag(pdu_type) + assert Constants.tag_to_pdu_type(tag) == pdu_type + end + end + + test "data type tags roundtrip correctly" do + data_types = [ + :integer, + :octet_string, + :null, + :object_identifier, + :counter32, + :gauge32, + :timeticks, + :counter64, + :ip_address, + :opaque, + :no_such_object, + :no_such_instance, + :end_of_mib_view + ] + + for data_type <- data_types do + tag = Constants.data_type_to_tag(data_type) + assert Constants.tag_to_data_type(tag) == data_type + end + end + + test "error status codes roundtrip correctly" do + error_statuses = [ + :no_error, + :too_big, + :no_such_name, + :bad_value, + :read_only, + :gen_err + ] + + for error_status <- error_statuses do + code = Constants.error_status_to_code(error_status) + assert Constants.error_status_to_atom(code) == error_status + end + end + end +end