Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions tests/usage/usage-filter-index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,11 @@ describe("filtered usage index availability", () => {
expect(existsSync(`${indexPath}-wal`)).toBe(false);
});

test("an unwritable home degrades to the streaming read", async () => {
// chmod cannot make a Windows directory unwritable, so there this would build the index and
// assert nothing about permissions. The degrade itself is the platform-neutral catch-all in
// readUsageFilterCandidates, which the vanishing-after-refresh case below reaches on every
// platform; contention and the foreign file cover the busy and explicit fallbacks.
test.skipIf(process.platform === "win32")("an unwritable home degrades to the streaming read", async () => {
const rows = Array.from({ length: 5 }, (_, index) => syntheticRow(index));
writeRows(rows);
const expected = rows.filter(row => row.provider === "openai").length;
Expand Down Expand Up @@ -1130,13 +1134,25 @@ describe("filtered usage index availability", () => {
}
});

test("a projection that vanishes before the read is not recreated", async () => {
/** Delete the projection at one point of a filtered query and expect a streaming answer. */
async function expectVanishedProjectionNotRecreated(hooks: (remove: (dbPath: string) => void) =>
Parameters<typeof setUsageFilterIndexTestHooksForTests>[0]): Promise<void> {
const rows = Array.from({ length: 5 }, (_, index) => syntheticRow(index));
writeRows(rows);
const indexPath = usageFilterIndexPath(testDir);
setUsageFilterIndexTestHooksForTests({
afterPublish: ({ dbPath }) => { rmSync(dbPath, { force: true }); },
});
let removed = false;
setUsageFilterIndexTestHooksForTests(hooks(dbPath => {
const existed = existsSync(dbPath);
// A scanner can hold a just-closed file on Windows for a moment; that is not the subject.
for (let attempt = 0; ; attempt += 1) {
try { rmSync(dbPath, { force: true }); break; } catch (error) {
const code = (error as NodeJS.ErrnoException).code;
if (attempt >= 4 || (code !== "EBUSY" && code !== "EPERM")) throw error;
Bun.sleepSync(25);
}
}
removed = existed && !existsSync(dbPath);
}));
try {
const result = await getFilteredUsageAggregate({ provider: "openai" });
expect(summary(result).summary.requests)
Expand All @@ -1145,7 +1161,19 @@ describe("filtered usage index availability", () => {
} finally {
setUsageFilterIndexTestHooksForTests(null);
}
// Without this the streaming fallback would satisfy every assertion even if the hook never ran.
expect(removed).toBe(true);
expect(existsSync(indexPath)).toBe(false);
}

// Windows refuses to delete a file SQLite holds open: there the projection can only vanish once
// the refresh has closed it, which the next case covers on every platform.
test.skipIf(process.platform === "win32")("a projection that vanishes before the read is not recreated", async () => {
await expectVanishedProjectionNotRecreated(remove => ({ afterPublish: ({ dbPath }) => remove(dbPath) }));
});

test("a projection that vanishes after the refresh closed it is not recreated by the read", async () => {
await expectVanishedProjectionNotRecreated(remove => ({ afterRefresh: ({ dbPath }) => remove(dbPath) }));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
});

test("a home change during a refresh never mixes installations", async () => {
Expand Down
Loading