test: stabilize dependency verification
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -25,7 +25,7 @@ function flushMicrotasks(depth: number): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function flushWithTimeout(): Promise<void> {
|
function flushWithTimeout(): Promise<void> {
|
||||||
return new Promise<void>((resolve) => setTimeout(resolve, 10))
|
return new Promise<void>((resolve) => setTimeout(resolve, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function settleDeferredModelOverrideWork(): Promise<void> {
|
async function settleDeferredModelOverrideWork(): Promise<void> {
|
||||||
@@ -37,6 +37,10 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|||||||
return typeof value === "object" && value !== null
|
return typeof value === "object" && value !== null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatLogCalls(calls: readonly (readonly unknown[])[]): string {
|
||||||
|
return calls.map((call: readonly unknown[]) => `${String(call[0])} ${JSON.stringify(call[1])}`).join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
describe("scheduleDeferredModelOverride", () => {
|
describe("scheduleDeferredModelOverride", () => {
|
||||||
let tempDir: string
|
let tempDir: string
|
||||||
let dbPath: string
|
let dbPath: string
|
||||||
@@ -105,6 +109,21 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
return JSON.parse(row.data)[field] ?? null
|
return JSON.parse(row.data)[field] ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function waitForLogCall(
|
||||||
|
description: string,
|
||||||
|
predicate: (message: unknown, metadata: unknown) => boolean,
|
||||||
|
): Promise<void> {
|
||||||
|
const deadline = Date.now() + 1_000
|
||||||
|
while (Date.now() < deadline) {
|
||||||
|
if (logSpy.mock.calls.some((call: readonly unknown[]) => predicate(call[0], call[1]))) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await flushWithTimeout()
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Timed out waiting for log call: ${description}\n${formatLogCalls(logSpy.mock.calls)}`)
|
||||||
|
}
|
||||||
|
|
||||||
test("should update model in DB after microtask flushes", async () => {
|
test("should update model in DB after microtask flushes", async () => {
|
||||||
//#given
|
//#given
|
||||||
insertMessage("msg_001", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
insertMessage("msg_001", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
||||||
@@ -146,13 +165,54 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
"msg_nonexistent",
|
"msg_nonexistent",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-7" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-7" },
|
||||||
)
|
)
|
||||||
await flushWithTimeout()
|
await waitForLogCall("setTimeout fallback failure for msg_nonexistent", (message, metadata) => (
|
||||||
|
typeof message === "string"
|
||||||
|
&& message.includes("setTimeout fallback failed")
|
||||||
|
&& isRecord(metadata)
|
||||||
|
&& metadata.messageId === "msg_nonexistent"
|
||||||
|
))
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
const fallbackFailureCall = logSpy.mock.calls.find((call: readonly unknown[]) => {
|
||||||
expect.stringContaining("setTimeout fallback failed"),
|
const message = call[0]
|
||||||
expect.objectContaining({ messageId: "msg_nonexistent" }),
|
const metadata = call[1]
|
||||||
|
return (
|
||||||
|
typeof message === "string"
|
||||||
|
&& message.includes("setTimeout fallback failed")
|
||||||
|
&& isRecord(metadata)
|
||||||
|
&& metadata.messageId === "msg_nonexistent"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
expect(fallbackFailureCall).toBeDefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should log when microtask retries are exhausted before setTimeout fallback", async () => {
|
||||||
|
//#given no message inserted
|
||||||
|
|
||||||
|
//#when
|
||||||
|
scheduleDeferredModelOverride(
|
||||||
|
"msg_retry_exhausted",
|
||||||
|
{ providerID: "anthropic", modelID: "claude-opus-4-7" },
|
||||||
)
|
)
|
||||||
|
await waitForLogCall("microtask retry exhaustion for msg_retry_exhausted", (message, metadata) => (
|
||||||
|
message === "[ultrawork-db-override] Exhausted microtask retries, falling back to setTimeout"
|
||||||
|
&& isRecord(metadata)
|
||||||
|
&& metadata.messageId === "msg_retry_exhausted"
|
||||||
|
&& metadata.attempt === 10
|
||||||
|
))
|
||||||
|
|
||||||
|
//#then
|
||||||
|
const retryExhaustedCall = logSpy.mock.calls.find((call: readonly unknown[]) => {
|
||||||
|
const message = call[0]
|
||||||
|
const metadata = call[1]
|
||||||
|
return (
|
||||||
|
message === "[ultrawork-db-override] Exhausted microtask retries, falling back to setTimeout"
|
||||||
|
&& isRecord(metadata)
|
||||||
|
&& metadata.messageId === "msg_retry_exhausted"
|
||||||
|
&& metadata.attempt === 10
|
||||||
|
)
|
||||||
|
})
|
||||||
|
expect(retryExhaustedCall).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should not update variant fields when variant is undefined", async () => {
|
test("should not update variant fields when variant is undefined", async () => {
|
||||||
@@ -205,15 +265,19 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
await flushMicrotasks(5)
|
await flushMicrotasks(5)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
const failureCall = logSpy.mock.calls.find(([message, metadata]) =>
|
const failureCall = logSpy.mock.calls.find((call: readonly unknown[]) => {
|
||||||
typeof message === "string"
|
const message = call[0]
|
||||||
&& (
|
const metadata = call[1]
|
||||||
message.includes("Failed to open DB")
|
return (
|
||||||
|| message.includes("Deferred DB update failed with error")
|
typeof message === "string"
|
||||||
|
&& (
|
||||||
|
message.includes("Failed to open DB")
|
||||||
|
|| message.includes("Deferred DB update failed with error")
|
||||||
|
)
|
||||||
|
&& isRecord(metadata)
|
||||||
|
&& metadata.messageId === "msg_corrupt"
|
||||||
)
|
)
|
||||||
&& isRecord(metadata)
|
})
|
||||||
&& metadata.messageId === "msg_corrupt"
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(failureCall).toBeDefined()
|
expect(failureCall).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ describe("dist bundle Bun globals", () => {
|
|||||||
stdout: "node-esm-load-ok",
|
stdout: "node-esm-load-ok",
|
||||||
stderr: "",
|
stderr: "",
|
||||||
})
|
})
|
||||||
})
|
}, 20_000)
|
||||||
|
|
||||||
test.skipIf(!existsSync(DIST_INDEX))("#given dist bundle #when scanned for raw Bun runtime APIs #then no unshimmed Bun API calls remain", async () => {
|
test.skipIf(!existsSync(DIST_INDEX))("#given dist bundle #when scanned for raw Bun runtime APIs #then no unshimmed Bun API calls remain", async () => {
|
||||||
expect(hasRawBunApiCall("Bun.file('dist/index.js')")).toBe(true)
|
expect(hasRawBunApiCall("Bun.file('dist/index.js')")).toBe(true)
|
||||||
@@ -172,5 +172,5 @@ describe("dist bundle Bun globals", () => {
|
|||||||
expect(stdout).toContain("SMOKE_OK:")
|
expect(stdout).toContain("SMOKE_OK:")
|
||||||
expect(stderrLower).not.toContain("referenceerror")
|
expect(stderrLower).not.toContain("referenceerror")
|
||||||
expect(stderr).not.toContain("Bun is not defined")
|
expect(stderr).not.toContain("Bun is not defined")
|
||||||
})
|
}, 20_000)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import path from "node:path"
|
|||||||
import ts from "typescript"
|
import ts from "typescript"
|
||||||
|
|
||||||
const SOURCE_ROOT = path.resolve(import.meta.dir, "..")
|
const SOURCE_ROOT = path.resolve(import.meta.dir, "..")
|
||||||
|
const MOCK_MODULE_TOKEN = "mock.module"
|
||||||
const MOCK_MODULE_LIFECYCLE_ALLOWLIST = new Map<string, string>([
|
const MOCK_MODULE_LIFECYCLE_ALLOWLIST = new Map<string, string>([
|
||||||
// TODO(MOCK-MODULE-AUDIT): add cleanup for ast-grep tool module mocks.
|
// TODO(MOCK-MODULE-AUDIT): add cleanup for ast-grep tool module mocks.
|
||||||
[
|
[
|
||||||
@@ -191,6 +192,10 @@ describe("mock.module lifecycle hygiene", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const contents = await readFile(filePath, "utf8")
|
const contents = await readFile(filePath, "utf8")
|
||||||
|
if (!contents.includes(MOCK_MODULE_TOKEN)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const sourceFile = ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true)
|
const sourceFile = ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true)
|
||||||
if (hasMockModuleCall(sourceFile) && !hasCleanupPattern(sourceFile)) {
|
if (hasMockModuleCall(sourceFile) && !hasCleanupPattern(sourceFile)) {
|
||||||
offenders.push(relativeSourcePath(filePath))
|
offenders.push(relativeSourcePath(filePath))
|
||||||
@@ -199,5 +204,5 @@ describe("mock.module lifecycle hygiene", () => {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
expect(offenders.sort()).toEqual([])
|
expect(offenders.sort()).toEqual([])
|
||||||
})
|
}, 20_000)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user