runs: list survives a damaged run record (#1551)
Row 82 round 2, owner Rocko, candidate manifest dbf36e92 on 876f1ffe.
Approved by Filbert (27650); Sage's gate green 02:05-02:09Z.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -72,7 +72,10 @@ printed them.
|
||||
|
||||
`list` and `show` print exactly what they printed before this package
|
||||
existed, for any data root with no link out of it, no run document that
|
||||
is JSON but not an object, and no unreadable directory.
|
||||
is JSON but not an object, no `result.json` with a field of the wrong
|
||||
type (a `status` or `taskId` that isn't a string, or a `workspace` or
|
||||
`session` that is neither a string nor `null`), and no unreadable
|
||||
directory.
|
||||
`agents/rocko/work/queue-56/byte-check.sh` checks that byte for byte
|
||||
against a seeded data root. Where those conditions don't hold, the
|
||||
output changes on purpose:
|
||||
@@ -82,6 +85,7 @@ output changes on purpose:
|
||||
| run directory or `result.json` linked out | read through the link | `list`: `unknown`; `show`: refuses (run directory) or `result.json: (missing or unreadable)` |
|
||||
| `runs/` linked out | read through the link | `list` and `show` refuse, exit 4 |
|
||||
| `result.json` is `5` or `[]` | `list` crashed; `show` printed `undefined` fields | `unknown`; `(missing or unreadable)` |
|
||||
| `result.json` is an object whose `status` or `taskId` isn't a string, or whose `workspace` or `session` is neither a string nor `null` (`{}`, a numeric `status`, a `null` `taskId`) | `list` crashed on a `status` or `taskId` that isn't a string, hiding every run after it, and printed a `workspace` or `session` that is neither a string nor `null` through `String` | `list`: `unknown` for the status, `-` for each other field, and every later run still lists; `show` as before |
|
||||
| `task.json` or `mission.json` is JSON but not an object | `show` printed its snapshot line | snapshot line omitted |
|
||||
| run is a regular file | `show` crashed | `run not found`, exit 4 |
|
||||
| `runs/` unreadable | `list` printed nothing | refuses, exit 4 |
|
||||
|
||||
@@ -32,6 +32,34 @@ test("list prints each run in the established format", (t) => {
|
||||
`${B} unknown task=- ws=- session=-\n`);
|
||||
});
|
||||
|
||||
test("list prints a damaged result.json as unknown and keeps listing the runs after it", (t) => {
|
||||
const { dataRoot } = scratch(t);
|
||||
const M = "r-20260101T000050Z-mmmmmm";
|
||||
write(path.join(dataRoot, "runs", A, "result.json"), { ...RESULT, workspace: "ws1", session: "s1" });
|
||||
write(path.join(dataRoot, "runs", M, "result.json"), {});
|
||||
write(path.join(dataRoot, "runs", B, "result.json"), { ...RESULT, taskId: "t-two", workspace: ":run" });
|
||||
const out = task(t, dataRoot, "list");
|
||||
assert.equal(out.status, 0, out.stderr);
|
||||
assert.equal(out.stdout,
|
||||
`${A} succeeded task=t-one ws=ws1 session=s1\n` +
|
||||
`${M} unknown task=- ws=- session=-\n` +
|
||||
`${B} succeeded task=t-two ws=:run session=-\n`);
|
||||
});
|
||||
|
||||
test("list prints each result field that isn't a string as unknown or -", (t) => {
|
||||
const { dataRoot } = scratch(t);
|
||||
const runs = [
|
||||
["r-20260101T000000Z-status", { status: 5 }, "unknown task=t-one ws=- session=-"],
|
||||
["r-20260101T000001Z-taskid", { taskId: null }, "succeeded task=- ws=- session=-"],
|
||||
["r-20260101T000002Z-worksp", { workspace: 7 }, "succeeded task=t-one ws=- session=-"],
|
||||
["r-20260101T000003Z-sessin", { session: { name: "s1" } }, "succeeded task=t-one ws=- session=-"],
|
||||
];
|
||||
for (const [runId, damage] of runs) write(path.join(dataRoot, "runs", runId, "result.json"), { ...RESULT, ...damage });
|
||||
const out = task(t, dataRoot, "list");
|
||||
assert.equal(out.status, 0, out.stderr);
|
||||
assert.equal(out.stdout, runs.map(([runId, , line]) => `${runId} ${line}\n`).join(""));
|
||||
});
|
||||
|
||||
test("show prints the run in the established format", (t) => {
|
||||
const { dataRoot } = scratch(t);
|
||||
const dir = path.join(dataRoot, "runs", A);
|
||||
|
||||
@@ -470,18 +470,19 @@ function readRuns(read) {
|
||||
function listRuns() {
|
||||
const resolved = loadConfig();
|
||||
for (const { runId, result } of readRuns(() => listRunRecords(resolved.dataRoot))) {
|
||||
// An incomplete or unreadable run record (result null) reports as unknown.
|
||||
// An incomplete or unreadable run record (result null) reports as unknown,
|
||||
// and so does each field of a damaged one that isn't a string.
|
||||
let status = "unknown";
|
||||
let taskId = "-";
|
||||
let workspace = "-";
|
||||
let session = "-";
|
||||
if (result) {
|
||||
status = result.status;
|
||||
taskId = result.taskId;
|
||||
workspace = result.workspace ?? "-";
|
||||
session = result.session ?? "-";
|
||||
if (typeof result.status === "string") status = result.status;
|
||||
if (typeof result.taskId === "string") taskId = result.taskId;
|
||||
if (typeof result.workspace === "string") workspace = result.workspace;
|
||||
if (typeof result.session === "string") session = result.session;
|
||||
}
|
||||
process.stdout.write(`${runId} ${status.padEnd(9)} task=${taskId.padEnd(18)} ws=${String(workspace).padEnd(10)} session=${session}\n`);
|
||||
process.stdout.write(`${runId} ${status.padEnd(9)} task=${taskId.padEnd(18)} ws=${workspace.padEnd(10)} session=${session}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user