Skip to content

Commit 9b5bfa7

Browse files
committed
Fixed #69, preparing 0.5.1
1 parent b75706a commit 9b5bfa7

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

CHANGES.md

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

312
### 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.1"

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

@@ -141,8 +142,10 @@ def __exit__(self, exc_type, exc_val, exc_tb):
141142
rollback_txt = self._rollback_file.read(mode="r")
142143
rollback_records = [
143144
record
144-
for record in [line.split() for line in rollback_txt.split("\n")]
145-
if record
145+
for record in [
146+
line.split(ROLLBACK_CSV_SEP) for line in rollback_txt.split("\n")
147+
]
148+
if record and record != [""]
146149
]
147150

148151
if rollback_records:
@@ -209,13 +212,14 @@ def _add_rollback_action(
209212
return
210213

211214
assert hasattr(self, "_" + action)
215+
212216
if data is not None:
213217
backup_id = str(uuid.uuid4())
214218
backup_file = self._rollback_dir.for_path(backup_id)
215219
backup_file.write(data)
216-
rollback_entry = f"{action} {path} {backup_id}"
220+
rollback_entry = ROLLBACK_CSV_SEP.join((action, path, backup_id))
217221
else:
218-
rollback_entry = f"{action} {path}"
222+
rollback_entry = ROLLBACK_CSV_SEP.join((action, path))
219223

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

0 commit comments

Comments
 (0)