mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
feat(scan): size portions from measured per-answer cost and isolate the kill culprit
The 7.8 trace showed the completion loss was a sizer death spiral, not expensive families: after two kills the budget fell to 3 sink visits and never recovered, because portions finishing in 25-30 s sat under an assumed 70 s fixed start and read as "no information", so the budget could only shrink. - taint.sc streams each answer's own cost (`ms`); the backend carries it as a reserved `__timing__` list through shards, partitions and reuse. - The sizer budgets predicted seconds from per-family seconds-per-visit rates learned from those costs, and measures the fixed start as the wall time the answers do not explain (median), instead of assuming it. - A kill names its culprit: the first unanswered id in request order. The ids behind it never started and are re-queued at once; the culprit is asked alone after the rest. One that still fails alone after more than a portion's target is reported as `query_too_expensive`, apart from `query_failed`. - Portions grow id by id from the queue head, and a single-portion scan now goes through the queue too, so a kill there re-asks its remainder. - Fix: the reuse wrapper wrapped only `run_batch`, so since 7.8 every portioned query bypassed the graph-reuse cache and its source-root normalization. `run_batch_once` is wrapped too. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c1a689f4b3
commit
1b28465a61
@@ -87,3 +87,37 @@ def test_fresh_missing_census_cannot_borrow_a_cached_query_census(tmp_path):
|
||||
assert "q" in result.run_batch("taint", {"q": {"file": "a.js"}})
|
||||
answer = result.run_batch("taint", {"q": {"file": "a.js"}, "fresh": {"file": "a.js", "callDepth": 3}})
|
||||
assert "q" in answer and "fresh" not in answer
|
||||
|
||||
|
||||
def test_the_single_attempt_path_is_reused_and_normalized_too(tmp_path):
|
||||
"""The portioner asks `run_batch_once`; wrapping only `run_batch` let every portioned query skip reuse."""
|
||||
from openultrasast.cpg.artifact import GraphArtifact, GraphCensus, GraphIdentity
|
||||
from openultrasast.cpg.backend import TIMING
|
||||
|
||||
identity = GraphIdentity(
|
||||
"source", "declarations", "exclude", "repository", "javascript", "engine", "frontend", "version", ("dataflowOss",), ()
|
||||
)
|
||||
artifact = GraphArtifact(identity, "graph-bytes", 10, GraphCensus(1, 1, 1), "complete", (), "/old", ("a.js",))
|
||||
cache = ArtifactCache(tmp_path / "cache", max_bytes=100000)
|
||||
semantics = SemanticKeys("facts", "queries", "config", "ranking", "admission", "disabled", "empty", "advisory")
|
||||
wrapper = ReusingBackend(JoernBackend(), cache, semantics, declarations="d", exclusions="e")
|
||||
census = [{"files": 1, "methods": 1, "file_names": ["a.js"]}]
|
||||
once_calls = []
|
||||
|
||||
def once(kind, requests):
|
||||
once_calls.append(dict(requests))
|
||||
return {
|
||||
**{rid: [{"file": "/old/a.js"}] for rid in requests},
|
||||
"__census__": census,
|
||||
TIMING: [{"id": rid, "ms": 5.0} for rid in requests],
|
||||
}
|
||||
|
||||
graph = CpgResult(tmp_path / "graph", lambda *_: None, lambda k, r: None, run_batch_once=once)
|
||||
result = wrapper._answers(graph, artifact, ExecutionBudget(time.monotonic() + 5, 0.2))
|
||||
assert result.run_batch_once is not None
|
||||
first = result.run_batch_once("taint", {"q": {"file": "a.js"}})
|
||||
assert first["q"] == [{"file": "a.js"}], "the source root was not stripped on the single-attempt path"
|
||||
assert first[TIMING] == [{"id": "q", "ms": 5.0}]
|
||||
second = result.run_batch_once("taint", {"q": {"file": "a.js"}})
|
||||
assert second["q"] == [{"file": "a.js"}] and len(once_calls) == 1, "the single-attempt path bypassed the cache"
|
||||
assert TIMING not in second, "a cached answer cost the engine nothing and must report no time"
|
||||
|
||||
Reference in New Issue
Block a user