Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
"""Gateway SessionStore must not FTS-repair a replaced state.db (#89332)."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import pytest
|
||||
|
||||
from gateway.config import GatewayConfig
|
||||
from gateway.session import SessionStore
|
||||
from hermes_state import SessionDB
|
||||
|
||||
|
||||
def _assert_diverted(tmp_path, sid, needle):
|
||||
pending = list((tmp_path / "pending_messages").glob("pending-*.json"))
|
||||
assert pending, "expected pending_messages/pending-*.json spool"
|
||||
spooled = False
|
||||
for path in pending:
|
||||
payload = json.loads(path.read_text(encoding="utf-8"))
|
||||
message = (payload.get("data") or {}).get("message") or {}
|
||||
if needle in str(message.get("content", "")):
|
||||
spooled = True
|
||||
break
|
||||
assert spooled, f"{needle!r} missing from pending spool"
|
||||
jsonl = tmp_path / "sessions" / f"{sid}.jsonl"
|
||||
assert jsonl.is_file()
|
||||
assert needle in jsonl.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_replaced_state_db_diverts_pending_without_fts_rebuild(tmp_path, monkeypatch):
|
||||
import hermes_state
|
||||
|
||||
live = tmp_path / "state.db"
|
||||
other = tmp_path / "other.db"
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
||||
monkeypatch.setattr(hermes_state, "DEFAULT_DB_PATH", live)
|
||||
|
||||
store = SessionStore(sessions_dir=tmp_path, config=GatewayConfig())
|
||||
sid = "gw-replaced"
|
||||
store._db.create_session(session_id=sid, source="cli")
|
||||
store.append_to_transcript(
|
||||
sid, {"role": "user", "content": "before", "timestamp": 1.0}
|
||||
)
|
||||
if store._db._db_file_identity is None:
|
||||
store.close_all_db_handles()
|
||||
pytest.skip("filesystem does not expose st_dev/st_ino")
|
||||
|
||||
alt = SessionDB(db_path=other)
|
||||
alt.create_session("other", "cli")
|
||||
alt.close()
|
||||
os.replace(other, live)
|
||||
|
||||
store.append_to_transcript(
|
||||
sid, {"role": "user", "content": "after-replace", "timestamp": 2.0}
|
||||
)
|
||||
|
||||
assert store._db._db_replaced is True
|
||||
# No FTS surgery ran on either layer: state-level fail-open never
|
||||
# detached, and the gateway one-shot rebuild was not consumed.
|
||||
assert store._db._fts_enabled is True
|
||||
assert store._db._fts_stale is False
|
||||
assert store._fts_rebuild_attempted is False
|
||||
_assert_diverted(tmp_path, sid, "after-replace")
|
||||
store.close_all_db_handles()
|
||||
|
||||
|
||||
def test_copyfile_replaced_state_db_diverts_pending_without_fts_rebuild(
|
||||
tmp_path, monkeypatch
|
||||
):
|
||||
import hermes_state
|
||||
|
||||
live = tmp_path / "state.db"
|
||||
other = tmp_path / "other.db"
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
||||
monkeypatch.setattr(hermes_state, "DEFAULT_DB_PATH", live)
|
||||
|
||||
store = SessionStore(sessions_dir=tmp_path, config=GatewayConfig())
|
||||
sid = "gw-cp-replaced"
|
||||
store._db.create_session(session_id=sid, source="cli")
|
||||
store.append_to_transcript(
|
||||
sid, {"role": "user", "content": "before-cp", "timestamp": 1.0}
|
||||
)
|
||||
if not store._db._db_file_application_id:
|
||||
store.close_all_db_handles()
|
||||
pytest.skip("generation stamp not recorded")
|
||||
|
||||
alt = SessionDB(db_path=other)
|
||||
alt.create_session("other", "cli")
|
||||
alt.close()
|
||||
shutil.copyfile(other, live)
|
||||
|
||||
store.append_to_transcript(
|
||||
sid, {"role": "user", "content": "after-cp", "timestamp": 2.0}
|
||||
)
|
||||
|
||||
assert store._db._db_replaced is True
|
||||
# No FTS surgery ran on either layer: state-level fail-open never
|
||||
# detached, and the gateway one-shot rebuild was not consumed.
|
||||
assert store._db._fts_enabled is True
|
||||
assert store._db._fts_stale is False
|
||||
assert store._fts_rebuild_attempted is False
|
||||
_assert_diverted(tmp_path, sid, "after-cp")
|
||||
store.close_all_db_handles()
|
||||
Reference in New Issue
Block a user