mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
"""Export must not carry the stale inline output.files snapshot when a workspace
|
|
exists. output.files is frozen at creation (v1); the agent edits land on disk
|
|
(v2). serialize() used to ship the v1 snapshot alongside the v2 disk copy, so an
|
|
imported app reverted every edited file (new files survived since they were never
|
|
in the snapshot). With a workspace, disk is the single source of truth; only true
|
|
flat apps (no workspace) still carry the inline copy."""
|
|
import uuid
|
|
|
|
import pytest
|
|
|
|
from backend.apps.outputs import workspace_io
|
|
from backend.apps.outputs.models import Output
|
|
from backend.apps.swarm.entities import apps as apps_mod
|
|
from backend.apps.swarm.entities.apps import AppExportable
|
|
|
|
|
|
class P_Ctx:
|
|
pass
|
|
|
|
|
|
@pytest.fixture
|
|
def p_ws_root(tmp_path, monkeypatch):
|
|
root = tmp_path / "ws"
|
|
root.mkdir()
|
|
out = tmp_path / "out"
|
|
out.mkdir()
|
|
monkeypatch.setattr(apps_mod, "OUTPUTS_WORKSPACE_DIR", str(root))
|
|
monkeypatch.setattr(workspace_io, "DATA_DIR", str(out))
|
|
return root
|
|
|
|
|
|
def p_make_app(ws_root, *, workspace: bool) -> str:
|
|
wsid = uuid.uuid4().hex if workspace else None
|
|
if wsid:
|
|
folder = ws_root / wsid
|
|
folder.mkdir()
|
|
(folder / "app.py").write_text("print('v1')\n")
|
|
o = Output(
|
|
name="Demo", description="", icon="view_quilt",
|
|
input_schema={"type": "object", "properties": {}, "required": []},
|
|
files={"app.py": "print('v1')\n"},
|
|
workspace_id=wsid, session_id=None,
|
|
)
|
|
workspace_io.save(o)
|
|
return o.id
|
|
|
|
|
|
def test_workspace_app_export_omits_stale_inline_files(p_ws_root):
|
|
oid = p_make_app(p_ws_root, workspace=True)
|
|
o = workspace_io.load_output(oid)
|
|
folder = p_ws_root / o.workspace_id
|
|
# agent edit -> v2 on disk: modify app.py + add new.py (output.files stays v1)
|
|
(folder / "app.py").write_text("print('v2 EDITED')\n")
|
|
(folder / "new.py").write_text("print('v2 NEW')\n")
|
|
|
|
exp = AppExportable.load(oid)
|
|
payload = exp.serialize(P_Ctx())
|
|
disk = exp.files()
|
|
|
|
# the stale v1 snapshot must NOT ride along
|
|
assert payload["files"] == {}, "workspace app must not export the frozen output.files snapshot"
|
|
# disk (v2) is what travels, both the edit and the new file
|
|
assert disk["workspace/app.py"] == b"print('v2 EDITED')\n"
|
|
assert disk["workspace/new.py"] == b"print('v2 NEW')\n"
|
|
|
|
|
|
def test_flat_app_without_workspace_still_carries_inline_files(p_ws_root):
|
|
oid = p_make_app(p_ws_root, workspace=False)
|
|
exp = AppExportable.load(oid)
|
|
payload = exp.serialize(P_Ctx())
|
|
# no workspace -> inline files ARE the source, must survive export
|
|
assert payload["files"] == {"app.py": "print('v1')\n"}
|