From 74319f3895ffe49668ce419abdbed60212f7e3ff Mon Sep 17 00:00:00 2001 From: Greg Soucy Date: Fri, 20 Mar 2026 17:48:45 -0400 Subject: [PATCH] [runtime] stabilize schema verify polling test Why: CI needs the chain test to tolerate validator warmup without aborting after a single short retry. Contract impact: none --- runtime/tests/runtime-signing.test.mjs | 55 +++++++++++++++++++------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/runtime/tests/runtime-signing.test.mjs b/runtime/tests/runtime-signing.test.mjs index 55e2ced..bfe7bc1 100644 --- a/runtime/tests/runtime-signing.test.mjs +++ b/runtime/tests/runtime-signing.test.mjs @@ -474,7 +474,7 @@ test("full chain clean -> summarize -> classify verifies with schema using parti async function verifyReceiptWithTimeout(receipt) { const controller = new AbortController(); - const timeout = setTimeout(() => controller.abort(), 5000); + const timeout = setTimeout(() => controller.abort(), 10000); try { const res = await fetch(`${srv.base}/verify?schema=1`, { @@ -528,25 +528,52 @@ test("full chain clean -> summarize -> classify verifies with schema using parti assert.equal(finalReceipt.x402.entry, "x402://classifyagent.eth/classify/v1.1.0"); - console.log("[chain] before verify request"); - let verifyAttempt = await verifyReceiptWithTimeout(finalReceipt); - console.log("[chain] after verify response", verifyAttempt.res.status, verifyAttempt.json ?? verifyAttempt.text); + let verifyAttempt; + let verifyError = null; + + for (let attempt = 1; attempt <= 3; attempt++) { + console.log(`[chain] before verify request attempt ${attempt}`); + + try { + verifyAttempt = await verifyReceiptWithTimeout(finalReceipt); + verifyError = null; + } catch (err) { + verifyError = err; + if (err?.message?.includes("AbortError")) { + throw new Error(`verify attempt ${attempt} aborted: ${err.message}; last status/body: ${verifyAttempt ? `${verifyAttempt.res.status} ${verifyAttempt.text}` : "none"}`); + } + throw err; + } + + console.log(`[chain] after verify response attempt ${attempt}`, verifyAttempt.res.status, verifyAttempt.json ?? verifyAttempt.text); + + if (verifyAttempt.res.status === 200) { + break; + } + + if (verifyAttempt.res.status === 202) { + console.log("[chain] verify warmup 202 response", verifyAttempt.json ?? verifyAttempt.text); + + if (attempt < 3) { + const retryAfterMs = Number(verifyAttempt.json?.retry_after_ms); + const delayMs = Number.isFinite(retryAfterMs) && retryAfterMs > 0 ? retryAfterMs : 1200; + await new Promise((resolve) => setTimeout(resolve, delayMs)); + continue; + } + } - if (verifyAttempt.res.status === 202) { - console.log("[chain] verify warmup 202 response", verifyAttempt.json ?? verifyAttempt.text); - await new Promise((resolve) => setTimeout(resolve, 1200)); - console.log("[chain] before verify request retry"); - verifyAttempt = await verifyReceiptWithTimeout(finalReceipt); - console.log("[chain] after verify response retry", verifyAttempt.res.status, verifyAttempt.json ?? verifyAttempt.text); + break; } - const verifyRes = verifyAttempt.res; - const verifyJson = verifyAttempt.json; + const verifyRes = verifyAttempt?.res; + const verifyJson = verifyAttempt?.json; assert.ok(verifyJson, "verify returned non-JSON response"); - if (verifyRes.status !== 200) { - throw new Error(`verify retry failed with status ${verifyRes.status}: ${verifyAttempt.text}`); + if (verifyRes?.status !== 200) { + throw new Error( + `verify did not succeed after 3 attempts; last status/body: ${verifyRes ? `${verifyRes.status} ${verifyAttempt.text}` : "none"}${verifyError ? `; last error: ${verifyError.message}` : ""}`, + ); } assert.equal(verifyJson.checks.signature_valid, true);