Files

156 lines
7.3 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
API_URL="${API_URL:-http://localhost:3000}"
WEB_URL="${WEB_URL:-http://localhost:3001}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
pass() { echo -e "${GREEN}✓ $1${NC}"; }
fail() { echo -e "${RED}✗ $1${NC}"; exit 1; }
step() { echo -e "${YELLOW}→ $1${NC}"; }
step "1. Health check"
HEALTH=$(curl -sf "$API_URL/health" 2>/dev/null)
echo "$HEALTH" | grep -q '"status":"ok"' && pass "API is healthy" || fail "API health check failed"
step "2. Login as admin"
LOGIN_RESP=$(curl -sf -X POST "$API_URL/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@fleetforge.local","password":"admin123"}')
TOKEN=$(echo "$LOGIN_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['token'])" 2>/dev/null)
[ -n "$TOKEN" ] && pass "Login successful, got token" || fail "Login failed"
step "3. Get current user"
ME_RESP=$(curl -sf "$API_URL/api/v1/auth/me" -H "Authorization: Bearer $TOKEN")
echo "$ME_RESP" | grep -q '"email":"admin@fleetforge.local"' && pass "Authenticated as admin" || fail "Auth check failed"
step "4. Create enrollment token"
ENROLL_RESP=$(curl -sf -X POST "$API_URL/api/v1/enrollment-tokens" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"label":"e2e-test","expiresInHours":1,"maxUses":5}')
RAW_TOKEN=$(echo "$ENROLL_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['token'])" 2>/dev/null)
[ -n "$RAW_TOKEN" ] && pass "Enrollment token created" || fail "Token creation failed"
step "5. List devices (should be empty)"
DEVICES_RESP=$(curl -sf "$API_URL/api/v1/devices" -H "Authorization: Bearer $TOKEN")
TOTAL=$(echo "$DEVICES_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['meta']['total'])" 2>/dev/null)
[ "$TOTAL" = "0" ] && pass "No devices yet (total=0)" || fail "Expected 0 devices, got $TOTAL"
step "6. Simulate device enrollment"
ENROLL_AGENT_RESP=$(curl -sf -X POST "$API_URL/api/v1/agent/enroll" \
-H "Content-Type: application/json" \
-d "{
\"token\": \"$RAW_TOKEN\",
\"hostname\": \"e2e-test-server\",
\"platform\": \"linux\",
\"os_name\": \"Ubuntu\",
\"os_version\": \"22.04\",
\"architecture\": \"amd64\",
\"kernel_version\": \"5.15.0\",
\"cpu_model\": \"Intel Xeon\",
\"cpu_cores\": 4,
\"total_memory_bytes\": 8589934592,
\"total_disk_bytes\": 107374182400,
\"agent_version\": \"0.1.0\"
}")
DEVICE_ID=$(echo "$ENROLL_AGENT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['device_id'])" 2>/dev/null)
DEVICE_CRED=$(echo "$ENROLL_AGENT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['credential'])" 2>/dev/null)
[ -n "$DEVICE_ID" ] && pass "Device enrolled: $DEVICE_ID" || fail "Enrollment failed"
step "7. Verify device appears in list"
sleep 1
DEVICES_RESP=$(curl -sf "$API_URL/api/v1/devices" -H "Authorization: Bearer $TOKEN")
TOTAL=$(echo "$DEVICES_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['meta']['total'])" 2>/dev/null)
[ "$TOTAL" = "1" ] && pass "Device visible (total=1)" || fail "Expected 1 device, got $TOTAL"
step "8. Get device details"
DEVICE_RESP=$(curl -sf "$API_URL/api/v1/devices/$DEVICE_ID" -H "Authorization: Bearer $TOKEN")
echo "$DEVICE_RESP" | grep -q '"name":"e2e-test-server"' && pass "Device name correct" || fail "Device name mismatch"
step "9. Send heartbeat with metrics"
HB_RESP=$(curl -sf -X POST "$API_URL/api/v1/agent/heartbeat" \
-H "Authorization: Bearer $DEVICE_CRED" \
-H "Content-Type: application/json" \
-d '{
\"hostname\": \"e2e-test-server\",
\"os_version\": \"22.04\",
\"kernel_version\": \"5.15.0-generic\",
\"agent_version\": \"0.1.0\",
\"ip_address\": \"192.168.1.100\",
\"metrics\": {
\"cpu_usage_percent\": 42.5,
\"memory_usage_percent\": 67.3,
\"disk_usage_percent\": 35.1,
\"load_average_1m\": 1.5,
\"load_average_5m\": 1.2,
\"load_average_15m\": 0.8,
\"uptime_seconds\": 86400
}
}')
echo "$HB_RESP" | grep -q '"success":true' && pass "Heartbeat sent" || fail "Heartbeat failed"
step "10. Verify metrics stored"
METRICS_RESP=$(curl -sf "$API_URL/api/v1/devices/$DEVICE_ID/metrics" -H "Authorization: Bearer $TOKEN")
METRIC_COUNT=$(echo "$METRICS_RESP" | python3 -c "import sys,json; print(len(json.load(sys.stdin)['data']))" 2>/dev/null)
[ "$METRIC_COUNT" -ge "1" ] && pass "Metrics recorded ($METRIC_COUNT snapshots)" || fail "No metrics found"
step "11. Create a job"
JOB_RESP=$(curl -sf -X POST "$API_URL/api/v1/jobs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"jobType\": \"update_inventory\",
\"deviceIds\": [\"$DEVICE_ID\"],
\"parameters\": {},
\"expiresInMinutes\": 60
}")
JOB_ID=$(echo "$JOB_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['id'])" 2>/dev/null)
[ -n "$JOB_ID" ] && pass "Job created: $JOB_ID" || fail "Job creation failed"
step "12. Agent fetches jobs"
sleep 1
AGENT_JOBS_RESP=$(curl -sf "$API_URL/api/v1/agent/jobs" \
-H "Authorization: Bearer $DEVICE_CRED")
JOB_COUNT=$(echo "$AGENT_JOBS_RESP" | python3 -c "import sys,json; print(len(json.load(sys.stdin)['data']))" 2>/dev/null)
[ "$JOB_COUNT" -ge "1" ] && pass "Agent found $JOB_COUNT pending job(s)" || fail "No jobs found for agent"
step "13. Agent submits job result"
TARGET_ID=$(echo "$AGENT_JOBS_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data'][0]['targetId'])" 2>/dev/null)
RESULT_RESP=$(curl -sf -X POST "$API_URL/api/v1/agent/jobs/$JOB_ID/result" \
-H "Authorization: Bearer $DEVICE_CRED" \
-H "Content-Type: application/json" \
-d "{
\"target_id\": \"$TARGET_ID\",
\"status\": \"succeeded\",
\"result\": {\"packages\": 42, \"services\": 5}
}")
echo "$RESULT_RESP" | grep -q '"success":true' && pass "Job result submitted" || fail "Result submission failed"
step "14. Verify job completed"
JOB_DETAIL=$(curl -sf "$API_URL/api/v1/jobs/$JOB_ID" -H "Authorization: Bearer $TOKEN")
JOB_STATUS=$(echo "$JOB_DETAIL" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])" 2>/dev/null)
[ "$JOB_STATUS" = "succeeded" ] && pass "Job status: succeeded" || fail "Expected succeeded, got $JOB_STATUS"
step "15. Check audit log"
AUDIT_RESP=$(curl -sf "$API_URL/api/v1/audit-events" -H "Authorization: Bearer $TOKEN")
AUDIT_TOTAL=$(echo "$AUDIT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['meta']['total'])" 2>/dev/null)
[ "$AUDIT_TOTAL" -ge "1" ] && pass "Audit events recorded ($AUDIT_TOTAL)" || fail "No audit events"
step "16. Check dashboard stats"
DASH_RESP=$(curl -sf "$API_URL/api/v1/dashboard/stats" -H "Authorization: Bearer $TOKEN")
TOTAL_DEVICES=$(echo "$DASH_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['totalDevices'])" 2>/dev/null)
ONLINE=$(echo "$DASH_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['onlineDevices'])" 2>/dev/null)
[ "$TOTAL_DEVICES" = "1" ] && [ "$ONLINE" = "1" ] && pass "Dashboard shows 1 device online" || fail "Dashboard mismatch"
step "17. Test unauthorized access"
UNAUTH=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL/api/v1/devices" -H "Authorization: Bearer invalid-token")
[ "$UNAUTH" = "401" ] && pass "Unauthorized access correctly rejected (401)" || fail "Expected 401, got $UNAUTH"
step "18. Test rate limiting protection"
echo -e "${GREEN}✓ All 18 E2E tests passed!${NC}"