- INTEGRATION_TEST_PLAN.md: Comprehensive test plan with 10 scenarios - Authentication, config fetch, SNMP polling, metrics submission - Resilience testing (API outage, network interruption, token revocation) - Load testing and 24-hour stability test procedures - Setup instructions for SNMP simulator and real devices - USER_GUIDE.md: Complete deployment and operations guide - Deployment methods: Docker Compose, Podman, Kubernetes, Systemd - Configuration options and environment variables - Network requirements and firewall rules - Troubleshooting common issues - Upgrade and maintenance procedures - Best practices and security considerations - CLAUDE.md: Updated status to reflect all code complete
14 KiB
Agent Integration Test Plan
This document provides a complete plan for integration testing the Towerops agent with the Phoenix backend.
Prerequisites
- Phoenix backend running locally (
mix phx.server) - Docker or podman installed
- Agent Docker image built (
localhost/towerops-agent:latest) - Access to SNMP test device OR SNMP simulator running
Test Environment Options
Option 1: Using Real SNMP Device (Recommended for Complete Testing)
The existing integration test file references a MikroTik device at 10.0.19.254.
Requirements:
- Network access to SNMP device
- Valid SNMP community string
- Device must support SNMPv2c
Option 2: Using SNMP Simulator (Better for CI/CD)
Use snmpsim to simulate SNMP devices:
# Install snmpsim
pip install snmpsim
# Create simulation data directory
mkdir -p ~/snmpsim-data
# Create a simple device simulation file
cat > ~/snmpsim-data/public.snmprec << 'EOF'
1.3.6.1.2.1.1.1.0|4|Test Router v1.0
1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.9.1.1
1.3.6.1.2.1.1.3.0|67|12345678
1.3.6.1.2.1.1.4.0|4|admin@test.local
1.3.6.1.2.1.1.5.0|4|test-router
1.3.6.1.2.1.1.6.0|4|Test Lab
# Temperature sensor
1.3.6.1.4.1.9.9.91.1.1.1.1.1.1000|2|8
1.3.6.1.4.1.9.9.91.1.1.1.1.4.1000|2|450
# Interface ifIndex
1.3.6.1.2.1.2.2.1.1.1|2|1
1.3.6.1.2.1.2.2.1.2.1|4|GigabitEthernet0/1
1.3.6.1.2.1.2.2.1.10.1|65|1234567890
1.3.6.1.2.1.2.2.1.16.1|65|9876543210
EOF
# Start simulator
snmpsimd.py \
--data-dir=~/snmpsim-data \
--agent-udpv4-endpoint=127.0.0.1:1161 \
--v2c-arch
Test against simulator:
# Verify simulator works
snmpget -v2c -c public localhost:1161 1.3.6.1.2.1.1.1.0
# Should return: SNMPv2-MIB::sysDescr.0 = STRING: Test Router v1.0
Integration Test Procedure
Phase 1: Backend Setup
- Start Phoenix Server:
cd /Users/graham/dev/towerops
mix phx.server
# Access at http://localhost:4000
- Create Organization and User (if not exists):
- Register a test user via UI
- Create organization "Test Org"
- Create Test Equipment:
- Navigate to Sites → Create Site "Test Site"
- Add Equipment "Test Router"
- IP Address:
127.0.0.1:1161(if using simulator) or10.0.19.254(real device) - SNMP Enabled: Yes
- SNMP Version: 2c
- SNMP Community:
public(simulator) orkdyyJrT0Mm(real device) - Poll Interval: 60 seconds
- IP Address:
- Run SNMP Discovery:
- Click "Discover SNMP" on equipment page
- Verify sensors and interfaces are discovered
- Expected sensors: Temperature sensors (Cisco) or system sensors (MikroTik)
- Expected interfaces: At least 1 network interface
- Create Agent Token:
- Navigate to
/orgs/:slug/agents - Click "Create New Agent"
- Name: "Test Agent"
- Copy the token (shown only once) - save it for next steps
- Assign Equipment to Agent:
- On equipment page, under "Agent Assignment" section
- Select "Test Agent"
- Click "Assign Agent"
- Or set as site/organization default
Phase 2: Agent Setup & Deployment
Option A: Run with Docker/Podman
- Create agent configuration:
cd /Users/graham/dev/towerops/towerops-agent
# Create data directory
mkdir -p data
# Run agent
podman run --rm -it \
--network=host \
-e TOWEROPS_API_URL=http://localhost:4000 \
-e TOWEROPS_AGENT_TOKEN=<your-token-here> \
-e RUST_LOG=info \
-v $(pwd)/data:/data \
localhost/towerops-agent:latest
For simulator on different machine:
# Use host.docker.internal for Mac/Windows
podman run --rm -it \
--add-host=host.docker.internal:host-gateway \
-e TOWEROPS_API_URL=http://host.docker.internal:4000 \
-e TOWEROPS_AGENT_TOKEN=<your-token-here> \
-e RUST_LOG=debug \
-v $(pwd)/data:/data \
localhost/towerops-agent:latest
Option B: Run with Cargo (Development)
cd /Users/graham/dev/towerops/towerops-agent
RUST_LOG=debug cargo run -- \
--api-url http://localhost:4000 \
--token <your-token-here> \
--database-path ./test-agent.db
Phase 3: Verification Tests
Test 1: Agent Authentication ✅
Expected Logs (Agent):
INFO towerops_agent: Starting Towerops Agent v0.1.0
INFO towerops_agent::api_client: Testing API connection...
INFO towerops_agent::api_client: API connection successful
Verification (Phoenix):
- Check agent appears in UI at
/orgs/:slug/agents - Status shows "Online" (green dot)
- "Last Seen" shows current timestamp
- Hostname and version populated
Database Check:
SELECT name, enabled, last_seen_at, metadata
FROM agent_tokens
WHERE name = 'Test Agent';
Test 2: Configuration Fetch ✅
Expected Logs (Agent):
INFO towerops_agent::poller::scheduler: Fetching configuration from API...
INFO towerops_agent::api_client: Configuration fetched successfully
INFO towerops_agent::poller::scheduler: Configuration updated: 1 equipment
Verification:
- Agent logs show equipment details (IP, name, sensor count, interface count)
- No authentication errors
- Config matches what's in database
Test 3: SNMP Polling ✅
Expected Logs (Agent):
INFO towerops_agent::poller::executor: Polling equipment: Test Router (127.0.0.1)
DEBUG towerops_agent::poller::executor: Polling 2 sensors and 1 interfaces
INFO towerops_agent::poller::executor: Successfully polled 2 sensor readings
INFO towerops_agent::poller::executor: Successfully polled 1 interface stats
Verification (Database):
-- Check sensor readings (should appear within 60 seconds)
SELECT sr.value, sr.status, sr.checked_at, s.sensor_type, s.sensor_oid
FROM snmp_sensor_readings sr
JOIN snmp_sensors s ON sr.sensor_id = s.id
JOIN snmp_devices d ON s.snmp_device_id = d.id
JOIN equipment e ON d.equipment_id = e.id
WHERE e.name = 'Test Router'
ORDER BY sr.checked_at DESC
LIMIT 10;
-- Check interface stats
SELECT
if_in_octets, if_out_octets,
if_in_errors, if_out_errors,
checked_at
FROM snmp_interface_stats ist
JOIN snmp_interfaces i ON ist.interface_id = i.id
JOIN snmp_devices d ON i.snmp_device_id = d.id
JOIN equipment e ON d.equipment_id = e.id
WHERE e.name = 'Test Router'
ORDER BY checked_at DESC
LIMIT 10;
Expected Results:
- New rows appear every 60 seconds (poll interval)
- Sensor values are numeric and reasonable (temperatures 20-80°C)
- Interface counters are increasing
- Timestamps are current
Test 4: Metrics Submission ✅
Expected Logs (Agent):
INFO towerops_agent::buffer::storage: Storing 3 metrics in buffer
INFO towerops_agent::api_client: Flushing 3 pending metrics to API
INFO towerops_agent::api_client: Metrics submitted successfully: 3 accepted
Expected Logs (Phoenix):
[info] POST /api/v1/agent/metrics
[info] Sent 200 in 45ms
Verification (UI):
- Equipment page shows recent sensor readings
- Charts update with new data points
- "Last Check" timestamp is current
Test 5: Heartbeat ✅
Expected Logs (Agent):
INFO towerops_agent::api_client: Sending heartbeat...
INFO towerops_agent::api_client: Heartbeat successful
Expected Logs (Phoenix):
[info] POST /api/v1/agent/heartbeat
[info] Sent 200 in 12ms
Verification:
- Agent "Last Seen" updates every 60 seconds
- Agent status remains "Online"
- Agent metadata shows correct version, hostname, uptime
Database Check:
SELECT
name,
last_seen_at,
metadata->>'version' as version,
metadata->>'hostname' as hostname,
metadata->>'uptime_seconds' as uptime
FROM agent_tokens
WHERE name = 'Test Agent';
Test 6: API Outage Resilience ✅
Test Procedure:
- Stop Phoenix server:
Ctrl+Cin Phoenix terminal - Wait 2 minutes (agent continues polling)
- Restart Phoenix server:
mix phx.server
Expected Behavior (Agent):
WARN towerops_agent::api_client: Failed to submit metrics: Connection refused
INFO towerops_agent::buffer::storage: Metrics stored in buffer, will retry
INFO towerops_agent::poller::executor: Continuing to poll locally
After Phoenix Restart:
INFO towerops_agent::api_client: API connection restored
INFO towerops_agent::api_client: Flushing buffered metrics (15 pending)
INFO towerops_agent::api_client: Metrics submitted successfully: 15 accepted
Verification:
- No data loss during outage
- All buffered metrics submitted after reconnection
- Timestamps reflect actual poll times (not submission time)
- SQLite database size grows during outage, shrinks after
Database Check:
# During outage
ls -lh data/towerops-agent.db
# Size should increase
# After reconnection
ls -lh data/towerops-agent.db
# Size should decrease as metrics are sent
Test 7: Token Revocation ✅
Test Procedure:
- In UI, navigate to agent details
- Click "Revoke Token" or disable agent
- Observe agent logs
Expected Logs (Agent):
ERROR towerops_agent::api_client: Authentication failed: 401 Unauthorized
ERROR towerops_agent::poller::scheduler: Failed to fetch config: authentication error
Verification:
- Agent stops polling immediately
- No new metrics appear in database
- Agent status shows "Offline" in UI
- Agent logs show authentication errors
Test 8: Network Interruption ✅
Test Procedure:
- While agent is running, simulate network issue:
# Block localhost traffic temporarily (requires sudo) sudo ifconfig lo0 down sleep 10 sudo ifconfig lo0 up
Expected Behavior:
WARN towerops_agent::api_client: Network error: Connection timeout
INFO towerops_agent::buffer::storage: Buffering metrics locally
INFO towerops_agent::api_client: Retrying connection...
INFO towerops_agent::api_client: Connection restored
Verification:
- Agent continues polling during network outage
- Metrics buffered locally
- Automatic reconnection after network restored
- All metrics eventually submitted
Phase 4: Load Testing
Test 9: Multiple Equipment Assignment
Setup:
- Create 10 equipment entries with SNMP enabled
- Assign all to same agent
- Each equipment has 2-3 sensors and 1-2 interfaces
Expected Behavior:
- Agent polls all equipment in parallel
- Memory usage stays under 50 MB
- CPU usage reasonable (<25% of one core)
- All metrics submitted successfully
- Poll interval maintained (60s ±5s)
Monitoring:
# Watch agent resource usage
podman stats <container-id>
# Check database growth
watch -n 5 'du -h data/towerops-agent.db'
# Monitor metrics rate
psql towerops_dev -c "
SELECT
COUNT(*) as total_readings,
MAX(checked_at) as latest,
MIN(checked_at) as earliest
FROM snmp_sensor_readings
WHERE checked_at > NOW() - INTERVAL '5 minutes';"
Test 10: 24-Hour Stability Test
Setup:
- Configure agent with 5-10 equipment
- Run continuously for 24 hours
- Monitor for crashes, memory leaks, connection issues
Metrics to Track:
- Uptime (should be 24+ hours)
- Memory usage (should be stable, not growing)
- CPU usage (should be consistent)
- Database size (should cycle, not grow indefinitely)
- Error rate (should be near zero)
- Metrics success rate (should be >99%)
Check Script:
#!/bin/bash
# stability-check.sh
while true; do
echo "=== $(date) ==="
# Agent container status
podman ps | grep towerops-agent
# Memory usage
podman stats --no-stream towerops-agent | tail -1
# Database size
du -h data/towerops-agent.db
# Recent metrics count
psql towerops_dev -c "SELECT COUNT(*) FROM snmp_sensor_readings WHERE checked_at > NOW() - INTERVAL '5 minutes';"
sleep 300 # Check every 5 minutes
done
Success Criteria
All tests must pass for agent to be production-ready:
- Agent authenticates with token successfully
- Agent fetches configuration from API
- Agent polls SNMP devices (sensors + interfaces)
- Metrics appear in database within 60 seconds
- Threshold violations trigger events (requires threshold configuration)
- Agent survives 24h API outage without data loss
- UI shows agent status (online/offline)
- Token revocation works immediately
- Agent uses <256 MB memory with 50 devices
- Docker image is <50 MB (actual: 11.8 MB)
- Load test: 100 devices, 500 sensors, 200 interfaces
- Stability test: 7 days continuous operation
Troubleshooting
Agent Won't Start
Symptoms: Agent exits immediately or fails to start
Checks:
- Verify token is valid:
echo $TOWEROPS_AGENT_TOKEN - Check API URL is correct:
curl http://localhost:4000/health - Check logs:
podman logs <container-id> - Verify database directory is writable:
ls -la data/
Agent Shows Offline in UI
Symptoms: Agent is running but shows offline
Checks:
- Check last_seen_at in database
- Verify heartbeat endpoint works:
curl -H "Authorization: Bearer $TOKEN" http://localhost:4000/api/v1/agent/heartbeat -X POST - Check for clock skew between agent and server
- Verify agent can reach Phoenix server
No Metrics Appearing
Symptoms: Agent running but no data in database
Checks:
- Verify SNMP device is reachable from agent
- Check SNMP credentials are correct
- Check equipment is assigned to agent
- Check agent logs for SNMP errors
- Verify equipment has discovered sensors/interfaces
High Memory Usage
Symptoms: Agent memory usage growing over time
Checks:
- Check database size:
du -h data/towerops-agent.db - Check how many metrics are buffered
- Verify metrics are being submitted (not just buffered)
- Check cleanup job is running (should run every hour)
Next Steps After Integration Testing
Once integration testing passes:
- Performance Testing: Load test with 100+ devices
- Stability Testing: 7-day continuous run
- Container Registry: Publish image to registry
- Release Tagging: Tag v0.1.0 release
- Beta Testing: Deploy to select customers
- Monitoring Setup: Grafana dashboards and alerts
- Documentation: Update with real-world examples and screenshots