test: harden release live probes

This commit is contained in:
Peter Steinberger
2026-05-02 10:22:32 +01:00
parent 5b2a0fbac1
commit 800a33bbfe
2 changed files with 48 additions and 17 deletions

View File

@@ -951,14 +951,17 @@ describeLive("gateway live (ACP bind)", () => {
logLiveStep("bound session classified the probe image");
}
const cronProbe = createLiveCronProbeSpec({
agentId: liveAgent,
sessionKey: spawnedSessionKey,
});
const requireCronMcpProbe = shouldRequireCronMcpProbe();
let cronJobId: string | undefined;
let lastCronAssistantText = "";
let lastCronProbeName = "";
let lastCronMismatch = "";
for (let attempt = 0; attempt < ACP_CRON_MCP_PROBE_MAX_ATTEMPTS; attempt += 1) {
const cronProbe = createLiveCronProbeSpec({
agentId: liveAgent,
sessionKey: spawnedSessionKey,
});
lastCronProbeName = cronProbe.name;
await sendChatAndWait({
client,
sessionKey: originalSessionKey,
@@ -998,13 +1001,26 @@ describeLive("gateway live (ACP bind)", () => {
});
const createdJob = verifyResult.job;
if (createdJob) {
assertCronJobMatches({
job: createdJob,
expectedName: cronProbe.name,
expectedMessage: cronProbe.message,
expectedSessionKey: spawnedSessionKey,
expectedAgentId: liveAgent,
});
try {
assertCronJobMatches({
job: createdJob,
expectedName: cronProbe.name,
expectedMessage: cronProbe.message,
expectedSessionKey: spawnedSessionKey,
expectedAgentId: liveAgent,
});
} catch (error) {
lastCronMismatch = error instanceof Error ? error.message : String(error);
logLiveStep(
`cron mcp job ${cronProbe.name} mismatch after attempt ${String(
attempt + 1,
)}: ${lastCronMismatch}`,
);
if (attempt === ACP_CRON_MCP_PROBE_MAX_ATTEMPTS - 1 && requireCronMcpProbe) {
throw error;
}
continue;
}
cronJobId = createdJob.id;
if (cronHistory) {
expect(cronHistory.lastAssistantText.trim().length).toBeGreaterThan(0);
@@ -1019,14 +1035,16 @@ describeLive("gateway live (ACP bind)", () => {
if (attempt === ACP_CRON_MCP_PROBE_MAX_ATTEMPTS - 1) {
if (!requireCronMcpProbe) {
logLiveStep(
`cron mcp job ${cronProbe.name} not observed; continuing after bind/image verification`,
`cron mcp job ${lastCronProbeName} not observed; continuing after bind/image verification${
lastCronMismatch ? `; last mismatch=${lastCronMismatch}` : ""
}`,
);
break;
}
throw new Error(
`acp cron cli verify could not find job ${cronProbe.name}: reply=${JSON.stringify(
`acp cron cli verify could not find job ${lastCronProbeName}: reply=${JSON.stringify(
lastCronAssistantText,
)}`,
)}${lastCronMismatch ? ` mismatch=${lastCronMismatch}` : ""}`,
);
}
}
@@ -1034,7 +1052,7 @@ describeLive("gateway live (ACP bind)", () => {
if (!requireCronMcpProbe) {
return;
}
throw new Error(`acp cron cli verify did not create job ${cronProbe.name}`);
throw new Error(`acp cron cli verify did not create job ${lastCronProbeName}`);
}
await runOpenClawCliJson(
["cron", "rm", cronJobId, "--json", "--url", `ws://127.0.0.1:${port}`, "--token", token],

View File

@@ -31,6 +31,11 @@ const describeLive = LIVE ? describe : describe.skip;
const providerFilter = parseCsvFilter(process.env.OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS);
const caseFilter = parseCaseFilter(process.env.OPENCLAW_LIVE_IMAGE_GENERATION_CASES);
const envModelMap = parseProviderModelMap(process.env.OPENCLAW_LIVE_IMAGE_GENERATION_MODELS);
const DEFAULT_LIVE_IMAGE_GENERATION_TIMEOUT_MS = 120_000;
const LIVE_IMAGE_GENERATION_TIMEOUT_MS = resolvePositiveIntegerEnv(
process.env.OPENCLAW_LIVE_IMAGE_GENERATION_TIMEOUT_MS,
DEFAULT_LIVE_IMAGE_GENERATION_TIMEOUT_MS,
);
type LiveProviderCase = {
pluginId: string;
@@ -48,6 +53,14 @@ type LiveImageCase = {
inputImages?: Array<{ buffer: Buffer; mimeType: string; fileName?: string }>;
};
function resolvePositiveIntegerEnv(raw: string | undefined, fallback: number): number {
if (!raw) {
return fallback;
}
const parsed = Number(raw);
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
}
function loadBundledProviderPlugin(
pluginId: string,
): ReturnType<typeof loadBundledProviderPluginFromTestHelper> {
@@ -255,7 +268,7 @@ describeLive("image generation live (provider sweep)", () => {
size: testCase.size,
resolution: testCase.resolution,
inputImages: testCase.inputImages,
timeoutMs: 60_000,
timeoutMs: LIVE_IMAGE_GENERATION_TIMEOUT_MS,
});
expect(result.images.length).toBeGreaterThan(0);
@@ -293,6 +306,6 @@ describeLive("image generation live (provider sweep)", () => {
}
expect(failures).toEqual([]);
},
10 * 60_000,
15 * 60_000,
);
});