Skip to content

Commit 3474a15

Browse files
committed
wip
fix tmppath issue fix tests make error message bad again
1 parent 2a34c7d commit 3474a15

File tree

6 files changed

+44
-47
lines changed

6 files changed

+44
-47
lines changed

disk_objectstore/backup_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ def call_rsync( # pylint: disable=too-many-arguments,too-many-branches
221221

222222
def get_existing_backup_folders(self):
223223
"""Get all folders matching the backup folder name pattern."""
224+
224225
success, stdout = self.run_cmd(
225226
[
226227
"find",

disk_objectstore/container.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def __init__(self, folder: str | Path) -> None:
121121
self._folder = Path(folder).resolve()
122122
# Will be populated by the _get_session function
123123
self._session: Session | None = None
124+
self._keep_open_session: Session | None = None
124125

125126
# These act as caches and will be populated by the corresponding properties
126127
# IMPORANT! IF YOU ADD MORE, REMEMBER TO CLEAR THEM IN `init_container()`!
@@ -134,9 +135,17 @@ def get_folder(self) -> Path:
134135
def close(self) -> None:
135136
"""Close open files (in particular, the connection to the SQLite DB)."""
136137
if self._session is not None:
138+
engine = self._session.bind
137139
self._session.close()
140+
engine.dispose()
138141
self._session = None
139142

143+
if self._keep_open_session is not None:
144+
engine = self._keep_open_session.bind
145+
self._keep_open_session.close()
146+
engine.dispose()
147+
self._keep_open_session = None
148+
140149
def __enter__(self) -> Container:
141150
"""Return a context manager that will close the session when exiting the context."""
142151
return self
@@ -180,32 +189,21 @@ def _get_config_file(self) -> Path:
180189
"""Return the path to the container config file."""
181190
return self._folder / "config.json"
182191

183-
@overload
184-
def _get_session(
185-
self, create: bool = False, raise_if_missing: Literal[True] = True
192+
def _create_init_session(
193+
self
186194
) -> Session:
187-
...
188-
189-
@overload
190-
def _get_session(
191-
self, create: bool = False, raise_if_missing: Literal[False] = False
192-
) -> Session | None:
193-
...
194-
195-
def _get_session(
196-
self, create: bool = False, raise_if_missing: bool = False
197-
) -> Session | None:
198195
"""Return a new session to connect to the pack-index SQLite DB.
199196
200197
:param create: if True, creates the sqlite file and schema.
201198
:param raise_if_missing: ignored if create==True. If create==False, and the index file
202199
is missing, either raise an exception (FileNotFoundError) if this flag is True, or return None
203200
"""
204-
return get_session(
205-
self._get_pack_index_path(),
206-
create=create,
207-
raise_if_missing=raise_if_missing,
208-
)
201+
if self._keep_open_session is None:
202+
self._keep_open_session = get_session(
203+
self._get_pack_index_path(),
204+
create=True,
205+
)
206+
return self._keep_open_session
209207

210208
def _get_cached_session(self) -> Session:
211209
"""Return the SQLAlchemy session to access the SQLite file,
@@ -214,7 +212,10 @@ def _get_cached_session(self) -> Session:
214212
# the latter means that in the previous run the pack file was missing
215213
# but maybe by now it has been created!
216214
if self._session is None:
217-
self._session = self._get_session(create=False, raise_if_missing=True)
215+
self._session = get_session(
216+
self._get_pack_index_path(),
217+
create=False,
218+
)
218219
return self._session
219220

220221
def _get_loose_path_from_hashkey(self, hashkey: str) -> Path:
@@ -332,6 +333,7 @@ def init_container(
332333
raise ValueError(f'Unknown hash type "{hash_type}"')
333334

334335
if clear:
336+
self.close()
335337
if self._folder.exists():
336338
shutil.rmtree(self._folder)
337339

@@ -391,7 +393,7 @@ def init_container(
391393
]:
392394
os.makedirs(folder)
393395

394-
self._get_session(create=True)
396+
self._create_init_session()
395397

396398
def _get_repository_config(self) -> dict[str, int | str]:
397399
"""Return the repository config."""
@@ -1141,7 +1143,7 @@ def get_total_size(self) -> TotalSize:
11411143

11421144
retval["total_size_packindexes_on_disk"] = (
11431145
self._get_pack_index_path().stat().st_size
1144-
)
1146+
)
11451147

11461148
total_size_loose = 0
11471149
for loose_hashkey in self._list_loose():
@@ -1916,6 +1918,9 @@ def add_objects_to_pack( # pylint: disable=too-many-arguments
19161918
19171919
:return: a list of object hash keys
19181920
"""
1921+
# TODO should be custom error but not sure what
1922+
if not self.is_initialised:
1923+
raise ValueError("Invalid use of function, please first initialise the container.")
19191924
stream_list: list[StreamSeekBytesType] = [
19201925
io.BytesIO(content) for content in content_list
19211926
]

disk_objectstore/database.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Obj(Base): # pylint: disable=too-few-public-methods
3232

3333

3434
def get_session(
35-
path: Path, create: bool = False, raise_if_missing: bool = False
35+
path: Path, create: bool = False
3636
) -> Optional[Session]:
3737
"""Return a new session to connect to the pack-index SQLite DB.
3838
@@ -41,9 +41,7 @@ def get_session(
4141
is missing, either raise an exception (FileNotFoundError) if this flag is True, or return None
4242
"""
4343
if not create and not path.exists():
44-
if raise_if_missing:
45-
raise FileNotFoundError("Pack index does not exist")
46-
return None
44+
raise FileNotFoundError("Pack index does not exist")
4745

4846
engine = create_engine(f"sqlite:///{path}", future=True)
4947

tests/conftest.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,14 @@ def temp_container(temp_dir): # pylint: disable=redefined-outer-name
8181

8282

8383
@pytest.fixture(scope="function")
84-
def temp_dir():
84+
def temp_dir(tmp_path):
8585
"""Get a temporary directory.
8686
8787
:return: The path to the directory
8888
:rtype: str
8989
"""
90-
import gc
91-
gc.collect()
92-
93-
try:
94-
dirpath = tempfile.mkdtemp()
95-
yield Path(dirpath)
96-
finally:
97-
# after the test function has completed, remove the directory again
98-
shutil.rmtree(dirpath)
90+
dirpath = tempfile.mkdtemp(dir=str(tmp_path))
91+
yield Path(dirpath)
9992

10093

10194
@pytest.fixture(scope="function")

tests/test_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def test_backup(temp_container, temp_dir, remote, verbosity):
223223
if verbosity:
224224
args += [f"--verbosity={verbosity}"]
225225

226-
result = CliRunner().invoke(cli.backup, args, obj=obj)
226+
result = CliRunner().invoke(cli.backup, args, obj=obj, catch_exceptions=False)
227227

228228
assert result.exit_code == 0
229229
assert path.exists()

tests/test_container.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -677,15 +677,16 @@ def test_initialisation(temp_dir):
677677

678678
# Check that the session cannot be obtained before initialising
679679
with pytest.raises(FileNotFoundError):
680-
container._get_session(create=False, raise_if_missing=True)
681-
assert container._get_session(create=False, raise_if_missing=False) is None
680+
container._get_cached_session()
682681

683682
container.init_container()
684683
assert container.is_initialised
684+
container.close()
685685

686686
# This call should go through
687687
container.init_container(clear=True)
688688
assert container.is_initialised
689+
container.close()
689690

690691
with pytest.raises(FileExistsError) as excinfo:
691692
container.init_container()
@@ -717,31 +718,32 @@ def test_initialisation(temp_dir):
717718

718719
@pytest.mark.parametrize("hash_type", ["sha256", "sha1"])
719720
@pytest.mark.parametrize("compress", [True, False])
720-
def test_check_hash_computation(temp_container, hash_type, compress):
721+
def test_check_hash_computation(temp_dir, hash_type, compress):
721722
"""Check that the hashes are correctly computed, when storing loose,
722723
directly to packs, and while repacking all loose.
723724
724725
Check both compressed and uncompressed packed objects.
725726
"""
726727
# Re-init the container with the correct hash type
727-
temp_container.init_container(hash_type=hash_type, clear=True)
728+
container = Container(temp_dir)
729+
container.init_container(hash_type=hash_type, clear=True)
728730
content1 = b"1"
729731
content2 = b"222"
730732
content3 = b"n2fwd"
731733

732734
expected_hasher = getattr(hashlib, hash_type)
733735

734-
hashkey1 = temp_container.add_object(content1)
736+
hashkey1 = container.add_object(content1)
735737
assert hashkey1 == expected_hasher(content1).hexdigest()
736738

737-
hashkey2, hashkey3 = temp_container.add_objects_to_pack(
739+
hashkey2, hashkey3 = container.add_objects_to_pack(
738740
[content2, content3], compress=compress
739741
)
740742
assert hashkey2 == expected_hasher(content2).hexdigest()
741743
assert hashkey3 == expected_hasher(content3).hexdigest()
742744

743745
# No exceptions should be aised
744-
temp_container.pack_all_loose(compress=compress, validate_objects=True)
746+
container.pack_all_loose(compress=compress, validate_objects=True)
745747

746748

747749
@pytest.mark.parametrize("validate_objects", [True, False])
@@ -1064,9 +1066,7 @@ def test_sizes(
10641066
temp_container, generate_random_data, compress_packs, compression_algorithm
10651067
):
10661068
"""Check that the information on size is reliable."""
1067-
temp_container.init_container(
1068-
clear=True, compression_algorithm=compression_algorithm
1069-
)
1069+
temp_container.init_container( clear=True, compression_algorithm=compression_algorithm)
10701070
size_info = temp_container.get_total_size()
10711071
assert size_info["total_size_packed"] == 0
10721072
assert size_info["total_size_packed_on_disk"] == 0

0 commit comments

Comments
 (0)