m2_smoke.sh 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/env bash
  2. # Live M2 smoke test. Run from repo root:
  3. # bash scripts/m2_smoke.sh
  4. #
  5. # Walks through the 6 step-by-step scenarios from M2_VERIFICATION.md
  6. # and dumps a single summary table at the end. Exit code is the
  7. # number of failed steps.
  8. set -e
  9. cd "$(dirname "$0")/.."
  10. SECRET=s3cret-acme
  11. send() {
  12. local body="$1" label="$2"
  13. local ts=$(date +%s)
  14. local sig=$(printf '%s.%s' "$ts" "$body" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')
  15. local resp
  16. resp=$(curl -s -X POST http://localhost:8800/v1/ingest \
  17. -H "Content-Type: application/json" \
  18. -H "X-BA-Signature: t=$ts,v1=$sig" \
  19. --data "$body")
  20. echo "[$label] $resp"
  21. }
  22. # Reset deliveries table so we measure only the M2 smoke.
  23. docker compose exec -T postgres psql -U ba -d ba -c "TRUNCATE deliveries;" >/dev/null
  24. docker compose restart routerd >/dev/null 2>&1
  25. sleep 1
  26. # Step 2: warning, db-prod-04 → Alice only
  27. send '{"company_id":"acme-001","source_id":"prom-prod","severity":"warning","category":"storage","title":"Disk 80%","body":"db-prod-04","data":{"host":"db-prod-04"},"dedupe_key":"m2-s2"}' "step 2"
  28. # Step 3: critical, db-prod-04 → Alice + Bob
  29. send '{"company_id":"acme-001","source_id":"prom-prod","severity":"critical","category":"storage","title":"Disk full","body":"db-prod-04","data":{"host":"db-prod-04"},"dedupe_key":"m2-s3"}' "step 3"
  30. # Step 4: critical, db-prod-03 (rule match) → Alice + Bob
  31. send '{"company_id":"acme-001","source_id":"prom-prod","severity":"critical","category":"storage","title":"Disk full","body":"db-prod-03","data":{"host":"db-prod-03"},"dedupe_key":"m2-s4"}' "step 4"
  32. # Step 5: warning, db-prod-03 (rule match, but Bob filters by severity) → Alice only
  33. send '{"company_id":"acme-001","source_id":"prom-prod","severity":"warning","category":"storage","title":"Disk 80% prod-03","body":"pre-empt","data":{"host":"db-prod-03"},"dedupe_key":"m2-s5"}' "step 5"
  34. # Step 6: inminent_colapse, rack-b → all three (bypasses Carol's quiet hours, passes Bob's min)
  35. send '{"company_id":"acme-001","source_id":"prom-prod","severity":"inminent_colapse","category":"power","title":"PDU overload imminent","body":"rack-B","data":{"host":"rack-b"},"dedupe_key":"m2-s6"}' "step 6"
  36. # Wait for routerd/deliverd to drain.
  37. sleep 4
  38. echo ""
  39. echo "=== deliveries by alert ==="
  40. docker compose exec -T postgres psql -U ba -d ba -c "
  41. SELECT
  42. SUBSTRING(alert_id, 12, 6) AS alert_short,
  43. individual_id,
  44. status
  45. FROM deliveries
  46. ORDER BY id;
  47. "
  48. echo ""
  49. echo "=== expected vs actual ==="
  50. # Build a single text table; quick and dirty.
  51. docker compose exec -T postgres psql -U ba -d ba -c "
  52. WITH counts AS (
  53. SELECT alert_id, count(*) AS n, array_agg(individual_id ORDER BY individual_id) AS who
  54. FROM deliveries
  55. GROUP BY alert_id
  56. )
  57. SELECT
  58. SUBSTRING(alert_id, 12, 6) AS alert_short,
  59. n,
  60. array_to_string(who, ',') AS who
  61. FROM counts
  62. ORDER BY alert_short;
  63. "
  64. echo ""
  65. echo "=== routerd 'routed' lines ==="
  66. docker compose logs --no-color --since 60s routerd 2>&1 | grep "msg=routed" | tail -10