mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 09:52:27 +00:00
test(kuna): scope short deadlines to hanging decompile work
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
1 parent
2127cff82d
commit
04042cf540
3 files changed
+97
-26
No files matched your search
@@ -32,7 +32,7 @@ it("runs a cold independent request without starting a project export", async ()
|
||||
{
|
||||
REA_KUNA_COMMAND: kuna,
|
||||
REA_KUNA_CACHE_DIR: join(root, "cache"),
|
||||
REA_KUNA_TIMEOUT_MS: "300",
|
||||
REA_KUNA_TIMEOUT_MS: "10000",
|
||||
},
|
||||
{ platform: process.platform },
|
||||
);
|
||||
@@ -67,6 +67,11 @@ it("runs a cold independent request without starting a project export", async ()
|
||||
functions: FUNCTIONS,
|
||||
decompile: "hang",
|
||||
});
|
||||
await call("update_analysis_settings", {
|
||||
changes: [
|
||||
{ setting: "kuna.function_timeout_ms", action: "set", value: 300 },
|
||||
],
|
||||
});
|
||||
const timeout = await harness.client.callTool({
|
||||
name: "procedure_pseudo_code",
|
||||
arguments: { procedure: "main", analysis: "independent_fresh" },
|
||||
@@ -84,6 +89,7 @@ it("runs a cold independent request without starting a project export", async ()
|
||||
limit: {
|
||||
setting: "kuna.function_timeout_ms",
|
||||
effective_value: 300,
|
||||
source: "runtime",
|
||||
update_mode: "runtime",
|
||||
pending_restart: false,
|
||||
minimum: 1,
|
||||
@@ -96,6 +102,9 @@ it("runs a cold independent request without starting a project export", async ()
|
||||
({ argv }) => argv[0] === "decompile-project",
|
||||
),
|
||||
).toHaveLength(0);
|
||||
await call("update_analysis_settings", {
|
||||
changes: [{ setting: "kuna.function_timeout_ms", action: "reset" }],
|
||||
});
|
||||
await setFakeKunaBehavior(kuna, { functions: FUNCTIONS });
|
||||
await call("procedure_assembly", { procedure: "main" });
|
||||
expect(
|
||||
@@ -231,7 +240,7 @@ it("retains the independent run slot until an unproven stop is resolved", async
|
||||
{
|
||||
REA_KUNA_COMMAND: kuna,
|
||||
REA_KUNA_CACHE_DIR: join(root, "cache"),
|
||||
REA_KUNA_TIMEOUT_MS: "300",
|
||||
REA_KUNA_TIMEOUT_MS: "10000",
|
||||
},
|
||||
{
|
||||
platform: process.platform,
|
||||
@@ -266,6 +275,15 @@ it("retains the independent run slot until an unproven stop is resolved", async
|
||||
expect(
|
||||
(await call("procedure_assembly", { procedure: "broken" })).isError,
|
||||
).not.toBe(true);
|
||||
expect(
|
||||
(
|
||||
await call("update_analysis_settings", {
|
||||
changes: [
|
||||
{ setting: "kuna.function_timeout_ms", action: "set", value: 300 },
|
||||
],
|
||||
})
|
||||
).isError,
|
||||
).not.toBe(true);
|
||||
const first = await call("procedure_pseudo_code", {
|
||||
procedure: "broken",
|
||||
analysis: "independent_fresh",
|
||||
@@ -314,6 +332,13 @@ it("retains the independent run slot until an unproven stop is resolved", async
|
||||
expect((await call("close_binary", {})).isError).toBe(true);
|
||||
unproven.release();
|
||||
expect((await call("close_binary", {})).isError).not.toBe(true);
|
||||
expect(
|
||||
(
|
||||
await call("update_analysis_settings", {
|
||||
changes: [{ setting: "kuna.function_timeout_ms", action: "reset" }],
|
||||
})
|
||||
).isError,
|
||||
).not.toBe(true);
|
||||
await setFakeKunaBehavior(kuna, { functions: FUNCTIONS });
|
||||
expect(
|
||||
(await call("open_binary", { path: target, provider_id: "kuna" }))
|
||||
|
||||
@@ -1032,25 +1032,34 @@ it("keeps reporting a failed close and succeeds once a retry proves the stop", a
|
||||
const { open } = await session(
|
||||
"rea-kuna-close-retry-",
|
||||
{ project: "hang", decompile: "hang" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "300" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "10000" },
|
||||
unproven.launcher,
|
||||
);
|
||||
const client = open();
|
||||
|
||||
expect(
|
||||
await client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
).toMatchObject({ ok: false, error: { cleanupIncomplete: true } });
|
||||
const first = await client.close();
|
||||
expect(first).toMatchObject({
|
||||
ok: false,
|
||||
error: { diagnostics: { reason: "decompile stop unproven" } },
|
||||
});
|
||||
// A retry that still cannot prove the stop keeps failing.
|
||||
expect((await client.close()).ok).toBe(false);
|
||||
try {
|
||||
expect((await client.execute("list_procedures", {})).ok).toBe(true);
|
||||
expect(
|
||||
await runWithAnalysisOperationSnapshot(
|
||||
{ revision: 1, overrides: { "kuna.function_timeout_ms": 300 } },
|
||||
() => client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
),
|
||||
).toMatchObject({ ok: false, error: { cleanupIncomplete: true } });
|
||||
const first = await client.close();
|
||||
expect(first).toMatchObject({
|
||||
ok: false,
|
||||
error: { diagnostics: { reason: "decompile stop unproven" } },
|
||||
});
|
||||
// A retry that still cannot prove the stop keeps failing.
|
||||
expect((await client.close()).ok).toBe(false);
|
||||
|
||||
unproven.release();
|
||||
expect(await client.close()).toEqual({ ok: true, value: null });
|
||||
expect(await client.close()).toEqual({ ok: true, value: null });
|
||||
unproven.release();
|
||||
expect(await client.close()).toEqual({ ok: true, value: null });
|
||||
expect(await client.close()).toEqual({ ok: true, value: null });
|
||||
} finally {
|
||||
unproven.release();
|
||||
expect((await client.close()).ok).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("reports an abandoned export's unproven cleanup from close", async () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { expect, it as test, vi } from "vitest";
|
||||
import { runWithAnalysisOperationSnapshot } from "../../../../src/domain/analysisOperationSnapshot.js";
|
||||
import { awaitAcknowledgement } from "../../../fixtures/lifecycleAcknowledgement.js";
|
||||
import { KunaRunSlots } from "../../../../src/kuna/KunaRunSlots.js";
|
||||
|
||||
@@ -183,29 +184,57 @@ it("keeps the slot of a run whose stop is unproven until close proves it", async
|
||||
const { kuna, open } = await session(
|
||||
"rea-kuna-single-retained-slot-",
|
||||
{ project: "hang", decompile: "hang" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "300" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "10000" },
|
||||
unproven.launcher,
|
||||
1,
|
||||
);
|
||||
const client = open();
|
||||
const waiter = new AbortController();
|
||||
let queued: ReturnType<typeof client.execute> | undefined;
|
||||
let restoreAcquire: (() => void) | undefined;
|
||||
try {
|
||||
expect((await client.execute("list_procedures", {})).ok).toBe(true);
|
||||
expect(
|
||||
await client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
await runWithAnalysisOperationSnapshot(
|
||||
{ revision: 1, overrides: { "kuna.function_timeout_ms": 300 } },
|
||||
() => client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
),
|
||||
).toMatchObject({ ok: false, error: { cleanupIncomplete: true } });
|
||||
// The timed-out tree may still run, so the next run must not start.
|
||||
const queued = client.execute(
|
||||
const admission = deferred<void>();
|
||||
const acquire = KunaRunSlots.prototype.acquire;
|
||||
let granted = false;
|
||||
const requests = vi
|
||||
.spyOn(KunaRunSlots.prototype, "acquire")
|
||||
.mockImplementation(function (this: KunaRunSlots, signal) {
|
||||
const pending = acquire.call(this, signal);
|
||||
void pending.then(() => {
|
||||
granted = true;
|
||||
});
|
||||
admission.resolve();
|
||||
return pending;
|
||||
});
|
||||
restoreAcquire = () => requests.mockRestore();
|
||||
queued = client.execute(
|
||||
"procedure_pseudo_code",
|
||||
{ procedure: "parse" },
|
||||
{ signal: waiter.signal },
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
await awaitAcknowledgement(
|
||||
admission.promise,
|
||||
queued,
|
||||
"retained single-function slot",
|
||||
);
|
||||
await new Promise<void>((resolve) => setImmediate(resolve));
|
||||
expect(granted).toBe(false);
|
||||
expect(await decompilesOf(kuna)).toHaveLength(1);
|
||||
waiter.abort();
|
||||
expect(await queued).toMatchObject({
|
||||
ok: false,
|
||||
error: { _tag: "AnalysisCancelledError" },
|
||||
});
|
||||
restoreAcquire();
|
||||
restoreAcquire = undefined;
|
||||
expect((await client.close()).ok).toBe(false);
|
||||
unproven.release();
|
||||
expect(await client.close()).toEqual({ ok: true, value: null });
|
||||
@@ -225,6 +254,8 @@ it("keeps the slot of a run whose stop is unproven until close proves it", async
|
||||
waiter.abort();
|
||||
unproven.release();
|
||||
await client.close();
|
||||
await Promise.allSettled([queued]);
|
||||
restoreAcquire?.();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -343,13 +374,17 @@ it("does not keep a failed run, so a repeat runs again", async () => {
|
||||
const { kuna, open } = await session(
|
||||
"rea-kuna-single-failed-not-kept-",
|
||||
{ project: "hang", decompile: "hang" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "200" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "10000" },
|
||||
);
|
||||
const client = open();
|
||||
try {
|
||||
expect((await client.execute("list_procedures", {})).ok).toBe(true);
|
||||
for (let repeat = 0; repeat < 2; repeat += 1)
|
||||
expect(
|
||||
await client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
await runWithAnalysisOperationSnapshot(
|
||||
{ revision: 1, overrides: { "kuna.function_timeout_ms": 200 } },
|
||||
() => client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
),
|
||||
).toMatchObject({ ok: false });
|
||||
expect(await decompilesOf(kuna)).toHaveLength(2);
|
||||
} finally {
|
||||
@@ -390,13 +425,15 @@ it("names the setting that owns a single-function deadline", async () => {
|
||||
const { open } = await session(
|
||||
"rea-kuna-function-deadline-",
|
||||
{ project: "hang", decompile: "hang" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "300" },
|
||||
{ REA_KUNA_TIMEOUT_MS: "10000" },
|
||||
);
|
||||
const client = open();
|
||||
try {
|
||||
const result = await client.execute("procedure_pseudo_code", {
|
||||
procedure: "main",
|
||||
});
|
||||
expect((await client.execute("list_procedures", {})).ok).toBe(true);
|
||||
const result = await runWithAnalysisOperationSnapshot(
|
||||
{ revision: 1, overrides: { "kuna.function_timeout_ms": 300 } },
|
||||
() => client.execute("procedure_pseudo_code", { procedure: "main" }),
|
||||
);
|
||||
if (result.ok) throw new Error("the hanging run answered");
|
||||
expect(projectAnalysisError(result.error)).toMatchObject({
|
||||
code: "provider_timeout",
|
||||
|
||||
Reference in new issue
Block a user