Skip to content

Commit 7db2402

Browse files
chore: replace with vi.waitFor
1 parent 7d795ca commit 7db2402

File tree

3 files changed

+30
-80
lines changed

3 files changed

+30
-80
lines changed

tests/integration/helpers.ts

Lines changed: 21 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import { Keychain } from "../../src/common/keychain.js";
2323
import { Elicitation } from "../../src/elicitation.js";
2424
import type { MockClientCapabilities, createMockElicitInput } from "../utils/elicitationMocks.js";
2525

26-
const SEARCH_READY_CHECK_RETRIES = 200;
27-
const SEARCH_INDEX_STATUS_CHECK_RETRIES = 100;
26+
export const DEFAULT_WAIT_TIMEOUT = 1000;
27+
export const DEFAULT_RETRY_INTERVAL = 100;
2828

2929
export const driverOptions = setupDriverConfig({
3030
config,
@@ -422,109 +422,59 @@ export function sleep(ms: number): Promise<void> {
422422
return new Promise((resolve) => setTimeout(resolve, ms));
423423
}
424424

425-
export async function waitFor(
426-
condition: () => boolean | Promise<boolean>,
427-
{
428-
retries,
429-
retryTimeout,
430-
abortSignal,
431-
shouldRetryOnError,
432-
}: {
433-
retries: number;
434-
retryTimeout: number;
435-
abortSignal?: AbortSignal;
436-
shouldRetryOnError?: (error: unknown) => boolean | Promise<boolean>;
437-
} = {
438-
retries: 100,
439-
retryTimeout: 100,
440-
}
441-
): Promise<void> {
442-
for (let i = 0; i < retries && !abortSignal?.aborted; i++) {
443-
try {
444-
if (await condition()) {
445-
return;
446-
}
447-
448-
await sleep(retryTimeout);
449-
} catch (error) {
450-
if (shouldRetryOnError && (await shouldRetryOnError(error))) {
451-
await sleep(retryTimeout);
452-
continue;
453-
}
454-
throw error;
455-
}
456-
}
457-
}
458-
459425
export async function waitUntilSearchManagementServiceIsReady(
460426
collection: Collection,
461-
abortSignal?: AbortSignal
427+
timeout: number = DEFAULT_WAIT_TIMEOUT,
428+
interval: number = DEFAULT_RETRY_INTERVAL
462429
): Promise<void> {
463-
await waitFor(
464-
async (): Promise<boolean> => {
465-
await collection.listSearchIndexes({}).toArray();
466-
return true;
467-
},
468-
{
469-
retries: SEARCH_READY_CHECK_RETRIES,
470-
retryTimeout: 100,
471-
abortSignal,
472-
shouldRetryOnError: (error: unknown) => {
473-
return (
474-
error instanceof Error &&
475-
error.message.includes("Error connecting to Search Index Management service")
476-
);
477-
},
478-
}
479-
);
430+
await vi.waitFor(async () => await collection.listSearchIndexes({}).toArray(), { timeout, interval });
480431
}
481432

482433
async function waitUntilSearchIndexIs(
483434
collection: Collection,
484435
searchIndex: string,
485436
indexValidator: (index: { name: string; queryable: boolean }) => boolean,
486-
abortSignal?: AbortSignal
437+
timeout: number,
438+
interval: number
487439
): Promise<void> {
488-
await waitFor(
489-
async (): Promise<boolean> => {
440+
await vi.waitFor(
441+
async () => {
490442
const searchIndexes = (await collection.listSearchIndexes(searchIndex).toArray()) as {
491443
name: string;
492444
queryable: boolean;
493445
}[];
494446

495-
return searchIndexes.some((index) => indexValidator(index));
447+
if (!searchIndexes.some((index) => indexValidator(index))) {
448+
throw new Error("Search index did not pass validation");
449+
}
496450
},
497451
{
498-
retries: SEARCH_INDEX_STATUS_CHECK_RETRIES,
499-
retryTimeout: 100,
500-
abortSignal,
501-
shouldRetryOnError: (error: unknown) => {
502-
return (
503-
error instanceof Error &&
504-
error.message.includes("Error connecting to Search Index Management service")
505-
);
506-
},
452+
timeout,
453+
interval,
507454
}
508455
);
509456
}
510457

511458
export async function waitUntilSearchIndexIsListed(
512459
collection: Collection,
513460
searchIndex: string,
514-
abortSignal?: AbortSignal
461+
timeout: number = DEFAULT_WAIT_TIMEOUT,
462+
interval: number = DEFAULT_RETRY_INTERVAL
515463
): Promise<void> {
516-
return waitUntilSearchIndexIs(collection, searchIndex, (index) => index.name === searchIndex, abortSignal);
464+
return waitUntilSearchIndexIs(collection, searchIndex, (index) => index.name === searchIndex, timeout, interval);
517465
}
518466

519467
export async function waitUntilSearchIndexIsQueryable(
520468
collection: Collection,
521469
searchIndex: string,
522-
abortSignal?: AbortSignal
470+
timeout: number = DEFAULT_WAIT_TIMEOUT,
471+
interval: number = DEFAULT_RETRY_INTERVAL
523472
): Promise<void> {
524473
return waitUntilSearchIndexIs(
525474
collection,
526475
searchIndex,
527476
(index) => index.name === searchIndex && index.queryable,
528-
abortSignal
477+
timeout,
478+
interval
529479
);
530480
}

tests/integration/tools/mongodb/delete/dropIndex.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function setupForVectorSearchIndexes(integration: MongoDBIntegrationTestCase): {
5656
} {
5757
let moviesCollection: Collection;
5858
const indexName = "searchIdx";
59-
beforeEach(async ({ signal }) => {
59+
beforeEach(async () => {
6060
await integration.connectMcpClient();
6161
const mongoClient = integration.mongoClient();
6262
moviesCollection = mongoClient.db("mflix").collection("movies");
@@ -66,12 +66,12 @@ function setupForVectorSearchIndexes(integration: MongoDBIntegrationTestCase): {
6666
plot: "This is a horrible movie about a database called BongoDB and how it tried to copy the OG MangoDB.",
6767
},
6868
]);
69-
await waitUntilSearchManagementServiceIsReady(moviesCollection, signal);
69+
await waitUntilSearchManagementServiceIsReady(moviesCollection, SEARCH_TIMEOUT);
7070
await moviesCollection.createSearchIndex({
7171
name: indexName,
7272
definition: { mappings: { dynamic: true } },
7373
});
74-
await waitUntilSearchIndexIsListed(moviesCollection, indexName, signal);
74+
await waitUntilSearchIndexIsListed(moviesCollection, indexName, SEARCH_TIMEOUT);
7575
});
7676

7777
afterEach(async () => {

tests/integration/tools/mongodb/search/listSearchIndexes.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ describeWithMongoDB(
4444
(integration) => {
4545
let fooCollection: Collection;
4646

47-
beforeEach(async ({ signal }) => {
47+
beforeEach(async () => {
4848
await integration.connectMcpClient();
4949
fooCollection = integration.mongoClient().db("any").collection("foo");
50-
await waitUntilSearchManagementServiceIsReady(fooCollection, signal);
50+
await waitUntilSearchManagementServiceIsReady(fooCollection, SEARCH_TIMEOUT);
5151
});
5252

5353
describe("when the collection does not exist", () => {
@@ -77,9 +77,9 @@ describeWithMongoDB(
7777
});
7878

7979
describe("when there are indexes", () => {
80-
beforeEach(async ({ signal }) => {
80+
beforeEach(async () => {
8181
await fooCollection.insertOne({ field1: "yay" });
82-
await waitUntilSearchManagementServiceIsReady(fooCollection, signal);
82+
await waitUntilSearchManagementServiceIsReady(fooCollection, SEARCH_TIMEOUT);
8383
await fooCollection.createSearchIndexes([{ definition: { mappings: { dynamic: true } } }]);
8484
});
8585

@@ -99,8 +99,8 @@ describeWithMongoDB(
9999
it(
100100
"returns the list of existing indexes and detects if they are queryable",
101101
{ timeout: SEARCH_TIMEOUT },
102-
async ({ signal }) => {
103-
await waitUntilSearchIndexIsQueryable(fooCollection, "default", signal);
102+
async () => {
103+
await waitUntilSearchIndexIsQueryable(fooCollection, "default", SEARCH_TIMEOUT);
104104

105105
const response = await integration.mcpClient().callTool({
106106
name: "list-search-indexes",

0 commit comments

Comments
 (0)