Session-gated MinIO save sync with AppImage GUI, CLI edit/session flow, and Gitea release helper. Co-authored-by: Cursor <[email protected]>
57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from syncgames.hashutil import tree_hash
|
|
from syncgames.store import FilesystemStore, empty_meta
|
|
|
|
|
|
def test_tree_hash_stable():
|
|
a = {"b.bin": "sha256:aa", "a.bin": "sha256:bb"}
|
|
b = {"a.bin": "sha256:bb", "b.bin": "sha256:aa"}
|
|
assert tree_hash(a) == tree_hash(b)
|
|
|
|
|
|
def test_filesystem_roundtrip(tmp_path: Path):
|
|
store = FilesystemStore(tmp_path / "ssot")
|
|
game = "test-game"
|
|
meta = empty_meta(game, 3)
|
|
store.put_meta(game, meta)
|
|
assert store.get_meta(game) is not None
|
|
|
|
local = tmp_path / "wip"
|
|
local.mkdir()
|
|
(local / "save.dat").write_bytes(b"hello-save")
|
|
checksums = store.upload_prefix(game, "live", "", local)
|
|
assert "save.dat" in checksums
|
|
|
|
dest = tmp_path / "down"
|
|
got = store.download_live(game, dest)
|
|
assert got["save.dat"].startswith("sha256:")
|
|
assert (dest / "save.dat").read_bytes() == b"hello-save"
|
|
|
|
store.upload_prefix(game, "history", "phone/20260101T000000Z", local)
|
|
hist = store.list_history(game)
|
|
assert any(h.startswith("phone/") for h in hist)
|
|
|
|
probe = store.probe()
|
|
assert probe.startswith("sha256:")
|
|
|
|
|
|
def test_meta_json_roundtrip(tmp_path: Path):
|
|
store = FilesystemStore(tmp_path)
|
|
m = empty_meta("g1")
|
|
m.raw["lease"] = {
|
|
"holder": "pc",
|
|
"expires_at": "2099-01-01T00:00:00Z",
|
|
"session_id": "x",
|
|
}
|
|
store.put_meta("g1", m)
|
|
again = store.get_meta("g1")
|
|
assert again is not None
|
|
assert again.lease["holder"] == "pc"
|
|
# ensure valid json file
|
|
text = (tmp_path / "games" / "g1" / "meta.json").read_text()
|
|
json.loads(text)
|