Files
awg-dash/tests/deploy/test_compose_manifests.py
T
embeddevio 59c3ad4918 test(#21): тесты инвариантов compose, Make-цели стенда и обновлённый deploy/README
- tests/deploy/test_compose_manifests.py — 7 тестов на compose-инварианты
  (без Docker, только PyYAML) — готовы к включению в CI (#17);
- Makefile: dev-up/dev-up-stub/dev-down/dev-logs/dev-verify/dev-verify-stub/
  dev-reset/test-netns/test-netns-keep/test-netns-ci/test-manifests/lint-shell,
  переменные HOST_DIR, DASH_PORT, NETNS_ARGS; dev-up без docker падает с внятным
  сообщением, а не трейсбеком;
- deploy/README.md — таблица артефактов и быстрые команды стенда.

Refs #21
Refs #15
2026-10-21 23:50:01 +03:00

69 lines
2.9 KiB
Python

"""Тесты статических инвариантов compose-файлов стенда (задача #21).
Проверяют то, что иначе выяснилось бы только на Docker-хосте: порт 8080,
монтирования /config и /data, healthcheck, capabilities, privileged netns-раннер.
Работают без Docker — только PyYAML (см. requirements-dev.txt).
"""
from __future__ import annotations
import pathlib
import unittest
import validate_compose
HERE = pathlib.Path(__file__).resolve().parent
ROOT = HERE.parents[1]
@unittest.skipUnless(validate_compose.yaml is not None, "нужен PyYAML (make venv)")
class ComposeManifestsTest(unittest.TestCase):
def test_dev_compose_matches_acceptance_criteria(self) -> None:
errors, _ = validate_compose.validate(require_dockerfile=False)
self.assertEqual([], errors, "compose-файлы стенда нарушают инварианты AC #21")
def test_dev_compose_publishes_app_port_to_host(self) -> None:
doc = validate_compose.load(validate_compose.DEV)
ports = " ".join(str(p) for p in doc["services"]["awg-dash"]["ports"])
self.assertIn(":8080", ports, "наружу должен публиковаться контейнерный порт приложения 8080")
def test_dev_compose_mounts_state_directories(self) -> None:
doc = validate_compose.load(validate_compose.DEV)
targets = validate_compose._mount_targets(doc["services"]["awg-dash"])
self.assertIn("/config", targets)
self.assertIn("/data", targets)
def test_healthcheck_hits_api_v1_health(self) -> None:
doc = validate_compose.load(validate_compose.DEV)
test_cmd = validate_compose.jsonish(doc["services"]["awg-dash"]["healthcheck"]["test"])
self.assertIn("/api/v1/health", test_cmd)
def test_test_compose_runs_netns_harness_privileged(self) -> None:
doc = validate_compose.load(validate_compose.TEST)
svc = doc["services"]["netns"]
self.assertTrue(svc["privileged"])
self.assertIn("tests/netns/run.sh", " ".join(svc["entrypoint"]))
def test_stub_override_is_labelled_dev_only(self) -> None:
text = validate_compose.STUB.read_text(encoding="utf-8")
self.assertIn("api_stub.py", text)
self.assertIn("DEV", text.upper())
def test_netns_harness_entrypoints_exist(self) -> None:
for rel in (
"tests/netns/run.sh",
"tests/netns/topology.sh",
"tests/netns/lib.sh",
"tests/netns/probe.py",
"tests/netns/mock_wg_endpoint.py",
"tests/netns/leak_sink.py",
"deploy/api_stub.py",
"deploy/verify-dev-stand.sh",
):
with self.subTest(rel=rel):
self.assertTrue((ROOT / rel).exists(), f"нет файла {rel}")
if __name__ == "__main__":
unittest.main(verbosity=2)