prole/tests/installer/test_knoe_conf.py

134 lines
4.2 KiB
Python

import os
from pathlib import Path
import pytest
from knoe import knoe_conf
def _symlink_supported(tmp_path: Path) -> bool:
try:
target = tmp_path / "target"
link = tmp_path / "link"
target.write_text("x")
os.symlink(str(target), str(link))
return link.is_symlink()
except Exception:
return False
def test_layered_cfg_files_order_and_merge(tmp_path: Path):
if not _symlink_supported(tmp_path):
pytest.skip("symlinks not supported")
conf_dir = tmp_path / "conf"
env_dir = conf_dir / "dev"
env_dir.mkdir(parents=True)
(env_dir / "knoe.cfg").write_text(
"[Global]\nNAMESPACE = base\nSERVICE_NAMESPACE = base-svc\n"
)
(env_dir / "10-first.cfg").write_text("[Global]\nNAMESPACE = first\n")
(env_dir / "20-second.cfg").write_text("[Global]\nNAMESPACE = second\n")
(env_dir / "gcp.cfg").write_text('project_id = "demo"\n')
(env_dir / "prod.cfg").write_text("[Global]\nNAMESPACE = ignored\n")
entry = conf_dir / "knoe.cfg"
os.symlink(str(env_dir / "knoe.cfg"), str(entry))
files = knoe_conf.layered_cfg_files(entry)
assert files == [
env_dir / "knoe.cfg",
env_dir / "10-first.cfg",
env_dir / "20-second.cfg",
]
cfg = knoe_conf.load_layered_config(entry)
assert cfg.get("Global", "NAMESPACE") == "second"
assert cfg.get("Global", "SERVICE_NAMESPACE") == "base-svc"
def test_activate_environment_updates_symlink_and_preserves_other_env(tmp_path: Path):
if not _symlink_supported(tmp_path):
pytest.skip("symlinks not supported")
conf_dir = tmp_path / "conf"
(conf_dir / "dev").mkdir(parents=True)
(conf_dir / "service").mkdir(parents=True)
dev_base = conf_dir / "dev" / "knoe.cfg"
svc_base = conf_dir / "service" / "knoe.cfg"
dev_base.write_text("[Global]\nNAMESPACE = dev-ns\n")
svc_base.write_text("[Global]\nNAMESPACE = service-ns\n")
knoe_conf.activate_environment(conf_dir, "dev", create_base_if_missing=False)
entry = conf_dir / "knoe.cfg"
assert entry.is_symlink()
assert entry.resolve() == dev_base
knoe_conf.activate_environment(conf_dir, "service", create_base_if_missing=False)
assert entry.is_symlink()
assert entry.resolve() == svc_base
# Ensure switching does not mutate other environments.
assert dev_base.read_text() == "[Global]\nNAMESPACE = dev-ns\n"
cfg = knoe_conf.load_layered_config(entry)
assert cfg.get("Global", "NAMESPACE") == "service-ns"
def test_test_environment_defaults_not_default_namespace(tmp_path: Path):
if not _symlink_supported(tmp_path):
pytest.skip("symlinks not supported")
conf_dir = tmp_path / "conf"
knoe_conf.activate_environment(conf_dir, "test")
entry = conf_dir / "knoe.cfg"
cfg = knoe_conf.load_layered_config(entry)
ns = cfg.get("Global", "NAMESPACE", fallback="")
assert ns
assert ns != "default"
assert ns == "knoe-test"
@pytest.mark.parametrize(
"mode,expected_env",
[
("k3d", "dev"),
("k3s", "service"),
("k8s", "prod"),
("test", "test"),
],
)
def test_ensure_entrypoint_migrates_legacy_regular_file_based_on_mode(
tmp_path: Path, mode: str, expected_env: str
):
if not _symlink_supported(tmp_path):
pytest.skip("symlinks not supported")
conf_dir = tmp_path / "conf"
conf_dir.mkdir(parents=True)
legacy_text = (
f"[Global]\nDEPLOYMENT_MODE = {mode}\nCLUSTER_ENV = {mode}-example\nNAMESPACE = ns\n"
)
entry = conf_dir / "knoe.cfg"
entry.write_text(legacy_text, encoding="utf-8")
knoe_conf.ensure_entrypoint(conf_dir)
# Entry should now be a symlink to the inferred env base.
assert entry.is_symlink()
target = entry.resolve()
assert target == conf_dir / expected_env / "knoe.cfg"
assert target.read_text(encoding="utf-8") == legacy_text
# Legacy should be preserved as a backup.
backups = list(conf_dir.glob("knoe.cfg.legacy.*"))
assert backups, "expected legacy backup to be created"
assert any(p.read_text(encoding="utf-8") == legacy_text for p in backups)
# All env dirs should exist after bootstrap.
for env in knoe_conf.ENVIRONMENTS:
assert (conf_dir / env).is_dir()