mirror of
https://github.com/pi-hole/FTL.git
synced 2026-07-01 04:45:38 +01:00
20164bff26
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>
77 lines
2.2 KiB
Python
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
|