Skip to content

Commit 68d52b2

Browse files
wehosHongzhi Wenclaude
authored
fix(tests): 对齐 tests/unit 12 个 pre-existing 失败到当前代码 (#1500)
这批失败在干净 HEAD 上同样存在,与 startup-perf 工作无关,逐个判定均为 "代码有意演进、测试陈旧"或测试自身脆弱,非生产回归: - api_config_manager: grok 在 PR #1306 成为 realtime voice provider(含 wss core_url),更新 core 期望集合;删除 PR #1373 已撤销/从未落地的 modelVisionOverrides→supports_vision 孤儿测试 - stepfun_tts_voices / gemini_realtime_voice_routing: PR #1385 把 step/free 默认音色改为 qingchunshaonv/青春少女 + wenrounansheng/温柔男声,对齐断言与 collision fixture - game_llm_static_contracts: soccer prompt 新增 es/pt 本地化,es 不再回退 en - reflection_related_context: reranker 在 PR #1401 改名 aretrieve_per_query_topk, 更新 mock 方法名 - cloudsave_lifecycle_flow: set_steamworks 启动期被 init_shared_state + runtime init 各调一次;record_app_start 新增 process= 参数(PR #1486),更新断言 - galgame_router: N.E.K.O 祖先 logger 在全量跑时 propagate=False,caplog 漏捕, 改为把 caplog handler 直挂发射 logger(仅测试侧加固) 全量 tests/unit:2825 passed, 14 skipped。未触碰 startup/lazy-import 生产文件。 Co-authored-by: Hongzhi Wen <cartabio.coder1@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 22770d2 commit 68d52b2

7 files changed

Lines changed: 45 additions & 38 deletions

tests/unit/test_api_config_manager.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -203,25 +203,6 @@ def test_on_applies_custom_overrides(self, config_manager):
203203
assert cfg['CONVERSATION_MODEL'] == 'custom-model-123'
204204
assert cfg['CONVERSATION_MODEL_API_KEY'] == 'sk-custom-conv'
205205

206-
@pytest.mark.unit
207-
def test_model_vision_override_marks_custom_model_capability(self, config_manager):
208-
"""Explicit modelVisionOverrides should win before model-name sniffing."""
209-
_write_core_config(config_manager, {
210-
'coreApiKey': 'sk-core',
211-
'coreApi': 'qwen',
212-
'assistApi': 'qwen',
213-
'enableCustomApi': True,
214-
'conversationModelUrl': 'https://custom.example.com/v1',
215-
'conversationModelId': 'local-multimodal',
216-
'conversationModelApiKey': 'sk-custom-conv',
217-
'modelVisionOverrides': {'local-multimodal': True},
218-
})
219-
220-
cfg = config_manager.get_model_api_config('conversation')
221-
222-
assert cfg['model'] == 'local-multimodal'
223-
assert cfg['supports_vision'] is True
224-
225206
@pytest.mark.unit
226207
def test_on_applies_all_model_types(self, config_manager):
227208
"""enableCustomApi=true → all 8 model types can be overridden."""
@@ -374,7 +355,9 @@ def test_core_only_has_realtime_providers(self):
374355
from utils.api_config_loader import get_core_api_profiles
375356
core_profiles = get_core_api_profiles()
376357

377-
expected_core = {'free', 'qwen', 'qwen_intl', 'openai', 'step', 'gemini', 'glm'}
358+
# grok joined core as a realtime voice provider (Grok Voice, wss
359+
# endpoint) in PR #1306 — it has a core_url, so it belongs here.
360+
expected_core = {'free', 'qwen', 'qwen_intl', 'openai', 'step', 'gemini', 'glm', 'grok'}
378361
actual_core = set(core_profiles.keys())
379362

380363
assert actual_core == expected_core, (
@@ -399,9 +382,12 @@ def test_text_only_providers_not_in_core(self):
399382
from utils.api_config_loader import get_core_api_profiles
400383
core_profiles = get_core_api_profiles()
401384

385+
# grok has a realtime voice endpoint (Grok Voice, PR #1306) so it is
386+
# intentionally also a core provider — only truly text-only providers
387+
# are listed here.
402388
must_not_be_core = [
403389
'deepseek', 'doubao', 'minimax', 'minimax_intl',
404-
'kimi', 'grok', 'silicon',
390+
'kimi', 'silicon',
405391
]
406392
for provider in must_not_be_core:
407393
assert provider not in core_profiles, (

tests/unit/test_cloudsave_lifecycle_flow.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pathlib import Path
66
from tempfile import TemporaryDirectory
77
from types import SimpleNamespace
8-
from unittest.mock import AsyncMock, Mock, patch
8+
from unittest.mock import AsyncMock, Mock, call, patch
99

1010
from fastapi.testclient import TestClient
1111

@@ -384,13 +384,17 @@ async def start(self):
384384
mock_sync_reload.assert_awaited_once_with(fake_import_result)
385385
mock_set_root_mode.assert_called_once()
386386
mock_init_steam.assert_called_once_with()
387-
mock_set_steamworks.assert_called_once_with(None)
387+
# set_steamworks is wired twice on startup: init_shared_state seeds the
388+
# shared registry with the current (None) handle, then runtime init
389+
# publishes the freshly initialized handle. Under this mock
390+
# initialize_steamworks returns None, so both calls carry None.
391+
assert mock_set_steamworks.call_args_list == [call(None), call(None)]
388392
mock_default_steam_info.assert_called_once_with()
389393
bridge_start.assert_awaited_once_with()
390394
mock_set_main_bridge.assert_called_once()
391395
mock_mount_workshop.assert_awaited_once_with()
392396
fake_tracker.start_periodic_save.assert_called_once_with()
393-
fake_tracker.record_app_start.assert_called_once_with()
397+
fake_tracker.record_app_start.assert_called_once_with(process="main_server")
394398
assert main_server._preload_task is not None
395399

396400

tests/unit/test_galgame_router.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,19 @@ async def ainvoke(self, messages):
399399
monkeypatch.setattr(galgame_router, "get_config_manager", lambda: config_manager)
400400
monkeypatch.setattr(galgame_router, "create_chat_llm", lambda *a, **kw: GarbageLLM())
401401

402-
with caplog.at_level(logging.INFO, logger=galgame_router.logger.name):
402+
# galgame_router.logger is a get_module_logger child whose N.E.K.O ancestor
403+
# gets configured with propagate=False once any service initializes logging
404+
# (e.g. the Memory logger during a full-suite import). caplog installs its
405+
# handler on root, so the INFO record never reaches it. Attach caplog's
406+
# handler directly to the emitting logger and silence propagation during the
407+
# call so the record is captured exactly once regardless of global state.
408+
galgame_logger = galgame_router.logger
409+
prev_propagate = galgame_logger.propagate
410+
prev_level = galgame_logger.level
411+
galgame_logger.addHandler(caplog.handler)
412+
galgame_logger.propagate = False
413+
galgame_logger.setLevel(logging.INFO)
414+
try:
403415
response = await galgame_router.generate_galgame_options(
404416
FakeRequest(
405417
{
@@ -408,6 +420,10 @@ async def ainvoke(self, messages):
408420
}
409421
)
410422
)
423+
finally:
424+
galgame_logger.removeHandler(caplog.handler)
425+
galgame_logger.propagate = prev_propagate
426+
galgame_logger.setLevel(prev_level)
411427

412428
data = _decode_response(response)
413429
assert data["success"] is True

tests/unit/test_game_llm_static_contracts.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ def test_soccer_game_prompts_follow_user_language():
3535
assert "Output only the spoken line" in en_prompt
3636
assert en_prompt != zh_prompt
3737
assert ja_prompt != en_prompt
38-
assert es_prompt == en_prompt # es falls back to en until its own i18n is added
38+
assert es_prompt != en_prompt # es now ships its own Spanish localization
39+
assert es_prompt.startswith("Eres Lan")
3940

4041

4142
@pytest.mark.unit

tests/unit/test_gemini_realtime_voice_routing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ def test_step_native_preview_provider_respects_custom_voice_collision():
175175
colliding_mgr = _FakeCharactersRouterConfigManager(
176176
"free",
177177
"wss://lanlan.tech/realtime",
178-
stored_voice_ids={"linjiameimei"},
178+
stored_voice_ids={"qingchunshaonv"},
179179
)
180180

181181
assert characters_router._get_active_native_preview_provider(native_mgr, "中文女") == "free"
182-
assert characters_router._get_active_native_preview_provider(colliding_mgr, "linjiameimei") is None
182+
assert characters_router._get_active_native_preview_provider(colliding_mgr, "qingchunshaonv") is None
183183
assert characters_router._get_active_native_preview_provider(colliding_mgr, "中文女") is None
184184

185185

tests/unit/test_reflection_related_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ async def test_happy_path_renders_watermarked_block():
9191
{"id": "f1", "text": "absorbed fact text", "absorbed": True, "importance": 7},
9292
])
9393
mock_reranker = MagicMock()
94-
mock_reranker.aretrieve_candidates = AsyncMock(return_value=[
94+
mock_reranker.aretrieve_per_query_topk = AsyncMock(return_value=[
9595
{"id": "f1", "text": "absorbed fact text", "importance": 7},
9696
])
9797
with patch("memory.embeddings.get_embedding_service", return_value=_enabled_service()), \

tests/unit/test_stepfun_tts_voices.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424

2525

2626
def test_stepfun_and_free_catalogs_are_registered():
27-
assert STEPFUN_TTS_DEFAULT_VOICE == "linjiameimei"
27+
assert STEPFUN_TTS_DEFAULT_VOICE == "qingchunshaonv"
2828
assert FALLBACK_STEPFUN_TTS_DEFAULT_VOICE == "linjiameimei"
29-
assert STEPFUN_TTS_DEFAULT_MALE_VOICE == "cixingnansheng"
29+
assert STEPFUN_TTS_DEFAULT_MALE_VOICE == "wenrounansheng"
3030
assert is_native_voice(STEPFUN_TTS_DEFAULT_VOICE, provider_key="step") is True
3131
assert is_native_voice(STEPFUN_TTS_DEFAULT_VOICE, provider_key="free") is True
32-
assert is_native_voice("清纯少女", provider_key="step") is True
32+
assert is_native_voice("青春少女", provider_key="step") is True
3333
assert is_native_voice("中文男", provider_key="free") is True
3434

3535

@@ -82,27 +82,27 @@ def test_stepfun_ui_catalog_exposes_provider_label():
8282
assert STEPFUN_TTS_DEFAULT_VOICE in catalog
8383
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["provider"] == "step"
8484
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["provider_label"] == "StepFun"
85-
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["display_name"] == "邻家妹妹"
85+
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["display_name"] == "青春少女"
8686
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["gender"] == ""
87-
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["prefix"] == "邻家妹妹"
87+
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["prefix"] == "青春少女"
8888

8989

9090
def test_free_ui_catalog_uses_voice_label_without_provider_prefix():
9191
catalog = get_native_voice_catalog_for_ui("free")
9292
assert catalog is not None
9393
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["provider"] == "free"
9494
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["provider_label"] == "免费 API"
95-
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["display_name"] == "邻家妹妹"
95+
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["display_name"] == "青春少女"
9696
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["gender"] == ""
97-
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["prefix"] == "邻家妹妹"
98-
assert catalog[STEPFUN_TTS_DEFAULT_MALE_VOICE]["prefix"] == "磁性男声"
97+
assert catalog[STEPFUN_TTS_DEFAULT_VOICE]["prefix"] == "青春少女"
98+
assert catalog[STEPFUN_TTS_DEFAULT_MALE_VOICE]["prefix"] == "温柔男声"
9999

100100

101101
def test_stepfun_catalog_is_loaded_from_api_providers_config():
102102
step_cfg = get_native_tts_voice_provider_config("step")
103103
free_cfg = get_native_tts_voice_provider_config("free")
104104

105-
assert step_cfg["voices"][STEPFUN_TTS_DEFAULT_VOICE] == "邻家妹妹"
105+
assert step_cfg["voices"][STEPFUN_TTS_DEFAULT_VOICE] == "青春少女"
106106
assert step_cfg["default_voice"] == STEPFUN_TTS_DEFAULT_VOICE
107107
assert step_cfg["default_male_voice"] == STEPFUN_TTS_DEFAULT_MALE_VOICE
108108
assert free_cfg["voices"] == step_cfg["voices"]

0 commit comments

Comments
 (0)