Files
reverse-engineering-anything/src/adb/AdbVersionProbe.test.ts
T
01788bac86 fix(android): name the JADX deadline and recover apktool decode (#6024)
* fix(android): name the JADX deadline and recover apktool decode

JADX operation timeouts now name REA_JADX_OPERATION_TIMEOUT_MS, the
effective milliseconds, the 1..2147483647 range, and that a change applies
on the next process start. Apktool decode accepts decode_timeout_ms,
omitted means 600000, and a timeout names that key. ADB deadlines and
apktool and Java version probes stay fixed and say there is no runtime
override.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): derive capture recovery from the fixed allowance

Main now stores a fixed allowance instead of a prebuilt remediation
string. Apktool and adb capture refusals keep the no-runtime-override
sentence in that allowance name, including that decode_timeout_ms does
not raise the apktool output cap.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(apktool): observe a real decode deadline and process cleanup

A hanging interpreter launcher and its pipe-holding child stay alive
until decode_timeout_ms elapses. The provider then reports
provider_timeout with completed cleanup, and both processes are gone.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 00:31:43 +08:00

63 lines
2.1 KiB
TypeScript

import { expect, it, vi } from "vitest";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { AnalysisTimeoutError } from "../domain/analysisErrorCore.js";
import { execFileOutput } from "../process/ExecFileOutput.js";
import { inspectAdbClient } from "./AdbConfiguration.js";
vi.mock("../process/ExecFileOutput.js", async (importOriginal) => ({
...(await importOriginal<typeof import("../process/ExecFileOutput.js")>()),
execFileOutput: vi.fn(),
}));
const selection = {
binary: "/host/adb",
pathSource: "environment",
} as const;
it("names the adb version-probe deadline and says it has no runtime override", async () => {
vi.mocked(execFileOutput).mockRejectedValueOnce(
Object.assign(new Error("deadline"), {
code: "ETIMEDOUT",
stdout: "",
stderr: "",
signal: null,
killed: true,
}),
);
const failure = await inspectAdbClient(selection).catch(
(cause: unknown) => cause,
);
expect(failure).toBeInstanceOf(AnalysisTimeoutError);
const projected = projectAnalysisError(failure as AnalysisTimeoutError);
expect(projected).toMatchObject({
code: "provider_timeout",
details: { timeout_ms: 10_000 },
});
expect(projected.message).toContain("10000 ms");
expect(projected.message).toContain("no runtime override");
expect(projected.remediation.action).toContain("no runtime override");
});
it("names the adb version-output cap and says it has no runtime override", async () => {
vi.mocked(execFileOutput).mockRejectedValueOnce(
Object.assign(new Error("too much"), {
code: "ERR_CHILD_PROCESS_STDIO_MAXBUFFER",
stdout: "",
stderr: "",
signal: null,
killed: false,
outputTruncated: true,
}),
);
const failure = await inspectAdbClient(selection).catch(
(cause: unknown) => cause,
);
const projected = projectAnalysisError(
failure as Parameters<typeof projectAnalysisError>[0],
);
expect(projected.message).toContain("65536-byte");
expect(projected.remediation.action).toContain("65536 bytes");
expect(projected.remediation.action).toContain("no runtime override");
});