Skip to content

Commit 1a3080e

Browse files
committed
- bugfix wrong path returned for local mirror caching
1 parent 69e8530 commit 1a3080e

File tree

3 files changed

+45
-31
lines changed

3 files changed

+45
-31
lines changed

aura/cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def metadata(self) -> dict:
348348

349349
def fetch(self):
350350
shutil.copyfile(src=self.src, dst=self.cache_file_location, follow_symlinks=True)
351-
self.metadata_location.write_text(dumps(self.metadata))
351+
self.save_metadata()
352352

353353

354354
class PyPIPackageList(Cache):

aura/uri_handlers/mirror.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ def get_paths(self, metadata: Optional[dict]=None, package=None) -> Generator[Sc
5353
meta.update(self.metadata)
5454
meta.setdefault("package", {})["info"] = x
5555
pkg_path = self.mirror_path / urlparse(x["url"]).path.lstrip("/")
56-
target = cache.MirrorFile.proxy(src=pkg_path, cache_id=x['filename'])
56+
target = cache.MirrorFile.proxy(src=pkg_path)
5757

5858
if target:
5959
yield ScanLocation(
60-
location=pkg_path,
60+
location=target,
6161
metadata=meta
6262
)

tests/test_cache.py

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import uuid
44
from unittest import mock
55
from pathlib import Path
6+
from urllib.parse import urlparse
7+
from contextlib import ExitStack
68

79
import pytest
810
import responses
@@ -11,6 +13,7 @@
1113
from aura import cache
1214
from aura import mirror
1315
from aura import exceptions
16+
from aura.uri_handlers.base import URIHandler
1417

1518

1619
CACHE_ENTRIES = {
@@ -99,50 +102,61 @@ def test_mirror_cache(fixtures, simulate_mirror, mock_cache):
99102
))
100103
def test_mirror_cache_paths(file_path, fixtures, mock_cache):
101104
pth = Path(fixtures.path(file_path))
105+
exc = RuntimeError("failed")
102106
assert pth.exists()
103107

108+
mock_pth = mock.Mock(spec=pth, wraps=pth)
109+
mock_pth.exists.side_effect = exc
110+
mock_pth.name = pth.name
111+
104112
cached = cache.MirrorFile.proxy(src=pth)
105113
assert cached != pth
114+
assert cached != mock_pth
106115

107-
with mock.patch.object(cache.MirrorFile, "fetch", side_effect=RuntimeError("failed")):
108-
cached2 = cache.MirrorFile.proxy(src=pth)
116+
with mock.patch.object(cache.MirrorFile, "fetch", side_effect=exc):
117+
cached2 = cache.MirrorFile.proxy(src=mock_pth)
109118

110119
assert cached2 == cached
111120

112121
cache_obj = cache.MirrorFile(src=pth)
113-
assert cache_obj.is_valid
122+
assert cache_obj.is_valid is True
114123
assert cache_obj.cache_file_location == cached
115124
assert cache_obj.cache_file_location.exists()
116125
assert cache_obj.metadata_location.exists()
117126

118127
cache_obj.delete()
119128
assert not cache_obj.cache_file_location.exists()
120129
assert not cache_obj.metadata_location.exists()
121-
assert not cache_obj.is_valid
122-
123-
124-
@mock.patch("aura.mirror.LocalMirror.get_mirror_path")
125-
def test_mirror_cache_no_remote_access(mirror_mock, tmp_path, mock_cache):
126-
"""
127-
Test that if the content is fully cached, the mirror uri handler does not attempt to access the mirror but rather retrieves **all** content from cache only
128-
This is mainly to test correctness of prefetching the data for global PyPI scan to ensure no further network calls are made
129-
"""
130-
pkg = str(uuid.uuid4())
131-
pkg_content = {"id": pkg}
132-
mirror_path = tmp_path / "mirror"
133-
mirror_mock.return_value = mirror_path
134-
m = mirror.LocalMirror()
135-
136-
cache_path = cache.Cache.get_location()
137-
assert m.get_mirror_path() == mirror_path
138-
assert mirror_path.exists() == False
139-
140-
with pytest.raises(exceptions.NoSuchPackage):
141-
m.get_json(pkg)
142-
143-
(cache_path/f"mirrorjson_{pkg}").write_text(json.dumps(pkg_content))
144-
out = m.get_json(pkg)
145-
assert out == pkg_content
130+
assert cache_obj.is_valid is False
131+
132+
133+
def test_mirror_no_remote_access(simulate_mirror, mock_cache):
134+
uri = "mirror://wheel"
135+
exc = RuntimeError("test failed")
136+
137+
assert str(mirror.LocalMirror.get_mirror_path()) == simulate_mirror
138+
assert cache.MirrorFile.get_location() is not None
139+
140+
handler = URIHandler.from_uri(uri)
141+
paths = tuple(handler.get_paths())
142+
assert len(paths) > 0
143+
144+
for path in paths:
145+
assert path.location.exists()
146+
path = str(path.location)
147+
assert not path.startswith(simulate_mirror)
148+
149+
150+
with ExitStack() as stack:
151+
# Mock any remote file access functionality to throw an exception
152+
shutil_mock = stack.enter_context(mock.patch("aura.cache.shutil"))
153+
shutil_mock.copyfile.side_effect = exc
154+
fetch_mock = stack.enter_context(mock.patch("aura.cache.MirrorFile.fetch", side_effect=exc))
155+
156+
handler_cached = URIHandler.from_uri(uri)
157+
paths_cached = tuple(handler_cached.get_paths())
158+
159+
assert paths == paths_cached
146160

147161

148162
@mock.patch("aura.cache.get_cache_threshold")

0 commit comments

Comments
 (0)