Skip to content

Commit 0c32c84

Browse files
committed
Fix the issue with construct gpkg diff in case of geodiff copy error
Make temp changeset and destination changeset have unique names which differ to avoid removing of live diff file.
1 parent 931f548 commit 0c32c84

2 files changed

Lines changed: 43 additions & 3 deletions

File tree

server/mergin/sync/storages/disk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ def construct_diff(
333333
# create changeset next to uploaded file copy
334334
changeset_tmp = os.path.join(
335335
os.path.dirname(uploaded_file_tmp),
336-
diff_name,
336+
diff_name + "_tmp",
337337
)
338338
self.flush_geodiff_logger()
339339
logging.info(

server/mergin/tests/test_project_controller.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
PushChangeType,
3939
ProjectFilePath,
4040
)
41+
from ..sync.storages.disk import copy_file as real_copy_file
4142
from ..sync.files import files_changes_from_upload
4243
from ..sync.schemas import ProjectListSchema
4344
from ..sync.utils import Checkpoint, generate_checksum, is_versioned_file
@@ -57,6 +58,7 @@
5758
create_project,
5859
create_workspace,
5960
DateTimeEncoder,
61+
execute_query,
6062
login,
6163
file_info,
6264
login_as_admin,
@@ -1620,6 +1622,44 @@ def test_push_no_diff_finish(client):
16201622
)
16211623
assert not os.path.exists(upload.project.storage.geodiff_working_dir)
16221624

1625+
# test the same with geodiff working dir error (fallback to _tmp next to original file)
1626+
working_file = os.path.join(working_dir, "base.gpkg")
1627+
sql = "INSERT INTO simple (geometry, name) VALUES (GeomFromText('POINT(24.5, 38.2)', 4326), 'insert_test')"
1628+
execute_query(working_file, sql)
1629+
changes = {
1630+
"added": [],
1631+
"removed": [],
1632+
"updated": [
1633+
file_info(working_dir, "base.gpkg", chunk_size=CHUNK_SIZE),
1634+
],
1635+
}
1636+
upload, upload_dir = create_transaction("mergin", changes, version=2)
1637+
upload_chunks(upload_dir, upload.changes, src_dir=working_dir)
1638+
1639+
def copy_file_failing_for_geodiff(src, dest):
1640+
"""Mocked implementation of copy_file, failing if dest is geodiff directory."""
1641+
if current_app.config["GEODIFF_WORKING_DIR"] in dest:
1642+
raise OSError("Mocked: copy to geodiff dir failed")
1643+
return real_copy_file(src, dest)
1644+
1645+
with patch(
1646+
"mergin.sync.storages.disk.copy_file",
1647+
side_effect=copy_file_failing_for_geodiff,
1648+
):
1649+
resp = client.post("/v1/project/push/finish/{}".format(upload.id))
1650+
assert resp.status_code == 200
1651+
latest_version = upload.project.get_latest_version()
1652+
file_meta = latest_version.changes.filter(
1653+
FileHistory.change == PushChangeType.UPDATE_DIFF.value
1654+
).first()
1655+
assert file_meta.diff_file is not None
1656+
assert os.path.exists(
1657+
os.path.join(
1658+
upload.project.storage.project_dir, file_meta.diff_file.location
1659+
)
1660+
)
1661+
assert not os.path.exists(upload.project.storage.geodiff_working_dir)
1662+
16231663
# change structure of gpkg file so diff would not be available -> hard overwrite
16241664
gpkg_conn = pysqlite3.connect(os.path.join(working_dir, "base.gpkg"))
16251665
gpkg_conn.enable_load_extension(True)
@@ -1635,7 +1675,7 @@ def test_push_no_diff_finish(client):
16351675
file_info(working_dir, "test.txt", chunk_size=CHUNK_SIZE),
16361676
],
16371677
}
1638-
upload, upload_dir = create_transaction("mergin", changes, version=2)
1678+
upload, upload_dir = create_transaction("mergin", changes, version=3)
16391679
upload_chunks(upload_dir, upload.changes, src_dir=working_dir)
16401680
resp = client.post("/v1/project/push/finish/{}".format(upload.id))
16411681
assert resp.status_code == 200
@@ -1652,7 +1692,7 @@ def test_push_no_diff_finish(client):
16521692
).count()
16531693
== 2
16541694
)
1655-
version_files = os.listdir(os.path.join(upload.project.storage.project_dir, "v3"))
1695+
version_files = os.listdir(os.path.join(upload.project.storage.project_dir, "v4"))
16561696
diff_files = [f for f in version_files if re.findall("-diff-", f)]
16571697
assert not diff_files
16581698

0 commit comments

Comments
 (0)