SnmpKit v0.3.4 Release Notes
Release Date: December 16, 2024
Version: 0.3.4
Previous Version: 0.3.3
๐ฏ Overview
This release focuses on API consistency, bug fixes, and developer experience improvements. We've resolved critical issues with return formats, fixed SNMP type encoding problems, and enhanced documentation to match the actual implementation.
๐ Key Highlights
โ API Consistency Restored
- Fixed return format mismatches between documentation and implementation
- Added missing
get_next_with_type/2,3
function for complete API coverage - Clear distinction between simple and type-aware operations
๐ง Critical Bug Fixes
- Resolved SNMP type encoding errors that were causing encoding failures
- Fixed empty device handling to return proper SNMP errors
- Eliminated compiler warnings and dead code
๐ Documentation Accuracy
- All examples now reflect actual implementation behavior
- Comprehensive type specifications added
- Clear guidance on when to use each API variant
๐ฅ Breaking Changes
None! This release maintains full backward compatibility while fixing the API to work as originally intended.
๐ What's New
New API Function: get_next_with_type/2,3
# Now available for complete API consistency
{:ok, {oid, type, value}} = SnmpKit.SNMP.get_next_with_type("192.168.1.1", "sysDescr")
Consistent Return Formats
# Simple operations (clean, no type info)
{:ok, value} = SnmpKit.SNMP.get("192.168.1.1", "sysDescr.0")
{:ok, {oid, value}} = SnmpKit.SNMP.get_next("192.168.1.1", "sysDescr")
# Type-aware operations (full SNMP information)
{:ok, {oid, type, value}} = SnmpKit.SNMP.get_with_type("192.168.1.1", "sysDescr.0")
{:ok, {oid, type, value}} = SnmpKit.SNMP.get_next_with_type("192.168.1.1", "sysDescr")
# Bulk operations (always include type information)
{:ok, results} = SnmpKit.SNMP.get_bulk("192.168.1.1", "ifTable")
# Returns: [{[1,3,6,1,2,1,2,2,1,1,1], :integer, 1}, ...]
{:ok, results} = SnmpKit.SNMP.walk("192.168.1.1", "system")
# Returns: [{[1,3,6,1,2,1,1,1,0], :octet_string, "Linux..."}, ...]
๐ Bug Fixes
Fixed SNMP Type Encoding Errors
Problem: Device simulators were generating invalid type atoms like :"octet string"
(with quotes and spaces) instead of :octet_string
(with underscores).
Solution: Added proper type mapping throughout the codebase:
# Before (broken)
"OCTET STRING" -> :"octet string" # Invalid!
# After (fixed)
"OCTET STRING" -> :octet_string # Correct!
Fixed Empty Device Handling
Problem: Devices with empty OID maps were falling back to default values instead of returning proper SNMP errors.
Solution: Fixed logic to check for manual OID maps even when empty and return :no_such_name
appropriately.
Fixed API Return Format Inconsistencies
Problem: Tests expected get/3
to return {:ok, value}
but it was returning {:ok, {type, value}}
.
Solution:
get/3
now returns{:ok, value}
(clean interface)get_with_type/3
returns{:ok, {oid, type, value}}
(full information)- Same pattern applied to
get_next/3
vsget_next_with_type/3
๐ Performance Improvements
Async Test Optimization
Made selected tests run in parallel for faster test execution:
test/snmpkit_test.exs
- Simple module teststest/snmp_lib/mib/docsis_mib_test.exs
- Pure MIB parsingtest/snmp_sim/correlation_engine_test.exs
- Data computations
Result: Faster test runs while maintaining safety through careful async selection.
๐ Documentation Updates
All Examples Fixed
Every example in the codebase now shows the correct return format:
# get_bulk examples now show proper 3-tuples
{:ok, results} = SnmpMgr.get_bulk("switch.local", "ifTable", max_repetitions: 10)
# [
# {[1,3,6,1,2,1,2,2,1,1,1], :integer, 1}, # ifIndex.1
# {[1,3,6,1,2,1,2,2,1,2,1], :octet_string, "FastEthernet0/1"}, # ifDescr.1
# {[1,3,6,1,2,1,2,2,1,8,1], :integer, 1}, # ifOperStatus.1
# # ... with proper type information
# ]
Enhanced Type Specifications
Added comprehensive @spec
declarations for better developer experience and Dialyzer support:
@spec get_bulk(target(), oid(), opts()) :: {:ok, [{list(), atom(), any()}]} | {:error, any()}
@spec walk(target(), oid(), opts()) :: {:ok, [{list(), atom(), any()}]} | {:error, any()}
๐งช Testing
- โ 1159 tests passing (0 failures)
- โ 76 doctests passing
- โ 3.3s async execution (improved from previous)
- โ Zero breaking changes confirmed
๐ Migration Guide
If you're using simple operations:
No changes needed! Your code will work better than before.
# This continues to work, but now returns cleaner format
{:ok, value} = SnmpKit.SNMP.get("192.168.1.1", "sysDescr.0")
If you're using bulk operations:
No changes needed! Bulk operations already returned type information.
# This continues to work exactly as before
{:ok, results} = SnmpKit.SNMP.walk("192.168.1.1", "system")
If you need type information from simple operations:
Use the new type-aware variants:
# New: Get type information from simple operations
{:ok, {oid, type, value}} = SnmpKit.SNMP.get_with_type("192.168.1.1", "sysDescr.0")
{:ok, {oid, type, value}} = SnmpKit.SNMP.get_next_with_type("192.168.1.1", "sysDescr")
๐ก๏ธ Reliability
Type Safety Improvements
- Eliminated type encoding errors that caused runtime failures
- Added proper type validation throughout the simulator stack
- Enhanced error handling for edge cases
Code Quality
- Removed compiler warnings
- Eliminated dead code paths
- Added comprehensive type specifications
๐ Related Issues
This release addresses several categories of issues:
- API Consistency - Return formats now match documentation
- Type Safety - Proper SNMP type handling throughout
- Developer Experience - Clear examples and specifications
- Test Performance - Faster execution through async optimization
๐ฆ Installation
Update your mix.exs
dependency:
def deps do
[
{:snmpkit, "~> 0.3.4"}
]
end
Then run:
mix deps.update snmpkit
๐ Acknowledgments
This release represents a significant investment in code quality, developer experience, and API consistency. Special attention was paid to maintaining backward compatibility while fixing underlying issues.
๐ Support
- Documentation: HexDocs
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Happy SNMP monitoring! ๐