96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
createAnalysisExecution,
|
|
type AnalysisOperationPort,
|
|
} from "../AnalysisProvider.js";
|
|
import { createAnalysisExecutionEvidence } from "../../domain/analysisObservation.js";
|
|
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
|
|
import { err, ok } from "../../domain/result.js";
|
|
import { readNativeCallRoutes } from "./NativeCallRoutes.js";
|
|
import { traceNativeValues } from "./NativeValueTrace.js";
|
|
import { inspectNativeDispatch } from "./NativeDispatchMetadataInspection.js";
|
|
|
|
import { createAnalysisProfile } from "../../domain/analysisProfile.js";
|
|
import { createEvidence } from "../../domain/evidence.js";
|
|
|
|
const provider = { id: "fixture", name: "Fixture", version: "1" };
|
|
const subject = {
|
|
path: "/fixture",
|
|
sha256: "a".repeat(64),
|
|
format: "elf" as const,
|
|
architecture: "x86_64" as const,
|
|
};
|
|
const source = createEvidence(subject, provider, {
|
|
operation: "list_names",
|
|
parameters: {},
|
|
result: [{ address: "0x1000", value: "entry" }],
|
|
});
|
|
const observation = createAnalysisExecution(
|
|
{ malformed: "provider facts" },
|
|
provider,
|
|
{
|
|
subject,
|
|
analysisProfile: createAnalysisProfile(provider, { language: "x86:LE:64" }),
|
|
sourceEvidence: [source],
|
|
rawResult: { output: "original output" },
|
|
limitations: ["partial provider coverage"],
|
|
locations: [],
|
|
},
|
|
);
|
|
|
|
describe("native reader validation Evidence", () => {
|
|
it.each(["references", "callees", "dossier", "binary", "symbols"] as const)(
|
|
"retains the original %s observation on a typed validation failure",
|
|
async (reader) => {
|
|
let operation = "";
|
|
let input: unknown;
|
|
const analysis: AnalysisOperationPort = {
|
|
execute: async (name, parameters) => {
|
|
if (
|
|
reader === "symbols" &&
|
|
name === "inspect_native_dispatch_metadata"
|
|
)
|
|
return err(
|
|
new AnalysisCapabilityUnavailableError(
|
|
"fixture",
|
|
name,
|
|
"unsupported",
|
|
),
|
|
);
|
|
operation = name;
|
|
input = parameters;
|
|
return ok(
|
|
reader === "callees" && name === "procedure_references"
|
|
? createAnalysisExecution(
|
|
{
|
|
reference_kinds_available: false,
|
|
references: [],
|
|
unresolved_calls: [],
|
|
},
|
|
provider,
|
|
)
|
|
: observation,
|
|
);
|
|
},
|
|
};
|
|
const result =
|
|
reader === "references" || reader === "callees"
|
|
? (await readNativeCallRoutes(analysis, "0x1000")).outcome
|
|
: reader === "dossier"
|
|
? await traceNativeValues(analysis, { procedure: "0x1000" })
|
|
: await inspectNativeDispatch(analysis, 10);
|
|
expect(result.ok).toBe(false);
|
|
if (result.ok) return;
|
|
expect(result.error._tag).toBe("AnalysisOutputError");
|
|
expect(result.error.partialObservation).toEqual(
|
|
createAnalysisExecutionEvidence(
|
|
operation,
|
|
input,
|
|
observation,
|
|
"observed",
|
|
),
|
|
);
|
|
},
|
|
);
|
|
});
|