test: add unit tests for credential pool env fallback

This commit is contained in:
阿泥豆 2026-04-26 14:54:48 +08:00 committed by Teknium
parent 8443998dc3
commit 27f4dba5ce

View file

@ -0,0 +1,110 @@
"""Tests for credential_pool .env fallback and auth credential pool lookup."""
import os
import pytest
from unittest.mock import patch, MagicMock
def _make_pconfig(env_vars=None):
"""Create a minimal ProviderConfig for testing."""
from hermes_cli.auth import ProviderConfig
return ProviderConfig(
id="openai",
name="OpenAI",
auth_type="api_key",
api_key_env_vars=tuple(env_vars or ["OPENAI_API_KEY"]),
)
class TestCredentialPoolEnvFallback:
"""Verify _seed_from_env resolves keys from both os.environ and .env file."""
def test_os_environ_still_works(self):
"""Existing os.environ resolution must not break.
_seed_from_env only collects env var names, does not return found=True
for existing keys that is _resolve's job. Just verify no crash."""
from agent.credential_pool import _seed_from_env
# Should not raise
found, entries = _seed_from_env("openai", [])
def test_get_env_value_import_does_not_crash(self):
"""Importing get_env_value from hermes_cli.config should not raise."""
try:
from hermes_cli.config import get_env_value
assert callable(get_env_value)
except ImportError:
pytest.skip("hermes_cli.config not available in test environment")
class TestAuthCredentialPoolFallback:
"""Verify auth.py falls back to credential pool when env vars are empty."""
def _clear_api_keys(self):
"""Temporarily clear API key env vars, return backup dict."""
backup = {}
for key in ["OPENAI_API_KEY", "ANTHROPIC_API_KEY", "OPENROUTER_API_KEY",
"ZAI_API_KEY", "DEEPSEEK_API_KEY"]:
if key in os.environ:
backup[key] = os.environ.pop(key)
return backup
def test_credential_pool_fallback_structure(self):
"""When no env var is set, auth should try credential pool."""
from hermes_cli.auth import _resolve_api_key_provider_secret
mock_entry = MagicMock()
mock_entry.access_token = "test-pool-key-12345"
mock_entry.runtime_api_key = ""
mock_pool = MagicMock()
mock_pool.has_credentials.return_value = True
mock_pool.peek.return_value = mock_entry
backup = self._clear_api_keys()
try:
with patch("agent.credential_pool.load_pool", return_value=mock_pool):
key, source = _resolve_api_key_provider_secret(
provider_id="openai",
pconfig=_make_pconfig(),
)
assert "test-pool-key-12345" in key
assert "credential_pool" in source
finally:
os.environ.update(backup)
def test_credential_pool_empty_returns_empty(self):
"""When pool is empty, return empty string."""
from hermes_cli.auth import _resolve_api_key_provider_secret
mock_pool = MagicMock()
mock_pool.has_credentials.return_value = False
backup = self._clear_api_keys()
try:
with patch("agent.credential_pool.load_pool", return_value=mock_pool):
key, source = _resolve_api_key_provider_secret(
provider_id="openai",
pconfig=_make_pconfig(),
)
assert key == ""
finally:
os.environ.update(backup)
def test_env_var_takes_priority_over_pool(self):
"""Env vars should be checked before credential pool."""
from hermes_cli.auth import _resolve_api_key_provider_secret
mock_pool = MagicMock()
mock_pool.has_credentials.return_value = True
with patch.dict(os.environ, {"OPENAI_API_KEY": "sk-env-key-first-abc123"}):
with patch("agent.credential_pool.load_pool", return_value=mock_pool):
key, source = _resolve_api_key_provider_secret(
provider_id="openai",
pconfig=_make_pconfig(),
)
assert key == "sk-env-key-first-abc123"
# Source is the env var name itself (e.g. "OPENAI_API_KEY")
assert "OPENAI_API_KEY" in source
# Pool peek should NOT have been called — env var found first
mock_pool.peek.assert_not_called()