SnmpKit.SnmpSim.ErrorInjector (snmpkit v0.6.3)

Inject realistic error conditions for comprehensive testing.

Supports timeouts, packet loss, malformed responses, and device failures for testing SNMP polling systems under realistic network conditions.

Features

  • Network timeouts with configurable probability and duration
  • Packet loss simulation with burst patterns
  • SNMP protocol errors (noSuchName, genErr, tooBig)
  • Malformed response corruption for robustness testing
  • Device failure and reboot simulation
  • Statistical tracking of all injected errors

Usage

# Inject timeout condition
SnmpKit.SnmpSim.ErrorInjector.inject_timeout(device_pid, probability: 0.1, duration: 5000)

# Simulate packet loss
SnmpKit.SnmpSim.ErrorInjector.inject_packet_loss(device_pid, loss_rate: 0.05)

# Generate SNMP errors
SnmpKit.SnmpSim.ErrorInjector.inject_snmp_error(device_pid, :noSuchName, ["1.3.6.1.2.1.2.2.1.99"])

Summary

Functions

Returns a specification to start this module under a supervisor.

Clear all error conditions and reset device to normal operation.

Get statistics for all injected errors.

Inject malformed response packets to test client robustness.

Inject packet loss with configurable loss rates and patterns.

Inject SNMP protocol errors for specific OIDs or patterns.

Inject timeout conditions with specified probability and duration.

Remove specific error condition.

Simulate device reboot or failure scenarios.

Start error injection monitoring for a device.

Types

error_config()

@type error_config() :: %{
  probability: float(),
  duration_ms: integer(),
  burst_patterns: boolean(),
  target_oids: [String.t()] | :all,
  error_details: map()
}

error_type()

@type error_type() ::
  :timeout | :packet_loss | :snmp_error | :malformed | :device_failure

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear_all_errors(injector_pid)

@spec clear_all_errors(pid()) :: :ok

Clear all error conditions and reset device to normal operation.

get_error_statistics(injector_pid)

@spec get_error_statistics(pid()) :: map()

Get statistics for all injected errors.

inject_malformed_response(injector_pid, corruption_type, opts \\ [])

@spec inject_malformed_response(pid(), atom(), keyword()) :: :ok | {:error, term()}

Inject malformed response packets to test client robustness.

Corruption Types

  • :truncated - Cut off response packets
  • :invalid_ber - Corrupt BER/DER encoding
  • :wrong_community - Incorrect community string
  • :invalid_pdu_type - Invalid PDU type field
  • :corrupted_varbinds - Corrupt variable bindings

Examples

# Randomly truncate 2% of responses
ErrorInjector.inject_malformed_response(device, :truncated,
  probability: 0.02,
  corruption_severity: 0.3
)

# Corrupt BER encoding occasionally
ErrorInjector.inject_malformed_response(device, :invalid_ber,
  probability: 0.01
)

inject_packet_loss(injector_pid, opts \\ [])

@spec inject_packet_loss(
  pid(),
  keyword()
) :: :ok | {:error, term()}

Inject packet loss with configurable loss rates and patterns.

Options

  • loss_rate: Float 0.0-1.0, percentage of packets to drop
  • burst_loss: Enable burst loss patterns (default: false)
  • burst_size: Number of consecutive packets to drop in burst (default: 5)
  • recovery_time_ms: Time between bursts (default: 30000)

Examples

# 5% random packet loss
ErrorInjector.inject_packet_loss(device, loss_rate: 0.05)

# Burst packet loss - lose 10 consecutive packets occasionally
ErrorInjector.inject_packet_loss(device,
  loss_rate: 0.02,
  burst_loss: true,
  burst_size: 10,
  recovery_time_ms: 60000
)

inject_snmp_error(injector_pid, error_type, opts \\ [])

@spec inject_snmp_error(pid(), atom(), keyword()) :: :ok | {:error, term()}

Inject SNMP protocol errors for specific OIDs or patterns.

Error Types

  • :noSuchName - OID does not exist
  • :genErr - General error
  • :tooBig - Response too large for UDP packet
  • :badValue - Invalid value in SET request
  • :readOnly - Attempt to SET read-only variable

Examples

# Generate noSuchName errors for specific OIDs
ErrorInjector.inject_snmp_error(device, :noSuchName,
  target_oids: ["1.3.6.1.2.1.2.2.1.99"],
  probability: 1.0
)

# Random genErr responses
ErrorInjector.inject_snmp_error(device, :genErr,
  probability: 0.05,
  target_oids: :all
)

inject_timeout(injector_pid, opts \\ [])

@spec inject_timeout(
  pid(),
  keyword()
) :: :ok | {:error, term()}

Inject timeout conditions with specified probability and duration.

Options

  • probability: Float 0.0-1.0, chance each request times out
  • duration_ms: Timeout duration in milliseconds
  • burst_probability: Chance of timeout bursts (default: 0.1)
  • burst_duration_ms: Duration of timeout bursts (default: 10000)

Examples

# 10% chance of 5-second timeouts
ErrorInjector.inject_timeout(device, probability: 0.1, duration_ms: 5000)

# Burst timeouts - 20% of requests timeout for 30 seconds when burst occurs
ErrorInjector.inject_timeout(device,
  probability: 0.2,
  duration_ms: 30000,
  burst_probability: 0.05,
  burst_duration_ms: 60000
)

remove_error_condition(injector_pid, error_type)

@spec remove_error_condition(pid(), error_type()) :: :ok

Remove specific error condition.

simulate_device_failure(injector_pid, failure_type, opts \\ [])

@spec simulate_device_failure(pid(), atom(), keyword()) :: :ok | {:error, term()}

Simulate device reboot or failure scenarios.

Failure Types

  • :reboot - Device becomes unreachable then recovers
  • :power_failure - Complete device failure
  • :network_disconnect - Network connectivity lost
  • :firmware_crash - Device crash with recovery
  • :overload - Device overloaded, slow responses

Examples

# Simulate device reboot (30 seconds downtime)
ErrorInjector.simulate_device_failure(device, :reboot,
  duration_ms: 30000,
  recovery_behavior: :reset_counters
)

# Network disconnect with gradual recovery
ErrorInjector.simulate_device_failure(device, :network_disconnect,
  duration_ms: 60000,
  recovery_behavior: :gradual
)

start_link(device_pid, device_port)

@spec start_link(pid(), integer()) :: {:ok, pid()} | {:error, term()}

Start error injection monitoring for a device.