- Test start_link/1 and Horde Registry registration
- Test initial check on monitoring enabled/disabled
- Test trigger_check/1 for running and stopped monitors
- Test successful and failed ping handling
- Test status change detection (up->down, down->up)
- Test alert creation and resolution
- Test PubSub broadcasts for status changes and alerts
- Test alert message formatting for ICMP vs SNMP
- Test check scheduling based on check_interval_seconds
- Coverage improved from 43.93% to 96.67%
Total tests: 1066 -> 1089 (23 new tests)
Total coverage: 48.72% -> 49.65%
- Add Mox stub setup in supervisor_test.exs to handle DeviceMonitor ping calls
- Change alert_notifier_test.exs to async: true to prevent mailbox contamination
- All 1066 tests now passing with 0 failures
Changes:
- Updated MonitorWorker to use configured ping_module adapter instead of System.cmd
- Removed direct ping command execution and regex parsing
- Simplified ping_device/1 to use adapter.ping/2 (mockable in tests)
- Added PingMock expectations to all MonitorWorker tests
- Removed @tag :integration from unreachable host test (now mocked)
- All ping calls now use mocked responses in tests
Benefits:
- MonitorWorker tests now run in 0.2s instead of 5+ seconds
- No real ICMP network traffic during test runs
- Tests are deterministic and don't depend on network conditions
- Follows same adapter pattern as SNMP (testable, configurable)
All 1041 tests passing with no real network operations.
- Add 'error' to valid sensor reading status values
- SensorReading changeset was rejecting 'error' status
- PollWorker creates error readings when SNMP fails
- Fixed validation to include: ok, warning, critical, error
- Replace log capture tests with functional assertions
- ExUnit.CaptureLog not reliably capturing worker logs
- Changed to verify actual behavior instead of log messages
- Tests now check created records and state changes
- Add debug assertions to sensor error test
- Verify SNMP device exists and has sensors
- Better error messages for test failures
All 1045 tests now passing (0 failures, 2 skipped)
- Fix Monitoring context API calls (list_devices_checks vs list_checks_for_device)
- Fix Snmp context API calls (get_interface_stats, get_sensor_readings)
- Fix Devices context API calls (update_device vs update_device!)
- Fix Discovery worker to expect 7 GET calls (test_connection + system_info)
- Fix Poll worker to use stub instead of expect for variable call counts
- Fix sensor setup to use correct types (sensor_index: string, sensor_divisor: integer)
- Fix neighbor schema to include required fields (protocol, last_discovered_at)
- Simplify walk mocks to use stub for complex neighbor discovery
18 of 23 tests now passing. Remaining issues:
- 1 sensor error reading test (may need investigation)
- 4 log capture tests (ExUnit.CaptureLog not capturing logs from workers)
Tests cover:
- Valid and invalid changesets
- All required field validations
- Foreign key constraints
- Status enum values
- Schema field types and associations
- Binary ID usage for primary/foreign keys
All 16 tests passing with good coverage of schema validation logic.
- DiscoveryWorker: Tests for SNMP device discovery
- MonitorWorker: Tests for ICMP ping monitoring checks
- PollWorker: Tests for SNMP polling of sensors, interfaces, and neighbors
These tests use fixtures and Mox for SNMP mocking to achieve good coverage
of the worker modules without requiring real SNMP devices.
Note: Some function names need correction based on actual Monitoring/Snmp context APIs.
Fixes crashes in Exq.Node.Server when Redis connections fail by adding
health checks before startup and wrapping Exq in a custom supervisor
with better resilience.
Problem:
- Valkey pod restarting frequently (24 times in 28h) due to K8s Flannel CNI issues
- When Redis disconnects, Exq.Node.Server crashes trying to process_signals/2
- Gets nil from Redis instead of expected list, crashes on Enum.each/2
- Rapid crash/restart cycles reduce application stability
Changes:
1. RedisHealthCheck module (lib/towerops/redis_health_check.ex)
- Waits for Redis availability with exponential backoff before starting Exq
- Prevents Exq from starting when Redis is unavailable
- Handles connection errors gracefully without crashing caller processes
- Supports configurable retry attempts, timeouts, and backoff intervals
2. ExqSupervisor module (lib/towerops/exq_supervisor.ex)
- Custom supervisor that wraps Exq with health checks
- Uses one_for_one strategy with limited restarts (3 per 60s)
- Prevents rapid crash loops when Redis is unstable
- Increased Exq retry/backoff settings for better Redis recovery
- Allows application to continue functioning without background jobs if Redis unavailable
3. Updated Application.ex
- Replaced direct Exq start with ExqSupervisor
- Removed inline exq_config/0 function (moved to supervisor)
4. Tests
- Comprehensive tests for RedisHealthCheck (health checks, retries, timeouts)
- Tests for ExqSupervisor (configuration, restart strategy)
- All 1006 tests passing
Benefits:
- Prevents Exq crashes from propagating when Redis fails
- Application continues running even when Redis is temporarily unavailable
- Better logging of Redis connection issues
- More graceful degradation during infrastructure problems
Infrastructure Issue (to be addressed separately):
- K8s Flannel CNI plugin failing: /run/flannel/subnet.env not found
- Causing Valkey pod network issues and restarts
- Needs investigation of Flannel daemonset and node configuration
🤖 Generated with Claude Code
- Created 23 tests covering all public functions and edge cases
- Tests for IPv4 and IPv6 address validation
- Tests for timeout behavior and error handling
- Tests for PingBehaviour implementation
- All tests passing (23 tests, 0 failures)
- Module now has improved test coverage
Improves test coverage toward 90% target by adding tests for:
- Organizations context (bulk SNMP/agent operations)
- Sites context (hierarchical structure and bulk operations)
- Profiles context and schemas (device/sensor OID management)
- EctoTypes.JsonAny custom type
- Snmp.Neighbor schema (LLDP/CDP topology)
All new tests validate changeset validations, business logic,
and database constraints to ensure data integrity.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
User deletion bug:
- Store client IP in socket assigns during mount
- Access stored IP during delete event instead of connect_info
- Fixes RuntimeError when attempting to delete users
Timezone support:
- Add timezone offset maps for common timezones (no external deps)
- Implement shift_timezone/2 helper using DateTime.add/3
- Add timezone-aware format_datetime/2, format_date/2, format_iso8601/2
- Keep backwards-compatible 1-arity versions defaulting to UTC
- Add comprehensive test coverage for timezone conversions
- All tests passing (23 tests, 0 failures)
Note: Timezone offsets are standard time only (no DST handling)
Common timezones supported: America/New_York, America/Los_Angeles,
Europe/London, Europe/Paris, Asia/Tokyo, Asia/Shanghai, Australia/Sydney
Updated all references to use the more technically accurate term 'ICMP Latency'
instead of 'Ping Latency' in:
- Graph titles and labels
- HTML comments
- Test assertions
- Added comprehensive tests for GraphLive.Show to ensure:
* Page renders with correct assigns
* Uses @current_organization (not @organization)
* Latency, processor, memory, and traffic graphs work
* Time range selection works correctly
* All required assigns are present
- Reordered device show page so Overall Traffic appears above Ping Latency
- Make device name field optional when SNMP is enabled (ICMP Only mode still requires name)
- Add database migration to make name column nullable
- Add conditional validation: name required only when snmp_enabled is false
- Update SNMP discovery to populate device name from sysName when empty
- Add helper text explaining SNMP name population behavior in form
- Add comprehensive tests for device name SNMP population
- Update test mocks to account for NetSnmp profile sensor discovery
- After creating a device, stay on /devices/new instead of navigating to device show page
- Display success flash message with creation confirmation
- Reset form to defaults (preserving selected site) for adding next device
- Allows users to quickly add multiple devices in a row without navigation
- Add tests for staying on page and adding multiple devices sequentially
- All 91 device-related tests passing with no Credo warnings
- Add tab selector in Monitoring Configuration section for choosing monitoring mode
- SNMP & ICMP mode: enables ICMP pings + SNMP discovery (default)
- ICMP Only mode: enables only ICMP ping monitoring, hides SNMP fields
- Monitoring mode controls snmp_enabled field automatically on save
- Test SNMP Connection button shows informational message when agent is configured
(agents handle SNMP testing during their polling cycle)
- Update all tests to use tab selector instead of setting snmp_enabled directly
- All 818 tests passing with no Credo warnings
- Add Monitoring.get_latency_data/2 to query successful checks with response times
- Support 'latency' sensor type in GraphLive.Show with configurable time ranges
- Add latency chart to device show page alongside other metric charts
- Add comprehensive tests for get_latency_data/2 (limit, since, failed checks)
- All 813 tests passing with no Credo warnings
Implemented hierarchical SNMP community string inheritance following TDD:
Schema changes:
- Updated Device.changeset to remove required validation for snmp_community
- Community string is now optional when SNMP is enabled
- Allows inheritance from site or organization level
Inheritance hierarchy:
- Device-level community (highest priority)
- Site-level community
- Organization-level community
- nil (no community set at any level)
Form updates:
- extract_snmp_config now resolves inherited community for SNMP testing
- validate_test_snmp_input provides clearer error message about inheritance
- SNMP test uses effective community from hierarchy
Tests:
- Added tests for creating devices with nil/empty community string
- Added comprehensive SNMP configuration inheritance tests
- Tests verify hierarchy: device > site > org > default
- All 28 device tests passing
All 808 tests passing (2 pre-existing alert notifier failures unrelated to this change)
No Credo warnings
Implemented ability to rename agents through a new edit page following TDD:
Backend changes:
- Added update_agent_token/2 in Agents context for updating agent names
- Added update_changeset/2 in AgentToken schema that only allows name updates
- Security: Token field cannot be changed, only name field is allowed
LiveView implementation:
- Created AgentLive.Edit module with mount, validate, and save handlers
- Created edit.html.heex template with form for renaming agents
- Added route /orgs/:org_slug/agents/:id/edit
- Added Edit button to agent show page header
- Validates organization ownership using Repo.get_by!
Tests:
- Added comprehensive context tests for update_agent_token/2
- Added LiveView tests for edit page functionality
- Tests cover: loading, validation, save/redirect, auth, and org ownership
All 801 tests passing, no Credo warnings.
Replace the revoke functionality with delete to properly clean up agent references.
When an agent is deleted:
- All direct device assignments are removed
- Agent is removed from site defaults
- Agent is removed from organization defaults
- Devices automatically fall back to site/org agents or cloud polling
This ensures no orphaned references and provides better clarity about
what happens to device monitoring when an agent is removed.
- Add delete_agent_token/1 function in Agents context
- Update LiveView to use delete_agent event instead of revoke_agent
- Update UI button from "Revoke" to "Delete" with clearer confirmation message
- Add comprehensive tests for delete functionality and fallback behavior
- All 792 tests passing, no Credo warnings
- Create UserSettingsLive to replace UserSettingsController
- Convert email/password forms to LiveView with proper form handling
- Add mobile session management (toggle alerts, revoke devices)
- Add require_sudo_mode on_mount hook to UserAuth
- Create dedicated live_session for sudo mode routes in router
- Keep UserSettingsController for email confirmation via token only
- Add MobileSessions.get_session/1 function for test support
- Update tests to match LiveView behavior (password update redirects to login)
- Remove old controller tests for email/password updates (now in LiveView)
Bandit 1.10.1 does not support read_timeout/write_timeout in http_1_options
or stream_idle_timeout in http_2_options. These invalid options caused the
application to crash on startup with 'Unsupported key(s) in http_1_options'.
Moved read_timeout to thousand_island_options where it belongs, and removed
the unsupported write_timeout and stream_idle_timeout options.
Also fixed UserSettingsHTMLTest to include the missing mobile_sessions assign
that is required by the edit.html.heex template.
Set explicit min/max bounds on chart x-axis to ensure all graphs
consistently show 24 hours of data, even when data points are sparse.
Also fix AlertNotifierTest race condition by disabling async execution.
Add three-level agent assignment hierarchy (Equipment > Site > Organization)
allowing flexible agent deployment strategies. Agents now receive only equipment
assigned to them through direct assignment or inheritance from site/organization
defaults.
Key changes:
- Add agent_token_id to Sites table with migration
- Implement get_effective_agent_token/1 for hierarchical resolution
- Add list_agent_polling_targets/1 to return polling targets per agent
- Update API config endpoint to use hierarchical polling targets
- Add agent assignment UI to equipment, site, and organization forms
- Show agent source (direct/site/org/none) in equipment form
- Add equipment count column to agent list
- Update terminology from "poll from server" to "cloud polling"
Tests:
- Add 8 comprehensive tests for list_agent_polling_targets/1
- Add end-to-end test for hierarchical config endpoint
- All 775 tests passing
- Update AgentAuth plug to use synchronous heartbeat updates in test env
- Refactor async heartbeat logic to reduce nesting (Credo)
- Remove Process.sleep from tests (no longer needed with sync updates)
This fixes 'owner exited' database errors in the test suite by avoiding
async Task spawns during tests, which caused DB connection ownership
conflicts with Ecto's sandbox mode.
Login flow improvements:
- Remove "Welcome back!" flash message on successful login
- Auto-login users clicking magic links without confirmation prompt
- Always use "remember me" for magic link logins
- Fix Accounts.login_user_by_magic_link/1 to handle invalid token format
Test fixes:
- Add @tag :integration to Ping tests (require actual system ping)
- Add halt() calls to UserAuth.start_impersonation error paths
Users now go directly to their intended destination after clicking a
magic link, with no interruption for "log in and stay logged in" choice.
- Test equipment information display
- Test overview tab rendering
- Test metrics display with monitoring checks
- Test empty state handling
- Test periodic data refresh
- Test authentication requirement
- Test event handling (equipment_status_changed, discovery_completed)
- Test tab switching functionality
- Test valid changesets with required and all fields
- Test validation for name, description, location lengths
- Test parent site relationships and circular reference validation
- Test all constraint validations
- Test unique organization name generation
- Test valid organization attributes
- Test organization creation with defaults and custom attributes
- Test membership creation for organization owner
- Test all fixture generation functions
- Test user creation (confirmed and unconfirmed)
- Test scope fixtures
- Test password setting
- Test token generation and manipulation
- Test credential fixtures