mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
fix(scripts): remove the ADB verifier's pushed probe file from the device (#5256)
* fix(scripts): remove the ADB verifier's pushed probe file from the device The verifier pushed `/data/local/tmp/rea-verify-<timestamp>.txt` for its transfer roundtrip but never deleted it, so every successful run left a probe behind while reporting that all checks passed. After a successful no-overwrite push, the verifier now removes that exact destination with the provider-reported adb client and confirms its absence through `list_adb_directory`. Removal runs even when the pull fails, and a removal failure is reported as a failed check instead of a pass. `pull_adb_file` still retains device originals. Fixes #5190 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(scripts): cover ADB probe cleanup after pull failure and leftover probes Add verifier cases where the pull returns an error or throws after a successful push, and where `adb shell rm` exits 0 but the listing still shows the probe. Pull failures must still remove the probe, and a leftover probe must fail the run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
c4b7a2e003
commit
81b94cebec
+83
-24
@@ -1,12 +1,15 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { mkdtemp, readFile, rm, stat } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { join, posix } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
import { AdbDeviceAnalysisService } from "../dist/application/adb/AdbDeviceAnalysisService.js";
|
||||
import { createAdbDeviceAnalysisProvider } from "../dist/composition/adb.js";
|
||||
import { closeVerifierResources } from "./lib/verifier-cleanup.mjs";
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
const options = parseArguments(process.argv.slice(2));
|
||||
if (options.help) {
|
||||
process.stdout.write(
|
||||
@@ -40,6 +43,80 @@ const run = async (operation, input) => {
|
||||
return result.value.normalized_result;
|
||||
};
|
||||
|
||||
// Remove the verifier's own transfer probe with the provider-reported adb
|
||||
// client, then confirm through the directory listing that it is gone.
|
||||
const removeDeviceProbe = async (binary, serial, devicePath) => {
|
||||
const name = "verifier transfer probe removed";
|
||||
if (typeof binary !== "string" || binary === "") {
|
||||
check(name, false, `${devicePath}: adb client path unavailable`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await execFileAsync(
|
||||
binary,
|
||||
["-s", serial, "shell", "rm", "--", devicePath],
|
||||
{
|
||||
timeout: 30_000,
|
||||
},
|
||||
);
|
||||
} catch (cause) {
|
||||
check(name, false, `${devicePath}: ${formatFailure(cause)}`);
|
||||
return;
|
||||
}
|
||||
const listing = await run("list_adb_directory", {
|
||||
serial,
|
||||
device_path: posix.dirname(devicePath),
|
||||
});
|
||||
if (listing !== null)
|
||||
check(
|
||||
name,
|
||||
listing.coverage === "complete" &&
|
||||
!listing.entries.some(
|
||||
(entry) => entry.name === posix.basename(devicePath),
|
||||
),
|
||||
devicePath,
|
||||
);
|
||||
};
|
||||
|
||||
const verifyTransferRoundtrip = async ({
|
||||
adbBinary,
|
||||
serial,
|
||||
payload,
|
||||
devicePath,
|
||||
outputDirectory,
|
||||
}) => {
|
||||
const pushed = await run("push_adb_file", {
|
||||
serial,
|
||||
local_path: payload,
|
||||
device_path: devicePath,
|
||||
overwrite: false,
|
||||
});
|
||||
if (pushed === null) return;
|
||||
// A successful no-overwrite push proves the verifier created this exact
|
||||
// destination; pull_adb_file deliberately retains device originals.
|
||||
try {
|
||||
check(
|
||||
"push reports matching device-side digest",
|
||||
pushed.device_digest_source === "device_sha256sum" &&
|
||||
pushed.device_sha256 === pushed.sha256,
|
||||
`${pushed.bytes} bytes`,
|
||||
);
|
||||
const pulled = await run("pull_adb_file", {
|
||||
serial,
|
||||
device_path: devicePath,
|
||||
output_directory: outputDirectory,
|
||||
});
|
||||
if (pulled !== null)
|
||||
check(
|
||||
"pulled file digest matches the pushed digest",
|
||||
pulled.sha256 === pushed.sha256,
|
||||
`${pulled.bytes} bytes`,
|
||||
);
|
||||
} finally {
|
||||
await removeDeviceProbe(adbBinary, serial, devicePath);
|
||||
}
|
||||
};
|
||||
|
||||
let verifierFailed = false;
|
||||
let verifierFailure;
|
||||
try {
|
||||
@@ -245,31 +322,13 @@ try {
|
||||
fs.writeFile(payload, payloadBytes),
|
||||
);
|
||||
const deviceTarget = `/data/local/tmp/rea-verify-${Date.now()}.txt`;
|
||||
const pushed = await run("push_adb_file", {
|
||||
await verifyTransferRoundtrip({
|
||||
adbBinary: client?.client.binary_path,
|
||||
serial,
|
||||
local_path: payload,
|
||||
device_path: deviceTarget,
|
||||
overwrite: false,
|
||||
payload,
|
||||
devicePath: deviceTarget,
|
||||
outputDirectory: transferRoot,
|
||||
});
|
||||
if (pushed !== null) {
|
||||
check(
|
||||
"push reports matching device-side digest",
|
||||
pushed.device_digest_source === "device_sha256sum" &&
|
||||
pushed.device_sha256 === pushed.sha256,
|
||||
`${pushed.bytes} bytes`,
|
||||
);
|
||||
const pulled = await run("pull_adb_file", {
|
||||
serial,
|
||||
device_path: deviceTarget,
|
||||
output_directory: transferRoot,
|
||||
});
|
||||
if (pulled !== null)
|
||||
check(
|
||||
"pulled file digest matches the pushed digest",
|
||||
pulled.sha256 === pushed.sha256,
|
||||
`${pulled.bytes} bytes`,
|
||||
);
|
||||
}
|
||||
const screenRoot = await mkdtemp(join(tmpdir(), "rea-adb-screen-"));
|
||||
try {
|
||||
const screen = await run("capture_adb_screen", {
|
||||
|
||||
Reference in New Issue
Block a user