Skip to content

Commit f78350f

Browse files
committed
Add unit-testing for DownloadDirectory to ensure expected operation
Also shortened the log line to not include traceback
1 parent 7cd4c99 commit f78350f

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

dandi/download.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -870,12 +870,11 @@ def __exit__(
870870
assert self.fp is not None
871871
if exc_type is not None or exc_val is not None or exc_tb is not None:
872872
lgr.debug(
873-
"%s - entered __exit__ with position %d with exception: " "%s, %s, %s",
873+
"%s - entered __exit__ with position %d with exception: %s, %s",
874874
self.dirpath,
875875
self.fp.tell(),
876876
exc_type,
877877
exc_val,
878-
exc_tb,
879878
)
880879
else:
881880
lgr.debug(

dandi/tests/test_download.py

+82
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from __future__ import annotations
22

33
from collections.abc import Callable
4+
from glob import glob
45
import json
6+
import logging
7+
from multiprocessing import Manager, Process
58
import os
69
import os.path
710
from pathlib import Path
@@ -21,6 +24,7 @@
2124
from ..consts import DRAFT, dandiset_metadata_file
2225
from ..dandiarchive import DandisetURL
2326
from ..download import (
27+
DownloadDirectory,
2428
Downloader,
2529
DownloadExisting,
2630
DownloadFormat,
@@ -1038,3 +1042,81 @@ def test_pyouthelper_time_remaining_1339():
10381042
assert len(done) == 2
10391043
else:
10401044
assert done[-1] == f"ETA: {10 - i} seconds<"
1045+
1046+
1047+
def test_DownloadDirectory_basic(tmp_path: Path) -> None:
1048+
with DownloadDirectory(tmp_path, digests={}) as dl:
1049+
assert dl.dirpath.exists()
1050+
assert dl.writefile.exists()
1051+
assert dl.writefile.stat().st_size == 0
1052+
assert dl.offset == 0
1053+
1054+
dl.append(b"123")
1055+
assert dl.fp is not None
1056+
dl.fp.flush() # appends are not flushed automatically
1057+
assert dl.writefile.stat().st_size == 3
1058+
assert dl.offset == 0 # doesn't change
1059+
1060+
dl.append(b"456")
1061+
# but after we are done - should be a full file!
1062+
assert tmp_path.stat().st_size == 6
1063+
assert tmp_path.read_bytes() == b"123456"
1064+
1065+
# no problem with overwriting with new content
1066+
with DownloadDirectory(tmp_path, digests={}) as dl:
1067+
dl.append(b"789")
1068+
assert tmp_path.read_bytes() == b"789"
1069+
1070+
# even if path is a directory which we "overwrite"
1071+
tmp_path.unlink()
1072+
tmp_path.mkdir()
1073+
(tmp_path / "somedata.dat").write_text("content")
1074+
with DownloadDirectory(tmp_path, digests={}) as dl:
1075+
assert set(glob(f"{tmp_path}*")) == {str(tmp_path), str(dl.dirpath)}
1076+
dl.append(b"123")
1077+
assert tmp_path.read_bytes() == b"123"
1078+
1079+
# no temp .dandidownload folder is left behind
1080+
assert set(glob(f"{tmp_path}*")) == {str(tmp_path)}
1081+
1082+
# test locking
1083+
def subproc(path, results):
1084+
try:
1085+
with DownloadDirectory(path, digests={}):
1086+
results.append("re-entered fine")
1087+
except Exception as exc:
1088+
results.append(str(exc))
1089+
1090+
with Manager() as manager:
1091+
results = manager.list()
1092+
with DownloadDirectory(tmp_path, digests={}) as dl:
1093+
dl.append(b"123")
1094+
p1 = Process(target=subproc, args=(tmp_path, results))
1095+
p1.start()
1096+
p1.join()
1097+
assert len(results) == 1
1098+
assert results[0] == f"Could not acquire download lock for {tmp_path}"
1099+
assert tmp_path.read_bytes() == b"123"
1100+
1101+
1102+
def test_DownloadDirectory_exc(
1103+
tmp_path: Path, caplog: pytest.LogCaptureFixture
1104+
) -> None:
1105+
caplog.set_level(logging.DEBUG, logger="dandi")
1106+
# and now let's exit with exception
1107+
with pytest.raises(RuntimeError):
1108+
with DownloadDirectory(tmp_path, digests={}) as dl:
1109+
dl.append(b"456")
1110+
raise RuntimeError("Boom")
1111+
assert (
1112+
"dandi",
1113+
10,
1114+
f"{dl.dirpath} - entered __exit__ with position 3 with exception: "
1115+
"<class 'RuntimeError'>, Boom",
1116+
) == caplog.record_tuples[-1]
1117+
# and we left without cleanup but closed things up after ourselves
1118+
assert tmp_path.exists()
1119+
assert tmp_path.is_dir()
1120+
assert dl.dirpath.exists()
1121+
assert dl.fp is None
1122+
assert dl.writefile.read_bytes() == b"456"

0 commit comments

Comments
 (0)