fix: address Codex review of telemetry fix (mkdir degrade, close, degrade tests)
This commit is contained in:
@@ -125,11 +125,43 @@ async def test_duplicate_call_id_does_not_raise(recorder, db_path):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_db_error_does_not_propagate(tmp_path):
|
||||
"""SQLite 写入失败时 record_llm_call 应静默降级,不抛异常。"""
|
||||
bad_recorder = SQLiteTelemetryRecorder(db_path=tmp_path / "nonexistent_dir" / "bad.db")
|
||||
kwargs = _make_call_kwargs()
|
||||
await bad_recorder.record_llm_call(**kwargs)
|
||||
async def test_init_db_error_does_not_propagate(db_path, monkeypatch):
|
||||
"""构造期 connect 失败应降级(self._conn=None),不冒泡拖垮初始化。"""
|
||||
|
||||
def _boom_connect(*args, **kwargs):
|
||||
raise sqlite3.OperationalError("unable to open database file")
|
||||
|
||||
monkeypatch.setattr(sqlite3, "connect", _boom_connect)
|
||||
recorder = SQLiteTelemetryRecorder(db_path=db_path) # 不抛
|
||||
assert recorder._conn is None
|
||||
await recorder.record_llm_call(**_make_call_kwargs()) # 写也降级不抛
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_init_mkdir_error_does_not_propagate(db_path, monkeypatch):
|
||||
"""构造期 mkdir 失败(PermissionError/OSError)也应降级,不冒泡。"""
|
||||
|
||||
def _boom_mkdir(*args, **kwargs):
|
||||
raise PermissionError("cannot create dir")
|
||||
|
||||
monkeypatch.setattr("adapters.telemetry.Path.mkdir", _boom_mkdir)
|
||||
recorder = SQLiteTelemetryRecorder(db_path=db_path) # 不抛
|
||||
assert recorder._conn is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_db_error_does_not_propagate(recorder):
|
||||
"""写入期 execute 失败应静默降级,不抛异常(遥测失败绝不拖垮 LLM 调用)。"""
|
||||
|
||||
class _BoomConn:
|
||||
def execute(self, *args, **kwargs):
|
||||
raise sqlite3.OperationalError("disk I/O error")
|
||||
|
||||
def commit(self):
|
||||
pass
|
||||
|
||||
recorder._conn = _BoomConn() # 连接存在但写抛错,验证 _write 的 except 降级
|
||||
await recorder.record_llm_call(**_make_call_kwargs()) # 降级不抛
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -173,17 +205,20 @@ def test_uses_single_persistent_connection(db_path, monkeypatch):
|
||||
每次写新建连接是并发锁竞争根源(多连接争 SQLite 写锁,撑爆 busy_timeout);
|
||||
单连接 + 进程内 Lock 串行化把并发控制拉到进程内,消除 SQLite 层锁竞争。
|
||||
"""
|
||||
connect_calls = {"n": 0}
|
||||
connect_calls = {"n": 0, "kwargs": None}
|
||||
real_connect = sqlite3.connect
|
||||
|
||||
def _counting_connect(*args, **kwargs):
|
||||
connect_calls["n"] += 1
|
||||
connect_calls["kwargs"] = kwargs
|
||||
return real_connect(*args, **kwargs)
|
||||
|
||||
monkeypatch.setattr(sqlite3, "connect", _counting_connect)
|
||||
|
||||
recorder = SQLiteTelemetryRecorder(db_path=db_path)
|
||||
after_init = connect_calls["n"]
|
||||
# 跨线程共享连接必须 check_same_thread=False(串行性由 self._lock 保证)
|
||||
assert connect_calls["kwargs"].get("check_same_thread") is False
|
||||
for _ in range(10):
|
||||
recorder._write(**_make_call_kwargs())
|
||||
after_writes = connect_calls["n"]
|
||||
|
||||
Reference in New Issue
Block a user