Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
88 lines
2.5 KiB
Python
88 lines
2.5 KiB
Python
from __future__ import annotations
|
|
from typing import Any, cast
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from teamlandkarte_mcp.azure.openai_client import AzureAPIError, AzureOpenAIClient
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_chat_completion_success():
|
|
client = AzureOpenAIClient(
|
|
endpoint="https://example.openai.azure.com",
|
|
api_version="2024-02-15-preview",
|
|
chat_deployment="gpt-4o",
|
|
llm_api_key="test-key",
|
|
)
|
|
|
|
# Mock the internal chat client
|
|
fake_choice = MagicMock()
|
|
fake_choice.message.content = '{"result": "ok"}'
|
|
fake_resp = MagicMock()
|
|
fake_resp.choices = [fake_choice]
|
|
|
|
fake_chat = MagicMock()
|
|
fake_chat.chat.completions.create = AsyncMock(return_value=fake_resp)
|
|
client._chat = cast(Any, fake_chat)
|
|
|
|
result = await client.chat_completion(system="sys", user="usr")
|
|
assert result == '{"result": "ok"}'
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_chat_completion_retries_on_timeout():
|
|
client = AzureOpenAIClient(
|
|
endpoint="https://example.openai.azure.com",
|
|
api_version="2024-02-15-preview",
|
|
chat_deployment="gpt-4o",
|
|
llm_api_key="test-key",
|
|
max_retries=3,
|
|
timeout_s=0.01,
|
|
)
|
|
|
|
# First call times out, second succeeds
|
|
fake_choice = MagicMock()
|
|
fake_choice.message.content = '{"ok": true}'
|
|
fake_resp = MagicMock()
|
|
fake_resp.choices = [fake_choice]
|
|
|
|
call_count = 0
|
|
|
|
async def _fake_create(**kwargs):
|
|
nonlocal call_count
|
|
call_count += 1
|
|
if call_count == 1:
|
|
raise RuntimeError("transient error")
|
|
return fake_resp
|
|
|
|
fake_chat = MagicMock()
|
|
fake_chat.chat.completions.create = _fake_create
|
|
client._chat = cast(Any, fake_chat)
|
|
|
|
result = await client.chat_completion(system="sys", user="usr")
|
|
assert result == '{"ok": true}'
|
|
assert call_count == 2
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_chat_completion_raises_after_all_retries():
|
|
client = AzureOpenAIClient(
|
|
endpoint="https://example.openai.azure.com",
|
|
api_version="2024-02-15-preview",
|
|
chat_deployment="gpt-4o",
|
|
llm_api_key="test-key",
|
|
max_retries=2,
|
|
timeout_s=0.01,
|
|
)
|
|
|
|
async def _always_fail(**kwargs):
|
|
raise RuntimeError("persistent error")
|
|
|
|
fake_chat = MagicMock()
|
|
fake_chat.chat.completions.create = _always_fail
|
|
client._chat = cast(Any, fake_chat)
|
|
|
|
with pytest.raises(AzureAPIError, match="persistent error"):
|
|
await client.chat_completion(system="sys", user="usr")
|