Skip to content

Commit 993c2e4

Browse files
committed
RepositorySimulator: add non-consistent snapshot support
Extend filename partitioning to support serving non-versioned metadata and non-prefixed target files. Signed-off-by: Teodora Sechkova <[email protected]>
1 parent fa7990c commit 993c2e4

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

tests/repository_simulator.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,12 @@ def __init__(self):
111111
# target downloads are served from this dict
112112
self.target_files: Dict[str, RepositoryTarget] = {}
113113

114-
# Whether to compute hashes and legth for meta in snapshot/timestamp
114+
# Whether to compute hashes and length for meta in snapshot/timestamp
115115
self.compute_metafile_hashes_length = False
116116

117+
# Enable hash-prefixed target file names
118+
self.prefix_targets_with_hash = True
119+
117120
self.dump_dir = None
118121
self.dump_version = 0
119122

@@ -192,24 +195,32 @@ def fetch(self, url: str) -> Iterator[bytes]:
192195
"""Fetches data from the given url and returns an Iterator (or yields
193196
bytes).
194197
"""
195-
if not self.root.consistent_snapshot:
196-
raise NotImplementedError("non-consistent snapshot not supported")
197198
path = parse.urlparse(url).path
198199
if path.startswith("/metadata/") and path.endswith(".json"):
200+
# figure out rolename and version
199201
ver_and_name = path[len("/metadata/") :][: -len(".json")]
200-
# only consistent_snapshot supported ATM: timestamp is special case
201-
if ver_and_name == "timestamp":
202-
version = None
203-
role = "timestamp"
204-
else:
202+
# root is always version-prefixed while timestamp is always NOT
203+
if ver_and_name.endswith("root") or (
204+
self.root.consistent_snapshot and ver_and_name != "timestamp"
205+
):
205206
version, _, role = ver_and_name.partition(".")
206207
version = int(version)
208+
else:
209+
# the file is not version-prefixed
210+
role = ver_and_name
211+
version = None
212+
207213
yield self._fetch_metadata(role, version)
208214
elif path.startswith("/targets/"):
209215
# figure out target path and hash prefix
210216
target_path = path[len("/targets/") :]
211217
dir_parts, sep, prefixed_filename = target_path.rpartition("/")
212-
prefix, _, filename = prefixed_filename.partition(".")
218+
# extract the hash prefix, if any
219+
if self.root.consistent_snapshot and self.prefix_targets_with_hash:
220+
prefix, _, filename = prefixed_filename.partition(".")
221+
else:
222+
filename = prefixed_filename
223+
prefix = None
213224
target_path = f"{dir_parts}{sep}{filename}"
214225

215226
yield self._fetch_target(target_path, prefix)
@@ -257,7 +268,7 @@ def _fetch_metadata(
257268
elif role == "targets":
258269
md = self.md_targets
259270
else:
260-
md = self.md_delegates[role]
271+
md = self.md_delegates.get(role)
261272

262273
if md is None:
263274
raise FetcherHTTPError(f"Unknown role {role}", 404)

0 commit comments

Comments
 (0)