Files
FTL/test/api/conftest.py
DL6ER 20164bff26 tests: resolve iCloud Private Relay zones from local pdns
The API query-count assertions depend on resolving mask.icloud.com, whose
mask.icloud.com -> mask.apple-dns.net CNAME chain was recursed to the public
internet. dnsmasq fires extra DNSKEY validation queries depending on whether
Apple currently DNSSEC-signs icloud.com / apple-dns.net, and Apple toggles this
over time. The runtime DS-probing workaround in conftest.py could not reliably
model dnsmasq's behaviour (e.g. when Apple returns SERVFAIL on DS), so the suite
went flaky again.

Serve the icloud.com and apple-dns.net zones from the local authoritative
PowerDNS server instead, so the chain resolves hermetically and the query counts
are deterministic regardless of Apple's upstream DNSSEC posture. The DS-probing
fixture is dropped and the expected counters become fixed constants again.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2026-06-24 06:25:39 +00:00

77 lines
2.2 KiB
Python

"""
Shared pytest fixtures for FTL API integration tests.
"""
import sys
import os
import pytest
import requests
# Add test/api to the path so libs/ can be imported
sys.path.insert(0, os.path.dirname(__file__))
FTL_URL = "http://127.0.0.1"
@pytest.fixture(scope="session")
def ftl_url():
"""Base URL for the FTL API."""
return FTL_URL
@pytest.fixture(scope="session")
def api_session():
"""Shared authenticated requests.Session for the entire test run.
If no password is set, the session works without authentication.
If a password is set, logs in with "ABC" and stores the SID in
the session headers so all subsequent requests are authenticated.
"""
session = requests.Session()
session.headers["Accept"] = "application/json"
try:
r = session.get(f"{FTL_URL}/api/auth", timeout=5)
if r.status_code not in (200, 401):
r.raise_for_status()
except requests.ConnectionError:
pytest.skip("FTL is not running at " + FTL_URL)
data = r.json()
if not data.get("session", {}).get("valid"):
# Password is set — login with "ABC"
r = session.post(f"{FTL_URL}/api/auth",
json={"password": "ABC"}, timeout=10)
sid = r.json().get("session", {}).get("sid")
if sid:
session.headers["X-FTL-SID"] = sid
return session
@pytest.fixture(scope="session")
def openapi():
"""Parsed OpenAPI specifications (session-scoped, parsed once)."""
from libs.openAPI import openApi
specs = openApi(base_path="src/api/docs/content/specs/", api_root="/api")
assert specs.parse("main.yaml"), "Failed to parse OpenAPI specs"
return specs
@pytest.fixture(scope="session")
def ftl():
"""FTLAPI client with endpoints loaded (session-scoped).
Authenticates with password "ABC" if a password is set, otherwise
connects without authentication.
"""
from libs.FTLAPI import FTLAPI
# Check if authentication is required
r = requests.get(f"{FTL_URL}/api/auth", timeout=5)
data = r.json()
if data.get("session", {}).get("valid"):
client = FTLAPI(FTL_URL)
else:
client = FTLAPI(FTL_URL, "ABC")
client.get_endpoints()
return client