fix(backup): correct marker filenames in _validate_backup_zip
The backup validation checked for 'hermes_state.db' and 'memory_store.db' as telltale markers of a valid Hermes backup zip. Neither name exists in a real Hermes installation — the actual database file is 'state.db' (hermes_state.py: DEFAULT_DB_PATH = get_hermes_home() / 'state.db'). A fresh Hermes installation produces: ~/.hermes/state.db (actual name) ~/.hermes/config.yaml ~/.hermes/.env Because the marker set never matched 'state.db', a backup zip containing only 'state.db' plus 'config.yaml' would fail validation with: 'zip does not appear to be a Hermes backup' and the import would exit with sys.exit(1), silently rejecting a valid backup. Fix: replace the wrong marker names with the correct filename. Adds TestValidateBackupZip with three cases: - state.db is accepted as a valid marker - old wrong names (hermes_state.db, memory_store.db) alone are rejected - config.yaml continues to pass (existing behaviour preserved)
This commit is contained in:
@@ -201,7 +201,7 @@ def _validate_backup_zip(zf: zipfile.ZipFile) -> tuple[bool, str]:
|
||||
return False, "zip archive is empty"
|
||||
|
||||
# Look for telltale files that a hermes home would have
|
||||
markers = {"config.yaml", ".env", "hermes_state.db", "memory_store.db"}
|
||||
markers = {"config.yaml", ".env", "state.db"}
|
||||
found = set()
|
||||
for n in names:
|
||||
# Could be at the root or one level deep (if someone zipped the directory)
|
||||
|
||||
@@ -232,6 +232,44 @@ class TestBackup:
|
||||
assert len(zips) == 1
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _validate_backup_zip tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestValidateBackupZip:
|
||||
def _make_zip(self, zip_path: Path, filenames: list[str]) -> None:
|
||||
with zipfile.ZipFile(zip_path, "w") as zf:
|
||||
for name in filenames:
|
||||
zf.writestr(name, "dummy")
|
||||
|
||||
def test_state_db_passes(self, tmp_path):
|
||||
"""A zip containing state.db is accepted as a valid Hermes backup."""
|
||||
from hermes_cli.backup import _validate_backup_zip
|
||||
zip_path = tmp_path / "backup.zip"
|
||||
self._make_zip(zip_path, ["state.db", "sessions/abc.json"])
|
||||
with zipfile.ZipFile(zip_path, "r") as zf:
|
||||
ok, reason = _validate_backup_zip(zf)
|
||||
assert ok, reason
|
||||
|
||||
def test_old_wrong_db_name_fails(self, tmp_path):
|
||||
"""A zip with only hermes_state.db (old wrong name) is rejected."""
|
||||
from hermes_cli.backup import _validate_backup_zip
|
||||
zip_path = tmp_path / "old.zip"
|
||||
self._make_zip(zip_path, ["hermes_state.db", "memory_store.db"])
|
||||
with zipfile.ZipFile(zip_path, "r") as zf:
|
||||
ok, reason = _validate_backup_zip(zf)
|
||||
assert not ok
|
||||
|
||||
def test_config_yaml_passes(self, tmp_path):
|
||||
"""A zip containing config.yaml is accepted (existing behaviour preserved)."""
|
||||
from hermes_cli.backup import _validate_backup_zip
|
||||
zip_path = tmp_path / "backup.zip"
|
||||
self._make_zip(zip_path, ["config.yaml", "skills/x/SKILL.md"])
|
||||
with zipfile.ZipFile(zip_path, "r") as zf:
|
||||
ok, reason = _validate_backup_zip(zf)
|
||||
assert ok, reason
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Import tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user