Files
FabledSteward/tests/integration/test_ansible_inventory.py
T

179 lines
5.9 KiB
Python

"""Integration tests: ansible_targets / ansible_groups tables + fetch_scope_targets.
Requires a live Postgres DB (STEWARD_DATABASE_URL).
Run with:
pytest tests/integration/test_ansible_inventory.py -m integration -v
"""
from __future__ import annotations
import os
import uuid
import pytest
from sqlalchemy import select, text
pytestmark = pytest.mark.integration
_NEEDS_DB = pytest.mark.skipif(
not os.environ.get("STEWARD_DATABASE_URL"),
reason="integration test needs a live Postgres (STEWARD_DATABASE_URL)",
)
def _make_app():
from steward.app import create_app
import asyncio
return asyncio.run(create_app(testing=False))
@_NEEDS_DB
def test_ansible_targets_table_exists():
"""Migration 0015 created the ansible_targets table."""
app = _make_app()
async def _check():
async with app.db_sessionmaker() as db:
result = await db.execute(
text(
"SELECT column_name FROM information_schema.columns "
"WHERE table_name = 'ansible_targets'"
)
)
return {row[0] for row in result.fetchall()}
import asyncio
columns = asyncio.run(_check())
assert "id" in columns
assert "name" in columns
assert "address" in columns
assert "ansible_vars" in columns
assert "host_id" in columns
@_NEEDS_DB
def test_ansible_groups_table_exists():
"""Migration 0016 created ansible_groups and ansible_target_groups."""
app = _make_app()
async def _check():
async with app.db_sessionmaker() as db:
groups_result = await db.execute(
text(
"SELECT column_name FROM information_schema.columns "
"WHERE table_name = 'ansible_groups'"
)
)
groups_cols = {row[0] for row in groups_result.fetchall()}
join_result = await db.execute(
text(
"SELECT column_name FROM information_schema.columns "
"WHERE table_name = 'ansible_target_groups'"
)
)
join_cols = {row[0] for row in join_result.fetchall()}
return groups_cols, join_cols
import asyncio
groups_cols, join_cols = asyncio.run(_check())
assert "id" in groups_cols
assert "name" in groups_cols
assert "ansible_vars" in groups_cols
assert "target_id" in join_cols
assert "group_id" in join_cols
@_NEEDS_DB
def test_ansible_run_scope_column_exists():
"""Migration 0017 added inventory_scope to ansible_runs."""
app = _make_app()
async def _check():
async with app.db_sessionmaker() as db:
result = await db.execute(
text(
"SELECT column_name FROM information_schema.columns "
"WHERE table_name = 'ansible_runs'"
)
)
return {row[0] for row in result.fetchall()}
import asyncio
columns = asyncio.run(_check())
assert "inventory_scope" in columns
assert "inventory_path" in columns
@_NEEDS_DB
def test_create_target_and_group_and_fetch():
"""Can create a target+group, assign membership, and fetch via fetch_scope_targets."""
from steward.models.ansible_inventory import AnsibleTarget, AnsibleGroup
from steward.ansible.inventory_gen import fetch_scope_targets, generate_inventory
app = _make_app()
target_id = str(uuid.uuid4())
group_id = str(uuid.uuid4())
target_name = f"test-target-{target_id[:8]}"
group_name = f"test-group-{group_id[:8]}"
async def _run():
# Create
async with app.db_sessionmaker() as db:
async with db.begin():
grp = AnsibleGroup(
id=group_id,
name=group_name,
ansible_vars={"env": "test"},
)
tgt = AnsibleTarget(
id=target_id,
name=target_name,
address="10.0.99.1",
ansible_vars={"ansible_user": "ubuntu"},
)
tgt.groups.append(grp)
db.add(grp)
db.add(tgt)
# Fetch all — target must be in the list
async with app.db_sessionmaker() as db:
all_targets = await fetch_scope_targets(db, "steward:all")
assert any(t.id == target_id for t in all_targets)
# Fetch by group
async with app.db_sessionmaker() as db:
group_targets = await fetch_scope_targets(db, f"steward:group:{group_id}")
assert any(t.id == target_id for t in group_targets)
# Fetch single target
async with app.db_sessionmaker() as db:
single = await fetch_scope_targets(db, f"steward:target:{target_id}")
assert len(single) == 1
assert single[0].id == target_id
# Generate inventory and verify var merging
async with app.db_sessionmaker() as db:
targets = await fetch_scope_targets(db, f"steward:group:{group_id}")
inv = generate_inventory(targets)
assert target_name in inv["all"]["hosts"]
assert target_name in inv[group_name]["hosts"]
assert inv["_meta"]["hostvars"][target_name]["ansible_host"] == "10.0.99.1"
assert inv["_meta"]["hostvars"][target_name]["ansible_user"] == "ubuntu"
assert inv["_meta"]["hostvars"][target_name]["env"] == "test"
# Cleanup
async with app.db_sessionmaker() as db:
async with db.begin():
t = (await db.execute(
select(AnsibleTarget).where(AnsibleTarget.id == target_id)
)).scalar_one_or_none()
if t:
await db.delete(t)
g = (await db.execute(
select(AnsibleGroup).where(AnsibleGroup.id == group_id)
)).scalar_one_or_none()
if g:
await db.delete(g)
import asyncio
asyncio.run(_run())