mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
Merge unseen-getrepo-cache: bucket-cache get_repo (one-time used-set canonicalization)
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
@@ -108,6 +108,9 @@ class CorpusBank:
|
||||
self.resolved_prefix = f"{prefix}/{seed}/resolved/"
|
||||
self.advisories_key = f"{prefix}/{seed}/advisories/list.json"
|
||||
self.repositories_prefix = f"{prefix}/{seed}/repositories/"
|
||||
# get_repo metadata is seed-independent GitHub data: share it across seeds
|
||||
# so the ~thousands of used-set canonicalization lookups are paid once ever.
|
||||
self.repos_prefix = f"{prefix}/repos/"
|
||||
|
||||
@staticmethod
|
||||
def advisory_key(advisory_id: str) -> str:
|
||||
@@ -192,6 +195,24 @@ class CorpusBank:
|
||||
if body["resolution_contract"] == contract
|
||||
}
|
||||
|
||||
def cache_repo(self, name: str, metadata: dict | None, *, contract: str) -> None:
|
||||
"""Persist one get_repo result (metadata, or None for a 404) by normalized name."""
|
||||
self._put(
|
||||
self.repos_prefix + hashlib.sha256(name.encode()).hexdigest() + ".json",
|
||||
{"name": name, "metadata": metadata, "resolution_contract": contract},
|
||||
labels={"contract": contract},
|
||||
)
|
||||
|
||||
def get_cached_repo(self, name: str, *, contract: str) -> tuple[bool, dict | None]:
|
||||
"""Return (found, metadata). found is True even when metadata is None (a cached 404)."""
|
||||
stored = _retry(self.client.get, self.repos_prefix + hashlib.sha256(name.encode()).hexdigest() + ".json")
|
||||
if stored is None:
|
||||
return (False, None)
|
||||
body = json.loads(stored[0])
|
||||
if body.get("name") != name or body.get("resolution_contract") != contract:
|
||||
return (False, None)
|
||||
return (True, body["metadata"])
|
||||
|
||||
@staticmethod
|
||||
def key_for(repository: str, fix: str) -> str:
|
||||
return hashlib.sha256(f"{repository}\n{fix}".encode()).hexdigest()
|
||||
|
||||
@@ -218,6 +218,26 @@ class BankedGitHub(ResolvedGitHub):
|
||||
self.resolutions = bank.repositories(contract=RESOLUTION_CONTRACT)
|
||||
journal.rows["resolution"].update({name: body["metadata"] if body is not None else None for name, body in self.resolutions.items()})
|
||||
|
||||
def get_repo(self, name):
|
||||
# Bucket-cache get_repo (the universal resolution choke point) so the
|
||||
# ~thousands of used-set canonicalization lookups and candidate resolves
|
||||
# are not re-fetched from GitHub every run. 404s are cached as None too.
|
||||
key = eligibility.normalize(name)
|
||||
if key not in self.journal.rows["resolution"]:
|
||||
found, value = self.bank.get_cached_repo(key, contract=RESOLUTION_CONTRACT)
|
||||
if not found:
|
||||
self.journal.boundary()
|
||||
try:
|
||||
value = self.github.get_repo(key)
|
||||
except eligibility.RepositoryNotFound:
|
||||
value = None
|
||||
self.bank.cache_repo(key, value, contract=RESOLUTION_CONTRACT)
|
||||
self.journal.put("resolution", key, value)
|
||||
value = self.journal.rows["resolution"][key]
|
||||
if value is None:
|
||||
raise eligibility.RepositoryNotFound("not_found")
|
||||
return value
|
||||
|
||||
def resolve(self, name):
|
||||
key = eligibility.normalize(name)
|
||||
if key not in self.resolutions:
|
||||
|
||||
@@ -38,6 +38,25 @@ class FakeObjects:
|
||||
return [key for key in reversed(self.objects) if key.startswith(prefix)]
|
||||
|
||||
|
||||
def test_cache_repo_roundtrip_404_and_shared_prefix():
|
||||
objects = FakeObjects()
|
||||
bank = CorpusBank(objects, seed=20260601, prefix="unseen")
|
||||
# the get_repo cache is shared across seeds, not under the seed prefix
|
||||
assert bank.repos_prefix == "unseen/repos/"
|
||||
bank.cache_repo("org/repo", {"full_name": "org/repo", "size": 10}, contract="v1")
|
||||
bank.cache_repo("org/gone", None, contract="v1")
|
||||
assert bank.get_cached_repo("org/repo", contract="v1") == (True, {"full_name": "org/repo", "size": 10})
|
||||
# a cached 404 is a hit (found True, metadata None): it must not re-hit GitHub
|
||||
assert bank.get_cached_repo("org/gone", contract="v1") == (True, None)
|
||||
assert bank.get_cached_repo("org/never", contract="v1") == (False, None)
|
||||
# a stale contract is a miss so the lookup is refreshed
|
||||
assert bank.get_cached_repo("org/repo", contract="v2") == (False, None)
|
||||
# idempotent: re-caching the same metadata does not rewrite
|
||||
puts = objects.calls.count("put")
|
||||
bank.cache_repo("org/repo", {"full_name": "org/repo", "size": 10}, contract="v1")
|
||||
assert objects.calls.count("put") == puts
|
||||
|
||||
|
||||
def settings_env():
|
||||
return {
|
||||
"CORPUS_S3_ENDPOINT": "https://objects.invalid",
|
||||
|
||||
Reference in New Issue
Block a user