mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 00:07:18 +00:00
* test: focus configuration diagnostics on their owners Preserve shape errors, selected paths, recovery guidance, and unchanged-file behavior across parser, setup, and uninstall boundaries. * test: focus artifact and evidence checks on behavior Retain format, identity, malformed-input, and cleanup coverage while removing fixed prose and closing the admitted test source. * refactor(debugger): use configured session admission limits * test: focus evidence and diagnostics on behavior * fix(test): restore verifier export and formatting * test(config): verify debugger limit ranges * test(rizin): keep fixture executable authoritative * test(rizin): isolate debugger fixture environment
167 lines
5.4 KiB
TypeScript
167 lines
5.4 KiB
TypeScript
import { readFile, rm, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { expect, onTestFinished } from "vitest";
|
|
import { cliTest } from "../support/cli/cliFixture.js";
|
|
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
|
import {
|
|
ESP32C3_APP_SEGMENTS,
|
|
ESP32C3_BOOTLOADER_SEGMENTS,
|
|
espImage,
|
|
} from "../fixtures/espImage.js";
|
|
import {
|
|
espFlashDump,
|
|
otaData,
|
|
otaRecord,
|
|
} from "../../src/domain/firmware/espFlash.fixture.js";
|
|
import { parseEvidence } from "../../src/domain/evidence.js";
|
|
import { artifactInspectionResultSchema } from "../../src/domain/artifactInspection.js";
|
|
import {
|
|
artifactExtractionResultSchema,
|
|
artifactInventoryResultSchema,
|
|
} from "../../src/domain/artifactGraph.js";
|
|
|
|
const rootMetadata = (json: unknown) => {
|
|
const graph = artifactInventoryResultSchema.parse(
|
|
artifactInspectionResultSchema.parse(parseEvidence(json).normalized_result)
|
|
.substeps[0]?.evidence.normalized_result,
|
|
);
|
|
return {
|
|
graph,
|
|
root: graph.occurrences.find(({ logical_path }) => logical_path === ".")
|
|
?.format_metadata,
|
|
};
|
|
};
|
|
|
|
cliTest(
|
|
"inventories and extracts a whole-flash dump through the compiled CLI",
|
|
async ({ cli }) => {
|
|
const directory = await createTestTempDirectory("rea-esp-flash-cli-");
|
|
const source = join(directory, "flash.bin");
|
|
const app = espImage({ segments: ESP32C3_APP_SEGMENTS });
|
|
const dump = espFlashDump({
|
|
bootloader: {
|
|
at: 0,
|
|
bytes: espImage({ segments: ESP32C3_BOOTLOADER_SEGMENTS }),
|
|
},
|
|
parts: [
|
|
{ at: 0xd000, bytes: otaData(otaRecord({ seq: 2 })) },
|
|
{ at: 0x2_0000, bytes: app },
|
|
{ at: 0x3_0000, bytes: app },
|
|
],
|
|
});
|
|
await writeFile(source, dump);
|
|
const inspected = await cli.run({
|
|
arguments: ["inspect-artifact", source, "--json"],
|
|
});
|
|
expect(inspected.exitCode, inspected.stdout + inspected.stderr).toBe(0);
|
|
const { graph, root } = rootMetadata(inspected.json);
|
|
expect(graph.manifest.root_format).toBe("esp-flash-image");
|
|
expect(root).toMatchObject({
|
|
kind: "esp-flash-image",
|
|
chip: { target: "esp32c3" },
|
|
partition_table: { method: "default", md5: { status: "valid" } },
|
|
boot_selection: {
|
|
basis: "otadata",
|
|
slot: 1,
|
|
partition_index: 5,
|
|
running_partition: "unknown",
|
|
},
|
|
});
|
|
const extracted = await cli.run({
|
|
arguments: ["extract-artifact", source, "--json"],
|
|
environment: { TMPDIR: directory, TMP: directory, TEMP: directory },
|
|
});
|
|
expect(extracted.exitCode, extracted.stdout + extracted.stderr).toBe(0);
|
|
const result = artifactExtractionResultSchema.parse(
|
|
parseEvidence(extracted.json).normalized_result,
|
|
);
|
|
onTestFinished(() =>
|
|
rm(result.output_root, { recursive: true, force: true }),
|
|
);
|
|
expect(
|
|
Buffer.compare(
|
|
await readFile(join(result.output_root, "partitions/ota_1.bin")),
|
|
dump.subarray(0x3_0000, 0x4_0000),
|
|
),
|
|
).toBe(0);
|
|
},
|
|
);
|
|
|
|
cliTest(
|
|
"reads a dump from a caller-selected flash offset and refuses unpaired inputs",
|
|
async ({ cli }) => {
|
|
const directory = await createTestTempDirectory(
|
|
"rea-esp-flash-cli-origin-",
|
|
);
|
|
const source = join(directory, "from-0x1000.bin");
|
|
const esp32 = espImage({
|
|
segments: ESP32C3_BOOTLOADER_SEGMENTS,
|
|
chipId: 0x0000,
|
|
});
|
|
await writeFile(
|
|
source,
|
|
espFlashDump({ bootloader: { at: 0x1000, bytes: esp32 } }).subarray(
|
|
0x1000,
|
|
),
|
|
);
|
|
const unpaired = await cli.run({
|
|
arguments: [
|
|
"inspect-artifact",
|
|
source,
|
|
"--flash-offset",
|
|
"0x1000",
|
|
"--json",
|
|
],
|
|
});
|
|
expect(unpaired.exitCode).not.toBe(0);
|
|
expect(unpaired.stdout + unpaired.stderr).toMatch(
|
|
/flash_offset.*only with format=esp-flash-image/iu,
|
|
);
|
|
// Without the format, the bootloader is read as one ESP image, and the
|
|
// table at file offset 0x7000 says how to reopen the dump.
|
|
const automatic = await cli.run({
|
|
arguments: ["inspect-artifact", source, "--json"],
|
|
});
|
|
expect(automatic.exitCode, automatic.stdout + automatic.stderr).toBe(0);
|
|
const guessed = rootMetadata(automatic.json);
|
|
expect(guessed.graph.manifest.root_format).toBe("esp-image");
|
|
expect(guessed.root).toMatchObject({
|
|
flash_dump: { flash_offset: 0x1000, table_file_offset: 0x7000 },
|
|
});
|
|
const inspection = artifactInspectionResultSchema.parse(
|
|
parseEvidence(automatic.json).normalized_result,
|
|
);
|
|
expect(inspection.next_probes).toEqual([
|
|
expect.objectContaining({
|
|
operation: "open_binary",
|
|
authority: "artifact-bytes",
|
|
rationale: expect.stringMatching(
|
|
/esp-flash-image.*flash_offset 0x1000.*0x7000/iu,
|
|
),
|
|
}),
|
|
]);
|
|
expect(guessed.graph.limitations).toContainEqual(
|
|
expect.stringMatching(
|
|
/flash dump.*0x1000.*0x7000.*0x8000.*esp-flash-image.*0x1000/iu,
|
|
),
|
|
);
|
|
const inspected = await cli.run({
|
|
arguments: [
|
|
"inspect-artifact",
|
|
source,
|
|
"--target-format",
|
|
"esp-flash-image",
|
|
"--flash-offset",
|
|
"0x1000",
|
|
"--json",
|
|
],
|
|
});
|
|
expect(inspected.exitCode, inspected.stdout + inspected.stderr).toBe(0);
|
|
expect(rootMetadata(inspected.json).root).toMatchObject({
|
|
flash_offset: { value: 0x1000, source: "caller" },
|
|
chip: { target: "esp32" },
|
|
bootloader: { flash_address: 0x1000 },
|
|
});
|
|
},
|
|
);
|