"""Tests for warden.config.""" from pathlib import Path import pytest import yaml from warden.config import ConfigError, load_config def write_yaml(path: Path, content: dict) -> None: with path.open("w") as f: yaml.dump(content, f) def test_load_local_config(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, {"backend": "local", "ca_key": str(tmp_path / "ca")}) cfg = load_config(cfg_path) assert cfg.backend == "local" assert cfg.ca_key == tmp_path / "ca" def test_local_backend_missing_ca_key_raises(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, {"backend": "local"}) with pytest.raises(ConfigError, match="ca_key"): load_config(cfg_path) def test_invalid_backend_raises(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, {"backend": "magic", "ca_key": "/tmp/ca"}) with pytest.raises(ConfigError, match="backend"): load_config(cfg_path) def test_vault_backend(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, { "backend": "vault", "vault": { "addr": "https://vault.example.com", "role_map": {"adm": "adm-role", "agt": "agt-role", "atm": "atm-role"}, }, }) cfg = load_config(cfg_path) assert cfg.backend == "vault" assert cfg.vault is not None assert cfg.vault.addr == "https://vault.example.com" assert cfg.vault.role_map["agt"] == "agt-role" def test_vault_backend_missing_addr_raises(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, {"backend": "vault", "vault": {}}) with pytest.raises(ConfigError, match="addr"): load_config(cfg_path) def test_missing_config_raises(): with pytest.raises(ConfigError, match="not found"): load_config(Path("/nonexistent/path/warden.yaml")) def test_custom_state_dir(tmp_path): cfg_path = tmp_path / "warden.yaml" custom_state = tmp_path / "my-state" write_yaml(cfg_path, { "backend": "local", "ca_key": str(tmp_path / "ca"), "state_dir": str(custom_state), }) cfg = load_config(cfg_path) assert cfg.state_dir == custom_state def test_default_vault_token_env(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, { "backend": "vault", "vault": {"addr": "https://vault.example.com"}, }) cfg = load_config(cfg_path) assert cfg.vault.token_env == "VAULT_TOKEN" def test_policy_defaults_to_unknown_zone_profile(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, {"backend": "local", "ca_key": str(tmp_path / "ca")}) cfg = load_config(cfg_path) assert cfg.policy.flex_auth_url is None assert cfg.policy.failure_modes["unknown"] == "fail_open" assert cfg.policy.failure_modes["z3-critical"] == "fail_closed" def test_policy_block_parsed(tmp_path): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, { "backend": "local", "ca_key": str(tmp_path / "ca"), "policy": { "flex_auth_url": "http://flex-auth:8080", "zone_registry_path": str(tmp_path / "zones.json"), "failure_modes": {"z2-protected": "fail_closed"}, "tenant": "tenant:coulomb", "subject_env": "MY_SUBJECT", "system": "warden-test", }, }) cfg = load_config(cfg_path) assert cfg.policy.flex_auth_url == "http://flex-auth:8080" assert cfg.policy.zone_registry_path == tmp_path / "zones.json" assert cfg.policy.failure_modes["z2-protected"] == "fail_closed" assert cfg.policy.tenant == "tenant:coulomb" assert cfg.policy.subject_env == "MY_SUBJECT" assert cfg.policy.system == "warden-test" @pytest.mark.parametrize("retired", ["enabled", "fail_closed"]) def test_retired_global_policy_switches_are_rejected(tmp_path, retired): cfg_path = tmp_path / "warden.yaml" write_yaml(cfg_path, { "backend": "local", "ca_key": str(tmp_path / "ca"), "policy": {retired: True}, }) with pytest.raises(ConfigError, match=f"policy.{retired}"): load_config(cfg_path)