towerops/config/test.exs
Graham McIntire e13eb3bbce
feat: implement LLDP topology discovery via SNMP
Implements Phase 1 of network topology discovery using LLDP (Link Layer
Discovery Protocol) via SNMP, inspired by concepts from lldp2map.

New Features:
- LLDP-MIB walker for discovering network neighbors via SNMP
- Database schema for storing neighbor relationships
- Functions to discover, store, and query device neighbors
- Automatic device linking when neighbors are found in database

Components Added:
- Migration: device_neighbors table with unique constraint on
  (device_id, local_port, neighbor_name)
- Schema: Towerops.Topology.DeviceNeighbor for neighbor relationships
- Module: Towerops.Topology.Lldp for SNMP LLDP-MIB walking
- Functions: discover_lldp_neighbors/1, list_lldp_neighbors/1,
  remove_stale_lldp_neighbors/1 in Topology context

LLDP-MIB OIDs:
- 1.0.8802.1.1.2.1.3.3.0 (lldpLocSysName)
- 1.0.8802.1.1.2.1.3.7.1.4 (lldpLocPortDesc)
- 1.0.8802.1.1.2.1.4.1.1.7 (lldpRemPortId)
- 1.0.8802.1.1.2.1.4.1.1.8 (lldpRemPortDesc)
- 1.0.8802.1.1.2.1.4.1.1.9 (lldpRemSysName)
- 1.0.8802.1.1.2.1.4.2.1.3 (lldpRemManAddr)

CI Fix:
- Updated config/test.exs to use DATABASE_URL from environment in CI
- Fixes "connection refused to localhost:5432" errors in CI builds
- Falls back to localhost config for local development

Code Quality:
- Refactored LLDP module to reduce cyclomatic complexity
- Extracted helper functions to improve readability
- Used 'with' statement to reduce nesting in parse_management_address
- All Credo checks passing

Next Steps (Phase 2):
- Background worker for automated topology discovery
- Topology visualization in LiveView
- Recursive discovery from seed devices
2026-03-05 10:53:57 -06:00

93 lines
2.9 KiB
Elixir

import Config
alias Ecto.Adapters.SQL.Sandbox
# Only in tests, remove the complexity from the password hashing algorithm
config :argon2_elixir,
t_cost: 1,
m_cost: 8
config :error_tracker, enabled: false
# Suppress log output during tests (tests that need logs use capture_log)
config :logger, :default_handler, false
config :logger, level: :error
# Initialize plugs at runtime for faster test compilation
config :phoenix, :plug_init_mode, :runtime
# Sort query params output of verified routes for robust url comparisons
config :phoenix,
sort_verified_routes_query_params: true
# Enable helpful, but potentially expensive runtime checks
config :phoenix_live_view,
enable_expensive_runtime_checks: true
# Disable swoosh api client as it is only required for production adapters
config :swoosh, :api_client, false
# Disable Oban job processing in tests (use testing mode)
config :towerops, Oban,
repo: Towerops.Repo,
testing: :manual,
queues: false,
plugins: false
# In test we don't send emails
config :towerops, Towerops.Mailer, adapter: Swoosh.Adapters.Test
# Configure your database
#
# The MIX_TEST_PARTITION environment variable can be used
# to provide built-in test partitioning in CI environment.
# Run `mix help test` for more information.
#
# In CI, DATABASE_URL is set and will be used automatically by Ecto.
# Locally, fall back to individual connection parameters.
if database_url = System.get_env("DATABASE_URL") do
config :towerops, Towerops.Repo,
url: database_url,
pool: Sandbox,
pool_size: System.schedulers_online() * 2
else
config :towerops, Towerops.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "towerops_test#{System.get_env("MIX_TEST_PARTITION")}",
pool: Sandbox,
pool_size: System.schedulers_online() * 2
end
# Configure Cloak encryption for testing
# Use a fixed test key (same as dev for simplicity)
config :towerops, Towerops.Vault,
ciphers: [
default: {
Cloak.Ciphers.AES.GCM,
# Test key - same as dev for consistency
tag: "AES.GCM.V1", key: Base.decode64!("nQWmgQYhoCNXA3PAxwriKxLyPHAOWH9VgpLkBOXrowM=")
}
]
# We don't run a server during test. If one is required,
# you can enable the server option below.
config :towerops, ToweropsWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4002],
secret_key_base: "XDSSqVUtRXUjEfzxefIAaPIzBfonpNMOrCRyP1a0kjPzzyOpVNSRmMBVae/bwTqj",
server: false
# Webhook secret for CI-triggered agent updates
config :towerops, :agent_webhook_secret, "test-webhook-secret"
# Set environment identifier for runtime checks
config :towerops, :env, :test
config :towerops,
ping_module: Towerops.Monitoring.PingMock,
poller_module: Towerops.Snmp.PollerMock,
snmp_adapter: Towerops.Snmp.SnmpMock,
sql_sandbox: true,
# Disable rate limiting in tests to avoid blocking concurrent test requests
rate_limiting_enabled: false