Phase A1: bootstrap Python ci_orchestrator package
- pyproject.toml (hatchling) with ruff/mypy/pytest dev deps - src/ci_orchestrator/: config, credentials, backends (Protocol + WorkstationVmrunBackend), transport (WinRM via pypsrp, SSH via paramiko) - CLI entry point with PoC 'wait-ready' subcommand (Windows + Linux guests) - tests/python/: 35 unit tests, 83% coverage, all backends/transport mocked - gitea/workflows/lint.yml: new 'python' job (ruff + mypy --strict + pytest --cov-fail-under=70) - config.example.toml + README setup section + .gitignore Python entries Neutral VmBackend Protocol prepared for Phase C ESXi extension. See plans/implementation-plan-A-B.md step A1.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
"""Tests for KeyringCredentialStore (mocked keyring backend)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import types
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from ci_orchestrator.credentials import KeyringCredentialStore
|
||||
|
||||
|
||||
def _install_fake_keyring(monkeypatch: pytest.MonkeyPatch, **behaviour: Any) -> None:
|
||||
fake = types.ModuleType("keyring")
|
||||
|
||||
def get_credential(target: str, _username: str | None) -> Any:
|
||||
return behaviour.get("credential_map", {}).get(target)
|
||||
|
||||
def get_password(service: str, target: str) -> str | None:
|
||||
return behaviour.get("password_map", {}).get((service, target))
|
||||
|
||||
fake.get_credential = get_credential # type: ignore[attr-defined]
|
||||
fake.get_password = get_password # type: ignore[attr-defined]
|
||||
monkeypatch.setitem(sys.modules, "keyring", fake)
|
||||
|
||||
|
||||
class _FakeCred:
|
||||
def __init__(self, username: str, password: str) -> None:
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
|
||||
def test_get_returns_credential(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
_install_fake_keyring(
|
||||
monkeypatch,
|
||||
credential_map={"BuildVMGuest": _FakeCred("Administrator", "s3cret")},
|
||||
)
|
||||
cred = KeyringCredentialStore().get("BuildVMGuest")
|
||||
assert cred.username == "Administrator"
|
||||
assert cred.password == "s3cret"
|
||||
|
||||
|
||||
def test_get_falls_back_to_password(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
_install_fake_keyring(
|
||||
monkeypatch,
|
||||
credential_map={},
|
||||
password_map={("ci", "GiteaPAT"): "tokentoken"},
|
||||
)
|
||||
cred = KeyringCredentialStore().get("GiteaPAT")
|
||||
assert cred.username == "GiteaPAT"
|
||||
assert cred.password == "tokentoken"
|
||||
|
||||
|
||||
def test_get_raises_when_missing(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
_install_fake_keyring(monkeypatch, credential_map={}, password_map={})
|
||||
with pytest.raises(KeyError):
|
||||
KeyringCredentialStore().get("Unknown")
|
||||
Reference in New Issue
Block a user