148 lines
3.4 KiB
Python
148 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from infra_controller.config import DiscoveryConfig
|
|
from infra_controller.discovery import InfraMetadata
|
|
from infra_controller.discovery import DiscoveryManager
|
|
|
|
|
|
def _write(path: Path, content: str) -> Path:
|
|
path.write_text(content, encoding="utf-8")
|
|
return path
|
|
|
|
|
|
def test_infra_metadata_toml_valid(tmp_path: Path) -> None:
|
|
p = _write(
|
|
tmp_path / ".infra.toml",
|
|
"""
|
|
project = "my-app"
|
|
|
|
[requires]
|
|
services = ["grafana", "prometheus"]
|
|
""".lstrip(),
|
|
)
|
|
|
|
md = InfraMetadata.from_file(p)
|
|
assert md.project == "my-app"
|
|
assert md.requires["services"] == ["grafana", "prometheus"]
|
|
|
|
|
|
def test_infra_metadata_yaml_valid_uses_dir_name_when_project_missing(tmp_path: Path) -> None:
|
|
proj_dir = tmp_path / "some-app"
|
|
proj_dir.mkdir()
|
|
p = _write(
|
|
proj_dir / ".infra.yml",
|
|
"""
|
|
requires:
|
|
services: grafana
|
|
""".lstrip(),
|
|
)
|
|
|
|
md = InfraMetadata.from_file(p)
|
|
assert md.project == "some-app"
|
|
assert md.requires["services"] == "grafana"
|
|
|
|
|
|
def test_infra_metadata_invalid_top_level(tmp_path: Path) -> None:
|
|
p = _write(tmp_path / ".infra.yml", "- not-a-mapping\n")
|
|
|
|
with pytest.raises(ValueError, match=r"expected mapping"):
|
|
InfraMetadata.from_file(p)
|
|
|
|
|
|
def test_infra_metadata_invalid_project(tmp_path: Path) -> None:
|
|
p = _write(
|
|
tmp_path / ".infra.toml",
|
|
"""
|
|
project = "bad name"
|
|
[requires]
|
|
services = "grafana"
|
|
""".lstrip(),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match=r"Invalid 'project'"):
|
|
InfraMetadata.from_file(p)
|
|
|
|
|
|
def test_infra_metadata_invalid_requires_type(tmp_path: Path) -> None:
|
|
p = _write(
|
|
tmp_path / ".infra.yml",
|
|
"""
|
|
project: app
|
|
requires: not-a-mapping
|
|
""".lstrip(),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match=r"Invalid 'requires'"):
|
|
InfraMetadata.from_file(p)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"services",
|
|
[
|
|
"[]",
|
|
"[\"\"]",
|
|
"[1]",
|
|
],
|
|
)
|
|
def test_infra_metadata_invalid_requires_services_list(tmp_path: Path, services: str) -> None:
|
|
p = _write(
|
|
tmp_path / ".infra.toml",
|
|
(
|
|
"project = \"app\"\n\n"
|
|
"[requires]\n"
|
|
f"services = {services}\n"
|
|
),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match=r"requires\.services"):
|
|
InfraMetadata.from_file(p)
|
|
|
|
|
|
def test_infra_metadata_invalid_requires_services_type(tmp_path: Path) -> None:
|
|
p = _write(
|
|
tmp_path / ".infra.yml",
|
|
"""
|
|
project: app
|
|
requires:
|
|
services: 123
|
|
""".lstrip(),
|
|
)
|
|
|
|
with pytest.raises(ValueError, match=r"requires\.services"):
|
|
InfraMetadata.from_file(p)
|
|
|
|
|
|
def test_discover_scan_prefers_toml_over_yaml_in_same_dir(tmp_path: Path, monkeypatch) -> None:
|
|
base = tmp_path / "apps"
|
|
proj = base / "proj"
|
|
(proj / ".git").mkdir(parents=True)
|
|
(proj / ".git" / "HEAD").write_text("ref: refs/heads/main\n", encoding="utf-8")
|
|
|
|
_write(
|
|
proj / ".infra.toml",
|
|
"""
|
|
project = "proj"
|
|
|
|
[requires]
|
|
services = ["svc_toml"]
|
|
""".lstrip(),
|
|
)
|
|
_write(
|
|
proj / ".infra.yml",
|
|
"""
|
|
project: proj
|
|
requires:
|
|
services: svc_yaml
|
|
""".lstrip(),
|
|
)
|
|
|
|
cfg = DiscoveryConfig(scan_enabled=True, scan_paths=[base], file_based_enabled=False)
|
|
mgr = DiscoveryManager(cfg)
|
|
|
|
apps = mgr.discover_all()
|
|
assert set(apps.keys()) == {"proj"}
|
|
assert apps["proj"].metadata.requires["services"] == ["svc_toml"]
|