test(server): reproduce heap exhaustion in overlapping directory searches

This commit is contained in:
paseo-bot[bot]
2026-10-09 22:04:06 +02:00
parent a1da1b8f23
commit 5e8b2143ea
2 changed files with 80 additions and 0 deletions
@@ -0,0 +1,55 @@
import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";
import { expect, it } from "vitest";
// Opt-in reproduction: prepare the directory tree with scripts/repro-directory-search-memory.py,
// then pass its location as PASEO_REPRO_SEARCH_ROOT. This exercises real filesystem calls.
it.skipIf(!process.env.PASEO_REPRO_SEARCH_ROOT)(
"finishes overlapping directory searches without exhausting the Node heap",
async () => {
const modulePath = fileURLToPath(new URL("./directory-suggestions.ts", import.meta.url));
const source = `
const { searchDirectoryEntries } = await import(${JSON.stringify(modulePath)});
const query = "zzzzzzzzzzzzzz";
await Promise.all(Array.from({ length: query.length }, (_, index) =>
searchDirectoryEntries({
root: process.env.PASEO_REPRO_SEARCH_ROOT,
query: query.slice(0, index + 1),
pathFormat: "absolute",
includeFiles: false,
includeDirectories: true,
pathQueryPolicy: "rooted",
rootAliases: ["~"],
blankQueryBehavior: "none",
confidentResultScanThreshold: 5000,
limit: 30,
})
));
`;
const result = await new Promise<{
code: number | null;
signal: string | null;
stderr: string;
}>((resolve, reject) => {
const child = spawn(
process.execPath,
["--import", "tsx", "--input-type=module", "--eval", source],
{
stdio: ["ignore", "ignore", "pipe"],
env: process.env,
},
);
let stderr = "";
child.stderr.setEncoding("utf8");
child.stderr.on("data", (data: string) => {
stderr += data;
});
child.on("error", reject);
child.on("close", (code, signal) => resolve({ code, signal, stderr }));
});
expect(result.stderr).not.toContain("JavaScript heap out of memory");
expect(result.signal).toBeNull();
expect(result.code).toBe(0);
},
120_000,
);
+25
View File
@@ -0,0 +1,25 @@
"""Create the real directory tree for the opt-in directory-search memory regression test.
Run from the checkout root, then run:
PASEO_REPRO_SEARCH_ROOT="$PWD/.diagnose-4879/home" npm exec --workspace=@getpaseo/server -- vitest run src/utils/directory-suggestions-memory.local.e2e.test.ts
The fixture needs approximately 6 GB of disk space. No heap limit or delay is injected.
"""
import os
import time
root = os.path.join(os.getcwd(), ".diagnose-4879", "home")
os.makedirs(root, exist_ok=True)
start = time.monotonic()
for branch_index in range(100):
branch = os.path.join(root, f"repos-{branch_index:03}")
os.makedirs(branch, exist_ok=True)
for package_index in range(140):
package = os.path.join(branch, f"packages-{package_index:03}")
os.makedirs(package, exist_ok=True)
for component_index in range(100):
os.makedirs(os.path.join(package, f"component-{component_index:03}"), exist_ok=True)
if branch_index % 10 == 9:
print(f"{branch_index + 1} branches built in {time.monotonic() - start:.1f}s", flush=True)
for name in ["ai-credential-refresh", "ai-engineer-reference", "ai-tevv", "gmail-local-sync"]:
os.makedirs(os.path.join(root, "workspace", "projects", name), exist_ok=True)
print("Created 1,414,106 directories", flush=True)