towerops-agent/INTEGRATION_TEST_PLAN.md
Graham McIntire 316c0b04f9
Add integration test plan and user guide
- 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
2026-01-14 09:10:00 -06:00

507 lines
14 KiB
Markdown

# 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:
```bash
# 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**:
```bash
# 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
1. **Start Phoenix Server**:
```bash
cd /Users/graham/dev/towerops
mix phx.server
# Access at http://localhost:4000
```
2. **Create Organization and User** (if not exists):
- Register a test user via UI
- Create organization "Test Org"
3. **Create Test Equipment**:
- Navigate to Sites → Create Site "Test Site"
- Add Equipment "Test Router"
- IP Address: `127.0.0.1:1161` (if using simulator) or `10.0.19.254` (real device)
- SNMP Enabled: Yes
- SNMP Version: 2c
- SNMP Community: `public` (simulator) or `kdyyJrT0Mm` (real device)
- Poll Interval: 60 seconds
4. **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
5. **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
6. **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
1. **Create agent configuration**:
```bash
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**:
```bash
# 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)
```bash
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**:
```sql
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)**:
```sql
-- 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**:
```sql
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**:
1. Stop Phoenix server: `Ctrl+C` in Phoenix terminal
2. Wait 2 minutes (agent continues polling)
3. 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**:
```bash
# 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**:
1. In UI, navigate to agent details
2. Click "Revoke Token" or disable agent
3. 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**:
1. While agent is running, simulate network issue:
```bash
# 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**:
1. Create 10 equipment entries with SNMP enabled
2. Assign all to same agent
3. 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**:
```bash
# 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**:
1. Configure agent with 5-10 equipment
2. Run continuously for 24 hours
3. 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**:
```bash
#!/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:
- [x] Agent authenticates with token successfully
- [x] Agent fetches configuration from API
- [x] Agent polls SNMP devices (sensors + interfaces)
- [x] Metrics appear in database within 60 seconds
- [ ] Threshold violations trigger events (requires threshold configuration)
- [x] Agent survives 24h API outage without data loss
- [x] UI shows agent status (online/offline)
- [x] Token revocation works immediately
- [x] Agent uses <256 MB memory with 50 devices
- [x] 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**:
1. Verify token is valid: `echo $TOWEROPS_AGENT_TOKEN`
2. Check API URL is correct: `curl http://localhost:4000/health`
3. Check logs: `podman logs <container-id>`
4. Verify database directory is writable: `ls -la data/`
### Agent Shows Offline in UI
**Symptoms**: Agent is running but shows offline
**Checks**:
1. Check last_seen_at in database
2. Verify heartbeat endpoint works: `curl -H "Authorization: Bearer $TOKEN" http://localhost:4000/api/v1/agent/heartbeat -X POST`
3. Check for clock skew between agent and server
4. Verify agent can reach Phoenix server
### No Metrics Appearing
**Symptoms**: Agent running but no data in database
**Checks**:
1. Verify SNMP device is reachable from agent
2. Check SNMP credentials are correct
3. Check equipment is assigned to agent
4. Check agent logs for SNMP errors
5. Verify equipment has discovered sensors/interfaces
### High Memory Usage
**Symptoms**: Agent memory usage growing over time
**Checks**:
1. Check database size: `du -h data/towerops-agent.db`
2. Check how many metrics are buffered
3. Verify metrics are being submitted (not just buffered)
4. Check cleanup job is running (should run every hour)
## Next Steps After Integration Testing
Once integration testing passes:
1. **Performance Testing**: Load test with 100+ devices
2. **Stability Testing**: 7-day continuous run
3. **Container Registry**: Publish image to registry
4. **Release Tagging**: Tag v0.1.0 release
5. **Beta Testing**: Deploy to select customers
6. **Monitoring Setup**: Grafana dashboards and alerts
7. **Documentation**: Update with real-world examples and screenshots