Skip to content

Commit 089cfea

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 8ae944c commit 089cfea

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

tests/repository_simulator.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def __init__(self):
108108
# target downloads are served from this dict
109109
self.target_files: Dict[str, RepositoryTarget] = {}
110110

111-
# Whether to compute hashes and legth for meta in snapshot/timestamp
111+
# Whether to compute hashes and length for meta in snapshot/timestamp
112112
self.compute_metafile_hashes_length = False
113113

114114
self.dump_dir = None
@@ -145,6 +145,21 @@ def create_key() -> Tuple[Key, SSlibSigner]:
145145
sslib_key = generate_ed25519_key()
146146
return Key.from_securesystemslib_key(sslib_key), SSlibSigner(sslib_key)
147147

148+
@staticmethod
149+
def _partition_filename(filename: str) -> Tuple[str, Optional[str]]:
150+
"""Partition 'filename' into filename and prefix, if any"""
151+
p1, sep, p2 = filename.partition(".")
152+
# If the separator is not found, returns a 3-tuple containing
153+
# the string itself, followed by two empty strings.
154+
if not sep:
155+
prefix = None
156+
filename = p1
157+
else:
158+
prefix = p1
159+
filename = p2
160+
161+
return filename, prefix
162+
148163
def add_signer(self, role: str, signer: SSlibSigner):
149164
if role not in self.signers:
150165
self.signers[role] = {}
@@ -185,24 +200,19 @@ def publish_root(self):
185200
logger.debug("Published root v%d", self.root.version)
186201

187202
def fetch(self, url: str) -> Iterator[bytes]:
188-
if not self.root.consistent_snapshot:
189-
raise NotImplementedError("non-consistent snapshot not supported")
190203
path = parse.urlparse(url).path
191204
if path.startswith("/metadata/") and path.endswith(".json"):
192205
ver_and_name = path[len("/metadata/") :][: -len(".json")]
193-
# only consistent_snapshot supported ATM: timestamp is special case
194-
if ver_and_name == "timestamp":
195-
version = None
196-
role = "timestamp"
197-
else:
198-
version, _, role = ver_and_name.partition(".")
206+
role, version = self._partition_filename(ver_and_name)
207+
if version:
199208
version = int(version)
209+
200210
yield self._fetch_metadata(role, version)
201211
elif path.startswith("/targets/"):
202212
# figure out target path and hash prefix
203213
target_path = path[len("/targets/") :]
204214
dir_parts, sep, prefixed_filename = target_path.rpartition("/")
205-
prefix, _, filename = prefixed_filename.partition(".")
215+
filename, prefix = self._partition_filename(prefixed_filename)
206216
target_path = f"{dir_parts}{sep}{filename}"
207217

208218
yield self._fetch_target(target_path, prefix)
@@ -245,7 +255,7 @@ def _fetch_metadata(
245255
elif role == "targets":
246256
md = self.md_targets
247257
else:
248-
md = self.md_delegates[role]
258+
md = self.md_delegates.get(role)
249259

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

0 commit comments

Comments
 (0)