Skip to content

Commit 073663c

Browse files
committed
Use download cache in unit tests
During unit tests, replace ModController.extract_archive with a version that caches extracted archives in /tmp, then copies them into ammo's mod storage directory when extraction is requested. This ensures that each archive must only be extracted once per test session. This also allows removing a condition from ModController.extract_archive which previously prevented archive validation from taking place when the unit tests were running. This doubles execution speed of the test suite on my system.
1 parent 2774333 commit 073663c

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

ammo/controller/mod.py

+7-9
Original file line numberDiff line numberDiff line change
@@ -406,15 +406,13 @@ def extract_archive(self, index: int, download: Path) -> Path:
406406
download.location = new_location
407407
download.name = new_location.name
408408

409-
if "pytest" not in sys.modules:
410-
# Don't run this during tests because it's slow.
411-
try:
412-
print("Verifying archive integrity...")
413-
subprocess.check_output(["7z", "t", f"{download.location}"])
414-
except subprocess.CalledProcessError:
415-
raise Warning(
416-
f"Extraction of {index} failed at integrity check. Incomplete download?"
417-
)
409+
try:
410+
print("Verifying archive integrity...")
411+
subprocess.check_output(["7z", "t", f"{download.location}"])
412+
except subprocess.CalledProcessError:
413+
raise Warning(
414+
f"Extraction of {index} failed at integrity check. Incomplete download?"
415+
)
418416

419417
os.system(f"7z x '{download.location}' -o'{extract_to}'")
420418

test/conftest.py

+42
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,52 @@
11
#!/usr/bin/env python3
2+
import os
3+
import shutil
4+
from pathlib import Path
25
from unittest.mock import patch
36

47
import pytest
58

69
from ammo.controller.mod import ModController
710

11+
EXTRACT_CACHE = Path("/tmp/ammo_extract_cache/")
12+
13+
14+
def get_cached_archive(self, index: int, download: Path) -> Path:
15+
"""
16+
See if an extracted archive is cached. If it is, copy it to
17+
/tmp/ammo_test/MockGame/mods/. If it's not, extract it, cache it,
18+
then copy it to /tmp/ammo_test/MockGame/mods/.
19+
20+
Return Path("/tmp/ammo_test/MockGame/mods/<extracted_archive>")
21+
"""
22+
extract_to_name = "".join(
23+
[i for i in download.location.stem.replace(" ", "_") if i.isalnum() or i == "_"]
24+
).strip()
25+
26+
extract_to = self.game.ammo_mods_dir / extract_to_name
27+
if extract_to.exists():
28+
raise Warning(
29+
f"Extraction of {index} failed since mod '{extract_to.name}' exists."
30+
)
31+
32+
archive_at = EXTRACT_CACHE / extract_to_name
33+
if not archive_at.exists():
34+
os.system(f"7z x '{download.location}' -o'{archive_at}'")
35+
36+
os.system(f"cp -r {archive_at} {extract_to}")
37+
38+
return extract_to
39+
40+
41+
@pytest.fixture(scope="session", autouse=True)
42+
def mock_extract_archive():
43+
try:
44+
EXTRACT_CACHE.mkdir(parents=True, exist_ok=True)
45+
with patch.object(ModController, "extract_archive", get_cached_archive):
46+
yield
47+
finally:
48+
shutil.rmtree(EXTRACT_CACHE, ignore_errors=True)
49+
850

951
@pytest.fixture
1052
def mock_has_extra_folder():

0 commit comments

Comments
 (0)