test: add end-to-end agent deployment lifecycle test
This commit is contained in:
parent
2382e17830
commit
cd505b9994
1 changed files with 104 additions and 0 deletions
104
tests/test_e2e_flow.py
Normal file
104
tests/test_e2e_flow.py
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import pytest
|
||||
import subprocess
|
||||
import os
|
||||
import uuid
|
||||
import testinfra
|
||||
import time
|
||||
|
||||
# Use the bin/infra wrapper for testing
|
||||
CLI_BIN = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "bin", "infra"))
|
||||
CONFIG_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "config.yaml"))
|
||||
SSH_KEY = os.path.expanduser("~/.ssh/id_ed25519_no_pass")
|
||||
ROUTER_PASS = "kpvoh58zhq2sq6ms"
|
||||
|
||||
def run_infra(cmd, env=None):
|
||||
full_env = os.environ.copy()
|
||||
if env:
|
||||
full_env.update(env)
|
||||
full_env["ROUTER_PASS"] = ROUTER_PASS
|
||||
full_cmd = [CLI_BIN, "--config", CONFIG_PATH] + cmd
|
||||
return subprocess.run(full_cmd, capture_output=True, text=True, env=full_env)
|
||||
|
||||
def get_testinfra_host(host_str):
|
||||
return testinfra.get_host(
|
||||
f"ssh://root@{host_str}",
|
||||
ssh_identity_file=SSH_KEY,
|
||||
ssh_extra_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def agent_context():
|
||||
"""Provides a unique context for an agent service deployment"""
|
||||
uid = str(uuid.uuid4())[:8]
|
||||
return {
|
||||
"id": uid,
|
||||
"name": f"agent-svc-{uid}",
|
||||
"domain": f"agent-{uid}.loopaware.com",
|
||||
"mac": f"aa:bb:cc:ee:ff:{uid[:2]}",
|
||||
"port": 8080
|
||||
}
|
||||
|
||||
def test_e2e_agent_deployment_lifecycle(agent_context):
|
||||
"""
|
||||
Tests the complete flow:
|
||||
IPAM -> DB -> DNS -> Ingress -> Cloudflare -> Decommission
|
||||
"""
|
||||
ctx = agent_context
|
||||
print(f"\n[E2E] Starting deployment for {ctx['name']}")
|
||||
|
||||
# 1. IPAM: Find next free IP
|
||||
res = run_infra(["ip", "next-free"])
|
||||
assert res.returncode == 0
|
||||
ip = res.stdout.strip()
|
||||
print(f"[E2E] Allocated IP: {ip}")
|
||||
|
||||
# 2. Database: Provision PostgreSQL
|
||||
res = run_infra(["db", "provision", ctx['name']])
|
||||
assert res.returncode == 0
|
||||
assert ctx['name'].replace("-", "_") in res.stdout
|
||||
print("[E2E] Database provisioned")
|
||||
|
||||
# 3. DNS: Register DHCP Host
|
||||
res = run_infra(["dns", "add-host", ctx['mac'], ip, ctx['name']])
|
||||
assert res.returncode == 0
|
||||
print("[E2E] DNS/DHCP host registered")
|
||||
|
||||
# 4. Ingress: Configure HAProxy
|
||||
res = run_infra(["ingress", "add", ctx['domain'], ip, str(ctx['port'])])
|
||||
assert res.returncode == 0
|
||||
print(f"[E2E] Ingress configured for {ctx['domain']}")
|
||||
|
||||
# 5. Cloudflare: Add to DDNS list
|
||||
res = run_infra(["cloudflare", "add-ddns", ctx['domain']])
|
||||
assert res.returncode == 0
|
||||
print("[E2E] Cloudflare DDNS registered")
|
||||
|
||||
# --- VERIFICATION PHASE ---
|
||||
print("[E2E] Verifying infrastructure state...")
|
||||
|
||||
# Verify HAProxy points to the CORRECT allocated IP
|
||||
pve = get_testinfra_host("10.32.2.1")
|
||||
# Wrap in single quotes to protect from local shell, double for remote
|
||||
be_name = f"be_{ctx['domain'].replace('.', '_')}"
|
||||
res = pve.run(f"pct exec 11220 -- grep -A 5 '{be_name}' /etc/haproxy/conf.d/99-dynamic.cfg")
|
||||
assert res.rc == 0
|
||||
assert ip in res.stdout
|
||||
assert str(ctx['port']) in res.stdout
|
||||
|
||||
# Verify Database exists
|
||||
db_host = get_testinfra_host("10.32.70.54")
|
||||
db_name = ctx['name'].lower().replace("-", "_")
|
||||
# Safer check: use psql -t -c to get raw list
|
||||
res = db_host.run(f"su - postgres -c \"psql -t -c '\\l' | grep -qw {db_name}\"")
|
||||
assert res.rc == 0
|
||||
|
||||
# --- CLEANUP / DECOMMISSION PHASE ---
|
||||
print("[E2E] Starting decommissioning...")
|
||||
res = run_infra(["decommission", "--domain", ctx['domain'], "--mac", ctx['mac']])
|
||||
assert res.returncode == 0
|
||||
|
||||
# Final state check: should be gone in sites.json
|
||||
res = pve.run(f"pct exec 11220 -- grep '{ctx['domain']}' /etc/haproxy/dynamic/sites.json")
|
||||
assert res.rc != 0
|
||||
|
||||
print("[E2E] Flow completed successfully.")
|
||||
Loading…
Add table
Add a link
Reference in a new issue