This commit is contained in:
@@ -113,7 +113,7 @@ def _stub_ollama(monkeypatch, *, success: bool = True,
|
||||
fake_resp.content = content if success else ""
|
||||
fake_resp.model = "qwen3:14b"
|
||||
fake_resp.error = None if success else error
|
||||
fake_resp.host = "http://34.143.170.20:11434"
|
||||
fake_resp.host = "http://34.87.90.216:11434"
|
||||
fake_resp.input_tokens = 30 if success else 0
|
||||
fake_resp.output_tokens = 12 if success else 0
|
||||
|
||||
|
||||
@@ -11029,7 +11029,7 @@ def test_candidate_queue_review_ai_summary_output_receipt_validates_manual_outpu
|
||||
"evidence_refs": [expected_key, "review_scope"],
|
||||
"model_route": {
|
||||
"provider": "ollama",
|
||||
"host": "34.143.170.20:11434",
|
||||
"host": "34.87.90.216:11434",
|
||||
"model": "qwen2.5-coder:7b",
|
||||
},
|
||||
},
|
||||
@@ -11214,7 +11214,7 @@ def test_candidate_queue_review_ai_summary_persistence_preflight_prepares_metada
|
||||
"evidence_refs": [expected_key, "review_scope"],
|
||||
"model_route": {
|
||||
"provider": "ollama",
|
||||
"host": "34.143.170.20:11434",
|
||||
"host": "34.87.90.216:11434",
|
||||
"model": "qwen2.5-coder:7b",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -108,7 +108,7 @@ def _enable_qwen3_path(monkeypatch, module):
|
||||
monkeypatch.setattr(module, "build_mcp_context", lambda: "MCP-MOCK")
|
||||
# 確保即使未被呼叫,import 路徑可解析
|
||||
import services.ollama_service as ollama_module
|
||||
monkeypatch.setattr(ollama_module, "resolve_ollama_host", lambda: "http://34.143.170.20:11434")
|
||||
monkeypatch.setattr(ollama_module, "resolve_ollama_host", lambda: "http://34.87.90.216:11434")
|
||||
monkeypatch.setattr(ollama_module, "mark_unhealthy", lambda *a, **kw: None)
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ def test_qwen3_retries_secondary_when_primary_chat_fails(monkeypatch):
|
||||
|
||||
_enable_qwen3_path(monkeypatch, module)
|
||||
hosts = iter([
|
||||
"http://34.143.170.20:11434",
|
||||
"http://34.87.90.216:11434",
|
||||
"http://34.21.145.224:11434",
|
||||
])
|
||||
marked = []
|
||||
@@ -221,7 +221,7 @@ def test_qwen3_retries_secondary_when_primary_chat_fails(monkeypatch):
|
||||
calls = _patch_execution_methods(monkeypatch, dispatcher)
|
||||
result = dispatcher.dispatch([FakeThreat()], hermes_stats={"duration_sec": 1.0})
|
||||
|
||||
assert marked == ["http://34.143.170.20:11434"]
|
||||
assert marked == ["http://34.87.90.216:11434"]
|
||||
assert result["nim_stats"].get("host") == "http://34.21.145.224:11434"
|
||||
assert result["dispatched"] == 1
|
||||
assert calls[0]["kind"] == "price_alert"
|
||||
|
||||
@@ -21,7 +21,7 @@ class TestGetHostLabel:
|
||||
|
||||
def test_gcp_primary_direct(self):
|
||||
"""docker-compose 環境直連 GCP-A"""
|
||||
assert get_host_label('http://34.143.170.20:11434') == 'GCP-SSD'
|
||||
assert get_host_label('http://34.87.90.216:11434') == 'GCP-SSD'
|
||||
|
||||
def test_gcp_secondary_direct(self):
|
||||
"""docker-compose 環境直連 GCP-B"""
|
||||
@@ -60,7 +60,7 @@ class TestGetProviderTag:
|
||||
|
||||
def test_gcp_primary_direct_or_nginx(self):
|
||||
"""直連 + Nginx 11435 都歸 gcp_ollama"""
|
||||
assert get_provider_tag('http://34.143.170.20:11434') == 'gcp_ollama'
|
||||
assert get_provider_tag('http://34.87.90.216:11434') == 'gcp_ollama'
|
||||
assert get_provider_tag('http://192.168.0.110:11435') == 'gcp_ollama'
|
||||
|
||||
def test_gcp_secondary_direct_or_nginx(self):
|
||||
@@ -77,7 +77,7 @@ class TestGetProviderTag:
|
||||
|
||||
@pytest.mark.parametrize('host,expected', [
|
||||
# 對齊 ai_calls 表 CHECK constraint 白名單(migration 043 補 ollama_other)
|
||||
('http://34.143.170.20:11434', 'gcp_ollama'),
|
||||
('http://34.87.90.216:11434', 'gcp_ollama'),
|
||||
('http://192.168.0.110:11435', 'gcp_ollama'),
|
||||
('http://34.21.145.224:11434', 'ollama_secondary'),
|
||||
('http://192.168.0.110:11436', 'ollama_secondary'),
|
||||
|
||||
@@ -138,6 +138,49 @@ def test_resolve_skips_recent_unhealthy_direct_primary_and_uses_proxy(monkeypatc
|
||||
assert seen_urls == [f"{oss.OLLAMA_HOST_PRIMARY_PROXY}/api/version"]
|
||||
|
||||
|
||||
def test_recent_direct_host_unhealthy_matches_actual_host_url(monkeypatch):
|
||||
"""舊 GCP-A 的 unhealthy 紀錄不能誤擋新 GCP-A。"""
|
||||
from datetime import datetime
|
||||
from services import ollama_service as oss
|
||||
|
||||
seen_params = []
|
||||
|
||||
class FakeResult:
|
||||
def __init__(self, row):
|
||||
self.row = row
|
||||
|
||||
def fetchone(self):
|
||||
return self.row
|
||||
|
||||
class FakeSession:
|
||||
def execute(self, _statement, params):
|
||||
seen_params.append(dict(params))
|
||||
if params.get("host_url") == oss.OLLAMA_HOST_PRIMARY:
|
||||
return FakeResult((False, "ConnectTimeout", datetime.now()))
|
||||
return FakeResult(None)
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
monkeypatch.setenv("OLLAMA_RESOLVE_HOST_HEALTH_SKIP_ENABLED", "true")
|
||||
monkeypatch.setattr("database.manager.get_session", lambda: FakeSession())
|
||||
|
||||
assert oss._recent_direct_host_unhealthy(oss.OLLAMA_HOST_PRIMARY) is True
|
||||
assert seen_params == [
|
||||
{"host_label": "Primary (GCP)", "host_url": oss.OLLAMA_HOST_PRIMARY}
|
||||
]
|
||||
|
||||
|
||||
def test_retired_gcp_a_host_is_not_approved(monkeypatch):
|
||||
"""已退役 GCP-A 不可再被 env 白名單接受。"""
|
||||
from services import ollama_service as oss
|
||||
|
||||
monkeypatch.setenv("OLLAMA_HOST_PRIMARY", "http://34.143.170.20:11434")
|
||||
|
||||
assert oss.is_approved_ollama_host("http://34.143.170.20:11434") is False
|
||||
assert oss.approved_ollama_env("OLLAMA_HOST_PRIMARY", oss.OLLAMA_HOST_PRIMARY) == oss.OLLAMA_HOST_PRIMARY
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# B4 — mark_unhealthy 行為
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
@@ -248,7 +291,7 @@ def test_get_ollama_host_rejects_unapproved_env(monkeypatch):
|
||||
import config
|
||||
importlib.reload(config)
|
||||
host = config.get_ollama_host()
|
||||
assert host == 'http://34.143.170.20:11434'
|
||||
assert host == 'http://34.87.90.216:11434'
|
||||
|
||||
|
||||
def test_get_ollama_host_falls_back_to_resolve_without_env(monkeypatch):
|
||||
@@ -259,7 +302,7 @@ def test_get_ollama_host_falls_back_to_resolve_without_env(monkeypatch):
|
||||
import config
|
||||
importlib.reload(config)
|
||||
host = config.get_ollama_host()
|
||||
# primary URL 由 env OLLAMA_HOST_PRIMARY 控制(預設 GCP-SSD 34.143.170.20)
|
||||
# primary URL 由 env OLLAMA_HOST_PRIMARY 控制(預設 GCP-SSD 34.87.90.216)
|
||||
assert host.startswith('http://')
|
||||
|
||||
|
||||
@@ -267,15 +310,15 @@ def test_config_ollama_compat_constants_do_not_probe_network(monkeypatch):
|
||||
monkeypatch.setenv('OLLAMA_HOST', 'http://192.168.0.188:11434')
|
||||
monkeypatch.setenv('HERMES_URL', 'http://192.168.0.188:11434')
|
||||
monkeypatch.setenv('EMBEDDING_HOST', 'http://192.168.0.188:11434')
|
||||
monkeypatch.setenv('OLLAMA_HOST_PRIMARY', 'http://34.143.170.20:11434')
|
||||
monkeypatch.setenv('OLLAMA_HOST_PRIMARY', 'http://34.87.90.216:11434')
|
||||
with patch('services.ollama_service.requests.get') as mock_get:
|
||||
import config
|
||||
importlib.reload(config)
|
||||
|
||||
mock_get.assert_not_called()
|
||||
assert config.OLLAMA_HOST == 'http://34.143.170.20:11434'
|
||||
assert config.HERMES_URL == 'http://34.143.170.20:11434'
|
||||
assert config.EMBEDDING_HOST == 'http://34.143.170.20:11434'
|
||||
assert config.OLLAMA_HOST == 'http://34.87.90.216:11434'
|
||||
assert config.HERMES_URL == 'http://34.87.90.216:11434'
|
||||
assert config.EMBEDDING_HOST == 'http://34.87.90.216:11434'
|
||||
|
||||
|
||||
def test_get_embedding_host_prefers_env(monkeypatch):
|
||||
@@ -286,10 +329,10 @@ def test_get_embedding_host_prefers_env(monkeypatch):
|
||||
|
||||
|
||||
def test_get_hermes_url_prefers_env(monkeypatch):
|
||||
monkeypatch.setenv('HERMES_URL', 'http://34.143.170.20:11434')
|
||||
monkeypatch.setenv('HERMES_URL', 'http://34.87.90.216:11434')
|
||||
import config
|
||||
importlib.reload(config)
|
||||
assert config.get_hermes_url() == 'http://34.143.170.20:11434'
|
||||
assert config.get_hermes_url() == 'http://34.87.90.216:11434'
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -490,7 +490,7 @@ def test_embedding_health_label_maps_direct_and_proxy_gcp_hosts():
|
||||
"""host_health skip 要對齊 scheduler 寫入的 host_label。"""
|
||||
from services import ollama_service as oss
|
||||
|
||||
assert oss._host_label_for_embedding_health("http://34.143.170.20:11434") == "Primary (GCP)"
|
||||
assert oss._host_label_for_embedding_health("http://34.87.90.216:11434") == "Primary (GCP)"
|
||||
assert oss._host_label_for_embedding_health("http://192.168.0.110:11435") == "Primary (GCP)"
|
||||
assert oss._host_label_for_embedding_health("http://34.21.145.224:11434") == "Secondary (GCP)"
|
||||
assert oss._host_label_for_embedding_health("http://192.168.0.110:11436") == "Secondary (GCP)"
|
||||
@@ -502,12 +502,15 @@ def test_recent_embedding_host_unhealthy_reads_fresh_host_health_probe(monkeypat
|
||||
from datetime import datetime
|
||||
from services import ollama_service as oss
|
||||
|
||||
seen_params = []
|
||||
|
||||
class FakeResult:
|
||||
def fetchone(self):
|
||||
return (False, "EmbedProbe ReadTimeout", datetime.now())
|
||||
|
||||
class FakeSession:
|
||||
def execute(self, *args, **kwargs):
|
||||
def execute(self, _statement, params):
|
||||
seen_params.append(dict(params))
|
||||
return FakeResult()
|
||||
|
||||
def close(self):
|
||||
@@ -518,6 +521,9 @@ def test_recent_embedding_host_unhealthy_reads_fresh_host_health_probe(monkeypat
|
||||
monkeypatch.setattr("database.manager.get_session", lambda: FakeSession())
|
||||
|
||||
assert oss._recent_embedding_host_unhealthy(oss.OLLAMA_HOST_SECONDARY) is True
|
||||
assert seen_params == [
|
||||
{"host_label": "Secondary (GCP)", "host_url": oss.OLLAMA_HOST_SECONDARY}
|
||||
]
|
||||
|
||||
|
||||
def test_recent_embedding_host_unhealthy_fails_open_when_db_is_unavailable(monkeypatch):
|
||||
|
||||
@@ -75,7 +75,7 @@ def _stub_ollama_generate(
|
||||
success: bool = True,
|
||||
content: str = '本週 momo 業績成長 12%,建議加碼家電促銷。',
|
||||
error: str = 'ConnectionError: connection refused',
|
||||
host: str = 'http://34.143.170.20:11434',
|
||||
host: str = 'http://34.87.90.216:11434',
|
||||
input_tokens: int = 150,
|
||||
output_tokens: int = 60,
|
||||
):
|
||||
@@ -450,7 +450,7 @@ class TestCallQwen3Telemetry:
|
||||
assert rec['fallback_to'] is None
|
||||
assert rec['meta'].get('flag') == 'OPENCLAW_QA_OLLAMA_FIRST'
|
||||
assert rec['meta'].get('route') == 'ollama_first'
|
||||
assert rec['meta'].get('host') == 'http://34.143.170.20:11434'
|
||||
assert rec['meta'].get('host') == 'http://34.87.90.216:11434'
|
||||
assert rec['meta'].get('host_label') == 'GCP-SSD'
|
||||
assert rec['request_id'] == "qa-test123"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user