Skip to content

Commit 605ff88

Browse files
committed
Merge branch 'main' into forman-72-replace_option
2 parents ed257e4 + 2b56f1f commit 605ff88

File tree

4 files changed

+46
-7
lines changed

4 files changed

+46
-7
lines changed

CHANGES.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## Version 0.5.2 (in development)
2+
3+
4+
5+
## Version 0.5.1 (2024-02-23)
6+
7+
* Fixed rollback for situations where writing to Zarr fails shortly after the
8+
Zarr directory has been created. [#69]
9+
10+
In this case the error message was
11+
```TypeError: Transaction._delete_dir() missing 1 required positional argument: 'target_path'```.
12+
13+
114
## Version 0.5.0 (2024-02-19)
215

316
### Enhancements

tests/fsutil/test_transaction.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ class TransactionTest(unittest.TestCase):
1818
def setUp(self):
1919
clear_memory_fs()
2020

21+
def test_rollback_after_create_dir(self):
22+
"""See https://github.com/bcdev/zappend/issues/69"""
23+
test_root = FileObj("memory://test")
24+
test_root.mkdir()
25+
target_dir = test_root / "target.zarr"
26+
try:
27+
with Transaction(target_dir, FileObj("memory://temp")) as rollback_cb:
28+
try:
29+
# create target directory
30+
target_dir.mkdir()
31+
# and then suddenly fail
32+
raise OSError("core meltdown")
33+
finally:
34+
# assert target directory created
35+
self.assertTrue(target_dir.exists())
36+
# notify this
37+
rollback_cb("delete_dir", "", None)
38+
except OSError:
39+
# assert that it correctly rolled back
40+
# creating of target directory
41+
self.assertFalse(target_dir.exists())
42+
2143
def test_transaction_success(self):
2244
self._run_transaction_test(fail=False, rollback=True)
2345

@@ -79,14 +101,14 @@ def create_test_folder(rollback_cb: Callable):
79101
if rollback:
80102
rollback_data = rollback_file.read(mode="rt")
81103
rollback_records = [
82-
line.split()[:2] for line in rollback_data.split("\n")
104+
line.split(";")[:2] for line in rollback_data.split("\n")
83105
]
84106
self.assertEqual(
85107
[
86108
["replace_file", "file-1.txt"],
87109
["delete_file", "file-2.txt"],
88110
["delete_dir", "folder"],
89-
[],
111+
[""],
90112
],
91113
rollback_records,
92114
)

zappend/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# Permissions are hereby granted under the terms of the MIT License:
33
# https://opensource.org/licenses/MIT.
44

5-
__version__ = "0.5.0"
5+
__version__ = "0.5.2.dev0"

zappend/fsutil/transaction.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
LOCK_EXT = ".lock"
2525
ROLLBACK_FILE = "__rollback__.txt"
26+
ROLLBACK_CSV_SEP = ";"
2627

2728
ROLLBACK_ACTIONS = "delete_dir", "delete_file", "replace_file"
2829

@@ -144,8 +145,10 @@ def __exit__(self, exc_type, exc_val, exc_tb):
144145
rollback_txt = self._rollback_file.read(mode="r")
145146
rollback_records = [
146147
record
147-
for record in [line.split() for line in rollback_txt.split("\n")]
148-
if record
148+
for record in [
149+
line.split(ROLLBACK_CSV_SEP) for line in rollback_txt.split("\n")
150+
]
151+
if record and record != [""]
149152
]
150153

151154
if rollback_records:
@@ -212,13 +215,14 @@ def _add_rollback_action(
212215
return
213216

214217
assert hasattr(self, "_" + action)
218+
215219
if data is not None:
216220
backup_id = str(uuid.uuid4())
217221
backup_file = self._rollback_dir.for_path(backup_id)
218222
backup_file.write(data)
219-
rollback_entry = f"{action} {path} {backup_id}"
223+
rollback_entry = ROLLBACK_CSV_SEP.join((action, path, backup_id))
220224
else:
221-
rollback_entry = f"{action} {path}"
225+
rollback_entry = ROLLBACK_CSV_SEP.join((action, path))
222226

223227
logger.debug(f"Recording rollback record: {rollback_entry!r}")
224228
self._rollback_file.write(rollback_entry + "\n", mode="a")

0 commit comments

Comments
 (0)