feat(javascript): discover semantic call literals in feature traces (#7840)
* feat(javascript): discover semantic call literals in feature traces * fix(javascript): bound retained call literals by transfer capacity * test(javascript): align feature no-match diagnostic
This commit is contained in:
1 parent
685f6db960
commit
f9e7571a3d
20 files changed
+681
-15
No files matched your search
@@ -31,6 +31,99 @@ import { getterExpansionSource } from "../../../tests/fixtures/javascriptGetterE
|
||||
|
||||
const SHA256 = "a".repeat(64);
|
||||
|
||||
it("retains direct call literals and resolves literal queries to their call site", () => {
|
||||
const source =
|
||||
'api.rpc("proc_0", 7, false, null, dynamic, ...values, `fixed`, -3);';
|
||||
const graph = graphFor(source);
|
||||
const call = graph.nodes.find(({ kind }) => kind === "call-site");
|
||||
const argumentsValue = call?.properties.arguments;
|
||||
expect(argumentsValue).toEqual([
|
||||
expect.objectContaining({
|
||||
index: 0,
|
||||
value: "proc_0",
|
||||
source_range: expect.any(Object),
|
||||
}),
|
||||
expect.objectContaining({ index: 1, value: 7 }),
|
||||
expect.objectContaining({ index: 2, value: false }),
|
||||
expect.objectContaining({ index: 3, value: null }),
|
||||
expect.objectContaining({ index: 6, value: "fixed" }),
|
||||
expect.objectContaining({ index: 7, value: -3 }),
|
||||
]);
|
||||
if (call === undefined) throw new Error("Expected call site");
|
||||
const trace = queryJavaScriptSemanticGraph(
|
||||
graph,
|
||||
javaScriptSemanticQueryInputSchema.parse({
|
||||
seed: { kind: "literal", value: "proc_0" },
|
||||
direction: "forward-influence",
|
||||
}),
|
||||
);
|
||||
expect(trace.seed_node_ids).toContain(call.node_id);
|
||||
});
|
||||
|
||||
it("reports the primitive byte bound when a direct argument is too large", () => {
|
||||
const source = `rpc(${JSON.stringify("x".repeat(175_000))});`;
|
||||
const ir = analyzeJavaScriptSemantics(source);
|
||||
expect(ir.coverage.resourceLimits).toContain("primitive-bytes");
|
||||
const graph = graphFor(source, ir);
|
||||
const call = graph.nodes.find(({ kind }) => kind === "call-site");
|
||||
expect(call?.properties.arguments).toBeUndefined();
|
||||
expect(graph.coverage.status).not.toBe("complete");
|
||||
const unknown = graph.unknowns.find(
|
||||
(entry) =>
|
||||
entry.node_id === call?.node_id && entry.reason === "resource-limit",
|
||||
);
|
||||
expect(unknown?.detail).toMatch(/primitive string-byte budget exceeded/i);
|
||||
expect(
|
||||
graph.evidence_contexts.find(
|
||||
(entry) => entry.context_id === unknown?.evidence.context_id,
|
||||
),
|
||||
).toMatchObject({
|
||||
coverage: {
|
||||
limits: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "javascript_semantic_primitive_bytes",
|
||||
}),
|
||||
]),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps a large call's graph within the worker record limit and reports omitted arguments", () => {
|
||||
const value = JSON.stringify("x".repeat(140_000));
|
||||
const source = `rpc(${Array.from({ length: 64 }, () => value).join(",")});`;
|
||||
const graph = graphFor(source);
|
||||
const call = graph.nodes.find(({ kind }) => kind === "call-site");
|
||||
if (call === undefined) throw new Error("Expected call site");
|
||||
const values = call.properties.arguments;
|
||||
expect(Array.isArray(values)).toBe(true);
|
||||
if (!Array.isArray(values)) throw new Error("Expected retained arguments");
|
||||
expect(values.length).toBeGreaterThan(0);
|
||||
expect(values.length).toBeLessThan(64);
|
||||
expect(
|
||||
Buffer.byteLength(`${JSON.stringify({ kind: "node", value: call })}\n`),
|
||||
).toBeLessThanOrEqual(8 * 1024 * 1024);
|
||||
const unknown = graph.unknowns.find(
|
||||
(entry) =>
|
||||
entry.node_id === call.node_id &&
|
||||
entry.detail.includes("worker transfer record ceiling"),
|
||||
);
|
||||
expect(unknown).toMatchObject({ reason: "resource-limit" });
|
||||
expect(
|
||||
graph.evidence_contexts.find(
|
||||
(entry) => entry.context_id === unknown?.evidence.context_id,
|
||||
),
|
||||
).toMatchObject({
|
||||
coverage: {
|
||||
limits: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "javascript_analysis_transfer_record_bytes",
|
||||
value: 8 * 1024 * 1024,
|
||||
}),
|
||||
]),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("projects bounded alias selection as a resource-limit unknown", () => {
|
||||
const source = aliasSelectionBudgetSource();
|
||||
const ir = analyzeJavaScriptSemantics(source);
|
||||
|
||||
Reference in new issue
Block a user