From ea747cccd115783f04b709bfefa5f5445f12e020 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Mon, 31 Jul 2023 11:37:37 -0600 Subject: [PATCH 1/7] fix merge conflicts --- .evergreen/config.in.yml | 25 +- .evergreen/config.yml | 39 ++-- .evergreen/generate_evergreen_tasks.js | 27 --- .../run-search-index-management-tests.sh | 2 +- package.json | 2 +- src/operations/search_indexes/drop.ts | 12 +- .../search-index-management.spec.test.ts | 4 +- .../search-index-management.prose.test.ts | 220 ++++++++++++++++++ .../index-management/createSearchIndex.json | 6 +- .../index-management/createSearchIndex.yml | 2 + .../index-management/createSearchIndexes.json | 9 +- .../index-management/createSearchIndexes.yml | 3 + .../index-management/dropSearchIndex.json | 3 +- .../spec/index-management/dropSearchIndex.yml | 2 +- .../index-management/listSearchIndexes.json | 9 +- .../index-management/listSearchIndexes.yml | 3 + .../index-management/updateSearchIndex.json | 3 +- .../index-management/updateSearchIndex.yml | 3 +- test/tools/runner/config.ts | 23 +- 19 files changed, 318 insertions(+), 79 deletions(-) rename test/{manual => integration/index-management}/search-index-management.spec.test.ts (57%) create mode 100644 test/manual/search-index-management.prose.test.ts diff --git a/.evergreen/config.in.yml b/.evergreen/config.in.yml index dd30ee38a3e..0fb1e64936b 100644 --- a/.evergreen/config.in.yml +++ b/.evergreen/config.in.yml @@ -45,15 +45,6 @@ functions: params: file: src/expansion.yml - "run search index management tests": - - command: subprocess.exec - params: - binary: bash - working_dir: src - add_expansions_to_env: true - args: - - .evergreen/run-search-index-management-tests.sh - "bootstrap mongo-orchestration": - command: subprocess.exec params: @@ -1281,6 +1272,19 @@ tasks: TEST_LAMBDA_DIRECTORY: ${PROJECT_DIRECTORY}/test/lambda AWS_REGION: us-east-1 + - name: test-search-index-helpers + commands: + - func: install dependencies + vars: + NODE_LTS_VERSION: 20 + - command: subprocess.exec + params: + working_dir: src + binary: bash + add_expansions_to_env: true + args: + - .evergreen/run-search-index-management-tests.sh + task_groups: - name: serverless_task_group setup_group_can_fail_task: true @@ -1420,6 +1424,8 @@ task_groups: working_dir: src binary: bash add_expansions_to_env: true + env: + MONGODB_VERSION: "7.0" args: - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh - command: expansions.update @@ -1437,6 +1443,7 @@ task_groups: setup_group_timeout_secs: 1800 tasks: - test-aws-lambda-deployed + - test-search-index-helpers pre: - func: "fetch source" diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 8b1c7752674..bbf8725ed87 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -25,14 +25,6 @@ functions: - command: expansions.update params: file: src/expansion.yml - run search index management tests: - - command: subprocess.exec - params: - binary: bash - working_dir: src - add_expansions_to_env: true - args: - - .evergreen/run-search-index-management-tests.sh bootstrap mongo-orchestration: - command: subprocess.exec params: @@ -1204,6 +1196,18 @@ tasks: env: TEST_LAMBDA_DIRECTORY: ${PROJECT_DIRECTORY}/test/lambda AWS_REGION: us-east-1 + - name: test-search-index-helpers + commands: + - func: install dependencies + vars: + NODE_LTS_VERSION: 20 + - command: subprocess.exec + params: + working_dir: src + binary: bash + add_expansions_to_env: true + args: + - .evergreen/run-search-index-management-tests.sh - name: test-latest-server tags: - latest @@ -2651,17 +2655,6 @@ tasks: variant: '*' status: '*' patch_optional: true - - name: test-search-index-helpers - tags: [] - commands: - - func: install dependencies - vars: - NODE_LTS_NAME: 20 - - func: bootstrap mongo-orchestration - vars: - VERSION: latest - TOPOLOGY: replica_set - - func: run search index management tests - name: run-custom-csfle-tests-5.0-pinned-commit tags: - run-custom-dependency-tests @@ -3473,6 +3466,8 @@ task_groups: working_dir: src binary: bash add_expansions_to_env: true + env: + MONGODB_VERSION: '7.0' args: - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh - command: expansions.update @@ -3490,6 +3485,7 @@ task_groups: setup_group_timeout_secs: 1800 tasks: - test-aws-lambda-deployed + - test-search-index-helpers pre: - func: fetch source - func: windows fix @@ -4063,8 +4059,3 @@ buildvariants: tasks: - test-lambda-example - test-lambda-aws-auth-example - - name: rhel8-test-seach-index-management-helpers - display_name: Search Index Management Helpers Tests - run_on: rhel80-large - tasks: - - test-search-index-helpers diff --git a/.evergreen/generate_evergreen_tasks.js b/.evergreen/generate_evergreen_tasks.js index 2ef05d4fe5c..e1bf4980090 100644 --- a/.evergreen/generate_evergreen_tasks.js +++ b/.evergreen/generate_evergreen_tasks.js @@ -688,26 +688,6 @@ const coverageTask = { }; SINGLETON_TASKS.push(coverageTask); -SINGLETON_TASKS.push({ - name: 'test-search-index-helpers', - tags: [], - commands: [ - { - func: 'install dependencies', - vars: { - NODE_LTS_NAME: LATEST_LTS - } - }, - { - func: 'bootstrap mongo-orchestration', - vars: { - VERSION: 'latest', - TOPOLOGY: 'replica_set' - } - }, - { func: 'run search index management tests' } - ] -}) SINGLETON_TASKS.push(...oneOffFuncAsTasks); BUILD_VARIANTS.push({ @@ -775,13 +755,6 @@ BUILD_VARIANTS.push({ tasks: ['test-lambda-example', 'test-lambda-aws-auth-example'] }); -BUILD_VARIANTS.push({ - name: 'rhel8-test-seach-index-management-helpers', - display_name: 'Search Index Management Helpers Tests', - run_on: DEFAULT_OS, - tasks: ['test-search-index-helpers'] -}) - // TODO(NODE-4575): unskip zstd and snappy on node 16 for (const variant of BUILD_VARIANTS.filter( variant => diff --git a/.evergreen/run-search-index-management-tests.sh b/.evergreen/run-search-index-management-tests.sh index 825e5732adf..2dc1f34e5ca 100644 --- a/.evergreen/run-search-index-management-tests.sh +++ b/.evergreen/run-search-index-management-tests.sh @@ -1,5 +1,5 @@ #! /bin/bash -source "${PROJECT_DIRECTORY}/.evergreen/init-nvm.sh" +source "${PROJECT_DIRECTORY}/.evergreen/init-node-and-npm-env.sh" npm run check:search-indexes diff --git a/package.json b/package.json index ac7ffaa6d93..da0319b8c9a 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "check:tsd": "tsd --version && tsd", "check:dependencies": "mocha test/action/dependency.test.ts", "check:dts": "node ./node_modules/typescript/bin/tsc --noEmit mongodb.d.ts && tsd", - "check:search-indexes": "nyc mocha --config test/mocha_mongodb.json test/manual/search-index-management.spec.test.ts", + "check:search-indexes": "nyc mocha --config test/mocha_mongodb.json test/manual/search-index-management.prose.test.ts", "check:test": "mocha --config test/mocha_mongodb.json test/integration", "check:unit": "mocha test/unit", "check:ts": "node ./node_modules/typescript/bin/tsc -v && node ./node_modules/typescript/bin/tsc --noEmit", diff --git a/src/operations/search_indexes/drop.ts b/src/operations/search_indexes/drop.ts index e9ba3cfa48b..5f29308f86e 100644 --- a/src/operations/search_indexes/drop.ts +++ b/src/operations/search_indexes/drop.ts @@ -1,6 +1,7 @@ import type { Document } from 'bson'; import type { Collection } from '../../collection'; +import { MONGODB_ERROR_CODES, MongoServerError } from '../../error'; import type { Server } from '../../sdam/server'; import type { ClientSession } from '../../sessions'; import { AbstractOperation } from '../operation'; @@ -22,7 +23,14 @@ export class DropSearchIndexOperation extends AbstractOperation { command.name = this.name; } - await server.commandAsync(namespace, command, { session }); - return; + try { + await server.commandAsync(namespace, command, { session }); + } catch (error) { + const isNamespaceNotFoundError = + error instanceof MongoServerError && error.code === MONGODB_ERROR_CODES.NamespaceNotFound; + if (!isNamespaceNotFoundError) { + throw error; + } + } } } diff --git a/test/manual/search-index-management.spec.test.ts b/test/integration/index-management/search-index-management.spec.test.ts similarity index 57% rename from test/manual/search-index-management.spec.test.ts rename to test/integration/index-management/search-index-management.spec.test.ts index ce7b7958fe6..f519605f690 100644 --- a/test/manual/search-index-management.spec.test.ts +++ b/test/integration/index-management/search-index-management.spec.test.ts @@ -1,7 +1,7 @@ import { join } from 'path'; -import { loadSpecTests } from '../spec'; -import { runUnifiedSuite } from '../tools/unified-spec-runner/runner'; +import { loadSpecTests } from '../../spec'; +import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner'; describe('Search Index Management Tests (Unified)', function () { runUnifiedSuite(loadSpecTests(join('index-management'))); diff --git a/test/manual/search-index-management.prose.test.ts b/test/manual/search-index-management.prose.test.ts new file mode 100644 index 00000000000..dae36715ee9 --- /dev/null +++ b/test/manual/search-index-management.prose.test.ts @@ -0,0 +1,220 @@ +import { expect } from 'chai'; +import { lt } from 'semver'; +import { Readable } from 'stream'; +import { clearTimeout, setTimeout as setTimeoutCb } from 'timers'; +import { setInterval } from 'timers/promises'; + +import { type Collection, type Document, type MongoClient, ObjectId } from '../mongodb'; + +class TimeoutController extends AbortController { + timeoutId: NodeJS.Timeout; + constructor(private timeoutMS: number) { + super(); + + this.timeoutId = setTimeoutCb(() => { + this.abort(new Error(`Test timed out after ${timeoutMS} milliseconds.`)); + }, timeoutMS); + } + + clear(abort = false) { + if (abort) { + this.abort(); + } + clearTimeout(this.timeoutId); + } +} + +const metadata: MongoDBMetadataUI = { + requires: { + mongodb: '>=7.0' + } +}; + +describe('Index Management Prose Tests', function () { + describe('Search Index Management Tests', function () { + this.timeout(300000); // set timeout at five minutes + + let client: MongoClient; + let timeoutController: TimeoutController; + + /** creates a readable stream that emits every \ ms */ + const interval = (interval: number, signal: AbortSignal) => + Readable.from(setInterval(interval, undefined, { signal, ref: false })); + + /** + * waits until the search indexes for `collection` satisfy `predicate`, optionally pre-filtering + * for indexes with name = `indexName` + */ + const waitForIndexes = ({ + collection, + predicate, + indexName + }: { + collection: Collection; + predicate: (arg0: Array) => boolean; + indexName?: string; + }): Promise> => + interval(5000, timeoutController.signal) + .map(() => collection.listSearchIndexes(indexName).toArray()) + .find(predicate); + + before(function () { + this.configuration = this.configuration.makeAtlasTestConfiguration(); + }); + + beforeEach(function () { + if (lt(process.version, '18.0.0')) { + this.currentTest!.skipReason = 'Test requires Node18+'; + this.skip(); + } + }); + + beforeEach(async function () { + client = this.configuration.newClient(); + await client.connect(); + + timeoutController = new TimeoutController(60 * 1000 * 4); + }); + + afterEach(async () => { + await client?.close(); + timeoutController?.clear(false); + }); + + it( + 'Case 1: Driver can successfully create and list search indexes', + metadata, + async function () { + const collection = await client + .db('test-db') + .createCollection(new ObjectId().toHexString()); + + await collection.createSearchIndex({ + name: 'test-search-index', + definition: { + mappings: { dynamic: false } + } + }); + + const [index] = await waitForIndexes({ + collection, + predicate: indexes => indexes.every(index => index.queryable), + indexName: 'test-search-index' + }); + + expect(index).to.exist; + expect(index) + .to.have.property('latestDefinition') + .to.deep.equal({ mappings: { dynamic: false } }); + } + ); + + it( + 'Case 2: Driver can successfully create multiple indexes in batch', + metadata, + async function () { + const collection = await client + .db('test-db') + .createCollection(new ObjectId().toHexString()); + + const indexDefinitions = [ + { + name: 'test-search-index-1', + definition: { + mappings: { dynamic: false } + } + }, + { + name: 'test-search-index-2', + definition: { + mappings: { dynamic: false } + } + } + ]; + + await collection.createSearchIndexes(indexDefinitions); + + const indexes = await waitForIndexes({ + collection, + predicate: indexes => indexes.every(index => index.queryable) + }); + + for (const indexDescription of indexDefinitions) { + const index = indexes.find(({ name }) => name === indexDescription.name); + expect(index, `expected ${indexDescription.name} to exist`).to.exist; + + expect(index) + .to.have.property('latestDefinition') + .to.deep.equal({ mappings: { dynamic: false } }); + } + } + ); + + it('Case 3: Driver can successfully drop search indexes', metadata, async function () { + const collection = await client.db('test-db').createCollection(new ObjectId().toHexString()); + + await collection.createSearchIndex({ + name: 'test-search-index', + definition: { + mappings: { dynamic: false } + } + }); + + await waitForIndexes({ + collection, + predicate: indexes => indexes.every(index => index.queryable), + indexName: 'test-search-index' + }); + + await collection.dropSearchIndex('test-search-index'); + + const indexes = await waitForIndexes({ + collection, + predicate: indexes => indexes.length === 0, + indexName: 'test-search-index' + }); + + expect(indexes).to.deep.equal([]); + }); + + it('Case 4: Driver can update a search index', metadata, async function () { + const collection = await client.db('test-db').createCollection(new ObjectId().toHexString()); + + await collection.createSearchIndex({ + name: 'test-search-index', + definition: { + mappings: { dynamic: false } + } + }); + + await waitForIndexes({ + collection, + predicate: indexes => indexes.every(index => index.queryable), + indexName: 'test-search-index' + }); + + await collection.updateSearchIndex('test-search-index', { mappings: { dynamic: true } }); + + const [updatedIndex] = await waitForIndexes({ + collection, + predicate: indexes => indexes.every(index => index.queryable && index.status === 'READY'), + indexName: 'test-search-index' + }); + + expect(updatedIndex).to.have.property('name', 'test-search-index'); + expect(updatedIndex) + .to.have.property('latestDefinition') + .to.deep.equal({ mappings: { dynamic: true } }); + }); + + it( + 'Case 5: `dropSearchIndex` suppresses namespace not found errors', + metadata, + async function () { + const collection = await client.db('test-db').collection(new ObjectId().toHexString()); + + await collection.dropSearchIndex('test-search-index'); + } + ); + }); +}); diff --git a/test/spec/index-management/createSearchIndex.json b/test/spec/index-management/createSearchIndex.json index da664631e7b..04cffbe9c9f 100644 --- a/test/spec/index-management/createSearchIndex.json +++ b/test/spec/index-management/createSearchIndex.json @@ -54,7 +54,8 @@ } }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], @@ -100,7 +101,8 @@ } }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], diff --git a/test/spec/index-management/createSearchIndex.yml b/test/spec/index-management/createSearchIndex.yml index 0eb5c1ab1d3..3f923edaed6 100644 --- a/test/spec/index-management/createSearchIndex.yml +++ b/test/spec/index-management/createSearchIndex.yml @@ -31,6 +31,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: @@ -50,6 +51,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: diff --git a/test/spec/index-management/createSearchIndexes.json b/test/spec/index-management/createSearchIndexes.json index b78b3ea6c87..95dbedde773 100644 --- a/test/spec/index-management/createSearchIndexes.json +++ b/test/spec/index-management/createSearchIndexes.json @@ -48,7 +48,8 @@ "models": [] }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], @@ -87,7 +88,8 @@ ] }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], @@ -135,7 +137,8 @@ ] }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], diff --git a/test/spec/index-management/createSearchIndexes.yml b/test/spec/index-management/createSearchIndexes.yml index dc01c1b1668..877fc0fa017 100644 --- a/test/spec/index-management/createSearchIndexes.yml +++ b/test/spec/index-management/createSearchIndexes.yml @@ -31,6 +31,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: @@ -51,6 +52,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: @@ -70,6 +72,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: diff --git a/test/spec/index-management/dropSearchIndex.json b/test/spec/index-management/dropSearchIndex.json index b73447f602c..0f21a5b68db 100644 --- a/test/spec/index-management/dropSearchIndex.json +++ b/test/spec/index-management/dropSearchIndex.json @@ -48,7 +48,8 @@ "name": "test index" }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], diff --git a/test/spec/index-management/dropSearchIndex.yml b/test/spec/index-management/dropSearchIndex.yml index 5ffef7d17e4..bfd6159281c 100644 --- a/test/spec/index-management/dropSearchIndex.yml +++ b/test/spec/index-management/dropSearchIndex.yml @@ -31,6 +31,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: @@ -39,4 +40,3 @@ tests: dropSearchIndex: *collection0 name: *indexName $db: *database0 - diff --git a/test/spec/index-management/listSearchIndexes.json b/test/spec/index-management/listSearchIndexes.json index 41e2655fb3a..24c51ad88c7 100644 --- a/test/spec/index-management/listSearchIndexes.json +++ b/test/spec/index-management/listSearchIndexes.json @@ -45,7 +45,8 @@ "name": "listSearchIndexes", "object": "collection0", "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], @@ -79,7 +80,8 @@ "name": "test index" }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], @@ -119,7 +121,8 @@ } }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], diff --git a/test/spec/index-management/listSearchIndexes.yml b/test/spec/index-management/listSearchIndexes.yml index 7d3c3187b91..c912eae83c0 100644 --- a/test/spec/index-management/listSearchIndexes.yml +++ b/test/spec/index-management/listSearchIndexes.yml @@ -29,6 +29,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: @@ -48,6 +49,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: @@ -70,6 +72,7 @@ tests: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: diff --git a/test/spec/index-management/updateSearchIndex.json b/test/spec/index-management/updateSearchIndex.json index 00cd7e75417..88a46a3069c 100644 --- a/test/spec/index-management/updateSearchIndex.json +++ b/test/spec/index-management/updateSearchIndex.json @@ -49,7 +49,8 @@ "definition": {} }, "expectError": { - "isError": true + "isError": true, + "errorContains": "Search index commands are only supported with Atlas" } } ], diff --git a/test/spec/index-management/updateSearchIndex.yml b/test/spec/index-management/updateSearchIndex.yml index 215dbc42f92..03d248b3dc2 100644 --- a/test/spec/index-management/updateSearchIndex.yml +++ b/test/spec/index-management/updateSearchIndex.yml @@ -28,10 +28,11 @@ tests: arguments: name: &indexName 'test index' definition: &definition {} - expectError: + expectError: # Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing # against an Atlas cluster and the expectError will be removed. isError: true + errorContains: Search index commands are only supported with Atlas expectEvents: - client: *client0 events: diff --git a/test/tools/runner/config.ts b/test/tools/runner/config.ts index 2f190fe3b1d..6cfd0eed60c 100644 --- a/test/tools/runner/config.ts +++ b/test/tools/runner/config.ts @@ -73,7 +73,7 @@ export class TestConfiguration { }; serverApi: string; - constructor(uri: string, context: Record) { + constructor(private uri: string, private context: Record) { const url = new ConnectionString(uri); const { hosts } = url; const hostAddresses = hosts.map(HostAddress.fromString); @@ -353,4 +353,25 @@ export class TestConfiguration { kmsProviders(localKey): Record { return { local: { key: localKey } }; } + + makeAtlasTestConfiguration(): AtlasTestConfiguration { + return new AtlasTestConfiguration(this.uri, this.context); + } +} + +/** + * A specialized configuration used to connect to Atlas for testing. + * + * This class requires that the Atlas srv URI is set as the `MONGODB_URI` in the environment. + */ +export class AtlasTestConfiguration extends TestConfiguration { + override newClient(): MongoClient { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return new MongoClient(process.env.MONGODB_URI!); + } + + override url(): string { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return process.env.MONGODB_URI!; + } } From bd94418a8e3ec27720c9c0eeee384df737c55bbd Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 12 Jul 2023 14:21:25 -0600 Subject: [PATCH 2/7] fix lint --- test/manual/search-index-management.prose.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/manual/search-index-management.prose.test.ts b/test/manual/search-index-management.prose.test.ts index dae36715ee9..e97b9027228 100644 --- a/test/manual/search-index-management.prose.test.ts +++ b/test/manual/search-index-management.prose.test.ts @@ -64,7 +64,7 @@ describe('Index Management Prose Tests', function () { beforeEach(function () { if (lt(process.version, '18.0.0')) { - this.currentTest!.skipReason = 'Test requires Node18+'; + this.currentTest.skipReason = 'Test requires Node18+'; this.skip(); } }); From 3019d93f64b1609f3b067841bbeacef742b61429 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 12 Jul 2023 16:26:04 -0600 Subject: [PATCH 3/7] use setup task --- .evergreen/config.in.yml | 15 ++++++++++++--- .evergreen/config.yml | 10 +++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.evergreen/config.in.yml b/.evergreen/config.in.yml index 0fb1e64936b..5b35a40c71c 100644 --- a/.evergreen/config.in.yml +++ b/.evergreen/config.in.yml @@ -1428,9 +1428,6 @@ task_groups: MONGODB_VERSION: "7.0" args: - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh - - command: expansions.update - params: - file: src/atlas-expansion.yml teardown_group: - command: subprocess.exec params: @@ -1439,6 +1436,18 @@ task_groups: add_expansions_to_env: true args: - ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh + # `setup_group`s get run once-per-task-group, but only changes that get written to disk + # are preserved across tasks inside the task group. Specifically, any expansions loaded + # into memory will not be present for any tasks except the first task that gets run. + # We load the expansions file again to ensure that necessary enviroment variables are present. + setup_task: + # Load the expansion file to make an evergreen variable with the current unique version + - command: expansions.update + params: + file: src/expansion.yml + - command: expansions.update + params: + file: src/atlas-expansion.yml setup_group_can_fail_task: true setup_group_timeout_secs: 1800 tasks: diff --git a/.evergreen/config.yml b/.evergreen/config.yml index bbf8725ed87..5f4f5c04f56 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -3470,9 +3470,6 @@ task_groups: MONGODB_VERSION: '7.0' args: - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh - - command: expansions.update - params: - file: src/atlas-expansion.yml teardown_group: - command: subprocess.exec params: @@ -3481,6 +3478,13 @@ task_groups: add_expansions_to_env: true args: - ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh + setup_task: + - command: expansions.update + params: + file: src/expansion.yml + - command: expansions.update + params: + file: src/atlas-expansion.yml setup_group_can_fail_task: true setup_group_timeout_secs: 1800 tasks: From ef2cb96c60bcf4d07e9fe6cd517eb9827352a207 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Mon, 17 Jul 2023 09:55:11 -0600 Subject: [PATCH 4/7] Misc cleanups for search indexes testing --- .evergreen/config.in.yml | 36 ++++++++++++++----- .evergreen/config.yml | 35 +++++++++++++++--- .evergreen/generate_evergreen_tasks.js | 8 +++++ .../search-index-management.prose.test.ts | 26 +++----------- 4 files changed, 71 insertions(+), 34 deletions(-) diff --git a/.evergreen/config.in.yml b/.evergreen/config.in.yml index 5b35a40c71c..df9df455f78 100644 --- a/.evergreen/config.in.yml +++ b/.evergreen/config.in.yml @@ -1428,6 +1428,9 @@ task_groups: MONGODB_VERSION: "7.0" args: - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh + - command: expansions.update + params: + file: src/atlas-expansion.yml teardown_group: - command: subprocess.exec params: @@ -1436,22 +1439,37 @@ task_groups: add_expansions_to_env: true args: - ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh - # `setup_group`s get run once-per-task-group, but only changes that get written to disk - # are preserved across tasks inside the task group. Specifically, any expansions loaded - # into memory will not be present for any tasks except the first task that gets run. - # We load the expansions file again to ensure that necessary enviroment variables are present. - setup_task: - # Load the expansion file to make an evergreen variable with the current unique version - - command: expansions.update + setup_group_can_fail_task: true + setup_group_timeout_secs: 1800 + tasks: + - test-aws-lambda-deployed + + - name: test_atlas_task_group_search_indexes + setup_group: + - func: fetch source + - command: subprocess.exec params: - file: src/expansion.yml + working_dir: src + binary: bash + add_expansions_to_env: true + env: + MONGODB_VERSION: "7.0" + args: + - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh - command: expansions.update params: file: src/atlas-expansion.yml + teardown_group: + - command: subprocess.exec + params: + working_dir: src + binary: bash + add_expansions_to_env: true + args: + - ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh setup_group_can_fail_task: true setup_group_timeout_secs: 1800 tasks: - - test-aws-lambda-deployed - test-search-index-helpers pre: diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 5f4f5c04f56..55d2fef4b00 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -3470,6 +3470,9 @@ task_groups: MONGODB_VERSION: '7.0' args: - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh + - command: expansions.update + params: + file: src/atlas-expansion.yml teardown_group: - command: subprocess.exec params: @@ -3478,17 +3481,36 @@ task_groups: add_expansions_to_env: true args: - ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh - setup_task: - - command: expansions.update + setup_group_can_fail_task: true + setup_group_timeout_secs: 1800 + tasks: + - test-aws-lambda-deployed + - name: test_atlas_task_group_search_indexes + setup_group: + - func: fetch source + - command: subprocess.exec params: - file: src/expansion.yml + working_dir: src + binary: bash + add_expansions_to_env: true + env: + MONGODB_VERSION: '7.0' + args: + - ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh - command: expansions.update params: file: src/atlas-expansion.yml + teardown_group: + - command: subprocess.exec + params: + working_dir: src + binary: bash + add_expansions_to_env: true + args: + - ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh setup_group_can_fail_task: true setup_group_timeout_secs: 1800 tasks: - - test-aws-lambda-deployed - test-search-index-helpers pre: - func: fetch source @@ -4063,3 +4085,8 @@ buildvariants: tasks: - test-lambda-example - test-lambda-aws-auth-example + - name: rhel8-test-search-indexes + display_name: Search Index Tests + run_on: rhel80-large + tasks: + - test_atlas_task_group_search_indexes diff --git a/.evergreen/generate_evergreen_tasks.js b/.evergreen/generate_evergreen_tasks.js index e1bf4980090..ecd65967dc8 100644 --- a/.evergreen/generate_evergreen_tasks.js +++ b/.evergreen/generate_evergreen_tasks.js @@ -547,6 +547,7 @@ SINGLETON_TASKS.push( ] ); + function* makeTypescriptTasks() { for (const TS_VERSION of ['next', 'current', '4.1.6']) { // 4.1.6 can consume the public API but not compile the driver @@ -755,6 +756,13 @@ BUILD_VARIANTS.push({ tasks: ['test-lambda-example', 'test-lambda-aws-auth-example'] }); +BUILD_VARIANTS.push({ + name: 'rhel8-test-search-indexes', + display_name: 'Search Index Tests', + run_on: DEFAULT_OS, + tasks: ['test_atlas_task_group_search_indexes'] +}); + // TODO(NODE-4575): unskip zstd and snappy on node 16 for (const variant of BUILD_VARIANTS.filter( variant => diff --git a/test/manual/search-index-management.prose.test.ts b/test/manual/search-index-management.prose.test.ts index e97b9027228..192421a07b8 100644 --- a/test/manual/search-index-management.prose.test.ts +++ b/test/manual/search-index-management.prose.test.ts @@ -36,6 +36,7 @@ describe('Index Management Prose Tests', function () { let client: MongoClient; let timeoutController: TimeoutController; + let collection: Collection; /** creates a readable stream that emits every \ ms */ const interval = (interval: number, signal: AbortSignal) => @@ -46,11 +47,9 @@ describe('Index Management Prose Tests', function () { * for indexes with name = `indexName` */ const waitForIndexes = ({ - collection, predicate, indexName }: { - collection: Collection; predicate: (arg0: Array) => boolean; indexName?: string; }): Promise> => @@ -73,10 +72,13 @@ describe('Index Management Prose Tests', function () { client = this.configuration.newClient(); await client.connect(); + collection = await client.db('node-test').createCollection(new ObjectId().toHexString()); + timeoutController = new TimeoutController(60 * 1000 * 4); }); afterEach(async () => { + await collection.drop(); await client?.close(); timeoutController?.clear(false); }); @@ -85,10 +87,6 @@ describe('Index Management Prose Tests', function () { 'Case 1: Driver can successfully create and list search indexes', metadata, async function () { - const collection = await client - .db('test-db') - .createCollection(new ObjectId().toHexString()); - await collection.createSearchIndex({ name: 'test-search-index', definition: { @@ -97,7 +95,6 @@ describe('Index Management Prose Tests', function () { }); const [index] = await waitForIndexes({ - collection, predicate: indexes => indexes.every(index => index.queryable), indexName: 'test-search-index' }); @@ -113,10 +110,6 @@ describe('Index Management Prose Tests', function () { 'Case 2: Driver can successfully create multiple indexes in batch', metadata, async function () { - const collection = await client - .db('test-db') - .createCollection(new ObjectId().toHexString()); - const indexDefinitions = [ { name: 'test-search-index-1', @@ -135,7 +128,6 @@ describe('Index Management Prose Tests', function () { await collection.createSearchIndexes(indexDefinitions); const indexes = await waitForIndexes({ - collection, predicate: indexes => indexes.every(index => index.queryable) }); @@ -151,8 +143,6 @@ describe('Index Management Prose Tests', function () { ); it('Case 3: Driver can successfully drop search indexes', metadata, async function () { - const collection = await client.db('test-db').createCollection(new ObjectId().toHexString()); - await collection.createSearchIndex({ name: 'test-search-index', definition: { @@ -161,7 +151,6 @@ describe('Index Management Prose Tests', function () { }); await waitForIndexes({ - collection, predicate: indexes => indexes.every(index => index.queryable), indexName: 'test-search-index' }); @@ -169,7 +158,6 @@ describe('Index Management Prose Tests', function () { await collection.dropSearchIndex('test-search-index'); const indexes = await waitForIndexes({ - collection, predicate: indexes => indexes.length === 0, indexName: 'test-search-index' }); @@ -178,8 +166,6 @@ describe('Index Management Prose Tests', function () { }); it('Case 4: Driver can update a search index', metadata, async function () { - const collection = await client.db('test-db').createCollection(new ObjectId().toHexString()); - await collection.createSearchIndex({ name: 'test-search-index', definition: { @@ -188,7 +174,6 @@ describe('Index Management Prose Tests', function () { }); await waitForIndexes({ - collection, predicate: indexes => indexes.every(index => index.queryable), indexName: 'test-search-index' }); @@ -196,7 +181,6 @@ describe('Index Management Prose Tests', function () { await collection.updateSearchIndex('test-search-index', { mappings: { dynamic: true } }); const [updatedIndex] = await waitForIndexes({ - collection, predicate: indexes => indexes.every(index => index.queryable && index.status === 'READY'), indexName: 'test-search-index' }); @@ -211,7 +195,7 @@ describe('Index Management Prose Tests', function () { 'Case 5: `dropSearchIndex` suppresses namespace not found errors', metadata, async function () { - const collection = await client.db('test-db').collection(new ObjectId().toHexString()); + const collection = await client.db('node-test').collection(new ObjectId().toHexString()); await collection.dropSearchIndex('test-search-index'); } From 842e28e7e432e7c37c9d0b092d98435809ccf6fa Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 19 Jul 2023 12:01:42 -0600 Subject: [PATCH 5/7] address comments from first round of spec review --- .../search-index-management.prose.test.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/test/manual/search-index-management.prose.test.ts b/test/manual/search-index-management.prose.test.ts index 192421a07b8..24b5601aea6 100644 --- a/test/manual/search-index-management.prose.test.ts +++ b/test/manual/search-index-management.prose.test.ts @@ -38,24 +38,23 @@ describe('Index Management Prose Tests', function () { let timeoutController: TimeoutController; let collection: Collection; - /** creates a readable stream that emits every \ ms */ - const interval = (interval: number, signal: AbortSignal) => - Readable.from(setInterval(interval, undefined, { signal, ref: false })); - /** * waits until the search indexes for `collection` satisfy `predicate`, optionally pre-filtering * for indexes with name = `indexName` */ - const waitForIndexes = ({ + function waitForIndexes({ predicate, indexName }: { predicate: (arg0: Array) => boolean; indexName?: string; - }): Promise> => - interval(5000, timeoutController.signal) + }): Promise> { + return Readable.from( + setInterval(5000, undefined, { signal: timeoutController.signal, ref: false }) + ) .map(() => collection.listSearchIndexes(indexName).toArray()) .find(predicate); + } before(function () { this.configuration = this.configuration.makeAtlasTestConfiguration(); @@ -87,13 +86,15 @@ describe('Index Management Prose Tests', function () { 'Case 1: Driver can successfully create and list search indexes', metadata, async function () { - await collection.createSearchIndex({ + const name = await collection.createSearchIndex({ name: 'test-search-index', definition: { mappings: { dynamic: false } } }); + expect(name).to.equal('test-search-index'); + const [index] = await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable), indexName: 'test-search-index' @@ -125,7 +126,8 @@ describe('Index Management Prose Tests', function () { } ]; - await collection.createSearchIndexes(indexDefinitions); + const names = await collection.createSearchIndexes(indexDefinitions); + expect(names).to.deep.equal(['test-search-index-1', 'test-search-index-2']); const indexes = await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable) @@ -143,13 +145,15 @@ describe('Index Management Prose Tests', function () { ); it('Case 3: Driver can successfully drop search indexes', metadata, async function () { - await collection.createSearchIndex({ + const name = await collection.createSearchIndex({ name: 'test-search-index', definition: { mappings: { dynamic: false } } }); + expect(name).to.equal('test-search-index'); + await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable), indexName: 'test-search-index' @@ -166,13 +170,15 @@ describe('Index Management Prose Tests', function () { }); it('Case 4: Driver can update a search index', metadata, async function () { - await collection.createSearchIndex({ + const name = await collection.createSearchIndex({ name: 'test-search-index', definition: { mappings: { dynamic: false } } }); + expect(name).to.equal('test-search-index'); + await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable), indexName: 'test-search-index' From e13080328f9964aed748473e8ec37204883a59d9 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Mon, 31 Jul 2023 11:35:49 -0600 Subject: [PATCH 6/7] fixup tests --- .../search-index-management.prose.test.ts | 121 ++++++++++++++---- 1 file changed, 99 insertions(+), 22 deletions(-) diff --git a/test/manual/search-index-management.prose.test.ts b/test/manual/search-index-management.prose.test.ts index 24b5601aea6..a4f4cb33be9 100644 --- a/test/manual/search-index-management.prose.test.ts +++ b/test/manual/search-index-management.prose.test.ts @@ -4,11 +4,11 @@ import { Readable } from 'stream'; import { clearTimeout, setTimeout as setTimeoutCb } from 'timers'; import { setInterval } from 'timers/promises'; -import { type Collection, type Document, type MongoClient, ObjectId } from '../mongodb'; +import { type Collection, type Document, isSuperset, type MongoClient, ObjectId } from '../mongodb'; class TimeoutController extends AbortController { timeoutId: NodeJS.Timeout; - constructor(private timeoutMS: number) { + constructor(timeoutMS: number) { super(); this.timeoutId = setTimeoutCb(() => { @@ -39,20 +39,24 @@ describe('Index Management Prose Tests', function () { let collection: Collection; /** - * waits until the search indexes for `collection` satisfy `predicate`, optionally pre-filtering + * waits until the search indexes for `collection` satisfy `predicate`. + * + * This optionally pre-filtering * for indexes with name = `indexName` */ function waitForIndexes({ predicate, - indexName + indexNames }: { predicate: (arg0: Array) => boolean; - indexName?: string; + indexNames: string | string[]; }): Promise> { + const names = new Set([indexNames].flat()); return Readable.from( setInterval(5000, undefined, { signal: timeoutController.signal, ref: false }) ) - .map(() => collection.listSearchIndexes(indexName).toArray()) + .map(() => collection.listSearchIndexes().toArray()) + .map((indexes: Document[]) => indexes.filter(index => names.has(index.name))) .find(predicate); } @@ -71,6 +75,7 @@ describe('Index Management Prose Tests', function () { client = this.configuration.newClient(); await client.connect(); + // Create a collection with the "create" command using a randomly generated name (referred to as coll0). collection = await client.db('node-test').createCollection(new ObjectId().toHexString()); timeoutController = new TimeoutController(60 * 1000 * 4); @@ -86,6 +91,13 @@ describe('Index Management Prose Tests', function () { 'Case 1: Driver can successfully create and list search indexes', metadata, async function () { + // Create a new search index on coll0 with the createSearchIndex helper. Use the following definition: + // { + // name: 'test-search-index', + // definition: { + // mappings: { dynamic: false } + // } + // } const name = await collection.createSearchIndex({ name: 'test-search-index', definition: { @@ -93,13 +105,17 @@ describe('Index Management Prose Tests', function () { } }); + // Assert that the command returns the name of the index: "test-search-index". expect(name).to.equal('test-search-index'); + // Run coll0.listSearchIndexes() repeatedly every 5 seconds until the following condition is satisfied and store the value in a variable index: + // 1. An index with the name of test-search-index is present and the index has a field queryable with a value of true. const [index] = await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable), - indexName: 'test-search-index' + indexNames: 'test-search-index' }); + // Assert that index has a property latestDefinition whose value is { 'mappings': { 'dynamic': false } } expect(index).to.exist; expect(index) .to.have.property('latestDefinition') @@ -111,6 +127,19 @@ describe('Index Management Prose Tests', function () { 'Case 2: Driver can successfully create multiple indexes in batch', metadata, async function () { + // Create two new search indexes on coll0 with the createSearchIndexes helper. Use the following definitions when creating the indexes. These definitions are referred to as indexDefinitions. + // { + // name: 'test-search-index-1', + // definition: { + // mappings: { dynamic: false } + // } + // } + // { + // name: 'test-search-index-2', + // definition: { + // mappings: { dynamic: false } + // } + // } const indexDefinitions = [ { name: 'test-search-index-1', @@ -127,24 +156,39 @@ describe('Index Management Prose Tests', function () { ]; const names = await collection.createSearchIndexes(indexDefinitions); + + // Assert that the command returns an array containing the new indexes' names: ["test-search-index-1", "test-search-index-2"]. expect(names).to.deep.equal(['test-search-index-1', 'test-search-index-2']); + // Run coll0.listSearchIndexes() repeatedly every 5 seconds until the following condition is satisfied. + // 1. An index with the name of test-search-index-1 is present and index has a field queryable with the value of true. Store result in index1. + // 2. An index with the name of test-search-index-2 is present and index has a field queryable with the value of true. Store result in index2. const indexes = await waitForIndexes({ - predicate: indexes => indexes.every(index => index.queryable) + predicate: indexes => indexes.every(index => index.queryable), + indexNames: ['test-search-index-1', 'test-search-index-2'] }); - for (const indexDescription of indexDefinitions) { - const index = indexes.find(({ name }) => name === indexDescription.name); - expect(index, `expected ${indexDescription.name} to exist`).to.exist; + const index1 = indexes.find(({ name }) => name === 'test-search-index-1'); + const index2 = indexes.find(({ name }) => name === 'test-search-index-2'); - expect(index) - .to.have.property('latestDefinition') - .to.deep.equal({ mappings: { dynamic: false } }); - } + // Assert that index1 and index2 have the property latestDefinition whose value is { "mappings" : { "dynamic" : false } } + expect(index1) + .to.have.property('latestDefinition') + .to.deep.equal({ mappings: { dynamic: false } }); + expect(index2) + .to.have.property('latestDefinition') + .to.deep.equal({ mappings: { dynamic: false } }); } ); it('Case 3: Driver can successfully drop search indexes', metadata, async function () { + // Create a new search index on coll0 with the following definition: + // { + // name: 'test-search-index', + // definition: { + // mappings: { dynamic: false } + // } + // } const name = await collection.createSearchIndex({ name: 'test-search-index', definition: { @@ -152,24 +196,37 @@ describe('Index Management Prose Tests', function () { } }); + // Assert that the command returns the name of the index: "test-search-index". expect(name).to.equal('test-search-index'); + // Run coll0.listSearchIndexes() repeatedly every 5 seconds until the following condition is satisfied: + // 1. An index with the name of test-search-index is present and index has a field queryable with the value of true. await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable), - indexName: 'test-search-index' + indexNames: 'test-search-index' }); + // Run a dropSearchIndex on coll0, using test-search-index for the name. await collection.dropSearchIndex('test-search-index'); + // Run coll0.listSearchIndexes() repeatedly every 5 seconds until listSearchIndexes returns an empty array. + // This test fails if it times out waiting for the deletion to succeed. const indexes = await waitForIndexes({ predicate: indexes => indexes.length === 0, - indexName: 'test-search-index' + indexNames: 'test-search-index' }); expect(indexes).to.deep.equal([]); }); it('Case 4: Driver can update a search index', metadata, async function () { + // Create a new search index on coll0 with the following definition: + // { + // name: 'test-search-index', + // definition: { + // mappings: { dynamic: false } + // } + // } const name = await collection.createSearchIndex({ name: 'test-search-index', definition: { @@ -177,22 +234,40 @@ describe('Index Management Prose Tests', function () { } }); + // Assert that the command returns the name of the index: "test-search-index". expect(name).to.equal('test-search-index'); + // Run coll0.listSearchIndexes() repeatedly every 5 seconds until the following condition is satisfied: + // 1. An index with the name of test-search-index is present and index has a field queryable with the value of true. await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable), - indexName: 'test-search-index' + indexNames: 'test-search-index' }); + // Run a updateSearchIndex on coll0, using the following definition. + // { + // name: 'test-search-index', + // definition: { + // mappings: { dynamic: true } + // } + // } await collection.updateSearchIndex('test-search-index', { mappings: { dynamic: true } }); - const [updatedIndex] = await waitForIndexes({ + // Assert that the command does not error and the server responds with a success. + // The above command throws on failure. + + // Run coll0.listSearchIndexes() repeatedly every 5 seconds until the following condition is satisfied: + // 1. An index with the name of test-search-index is present. This index is referred to as index. + // 2. The index has a field queryable with a value of true and has a field status with the value of READY. + const [index2] = await waitForIndexes({ predicate: indexes => indexes.every(index => index.queryable && index.status === 'READY'), - indexName: 'test-search-index' + indexNames: 'test-search-index' }); - expect(updatedIndex).to.have.property('name', 'test-search-index'); - expect(updatedIndex) + // Assert that an index is present with the name test-search-index and the definition has a + // property latestDefinition whose value is { 'mappings': { 'dynamic': true } }. + expect(index2).to.have.property('name', 'test-search-index'); + expect(index2) .to.have.property('latestDefinition') .to.deep.equal({ mappings: { dynamic: true } }); }); @@ -201,8 +276,10 @@ describe('Index Management Prose Tests', function () { 'Case 5: `dropSearchIndex` suppresses namespace not found errors', metadata, async function () { + // Create a driver-side collection object for a randomly generated collection name. Do not create this collection on the server. const collection = await client.db('node-test').collection(new ObjectId().toHexString()); + // Run a dropSearchIndex command and assert that no error is thrown. await collection.dropSearchIndex('test-search-index'); } ); From bd1d8ec13a55e9d3e2616d91e0baa657f7acb337 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Mon, 31 Jul 2023 13:12:37 -0600 Subject: [PATCH 7/7] fix lint --- test/manual/search-index-management.prose.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/manual/search-index-management.prose.test.ts b/test/manual/search-index-management.prose.test.ts index a4f4cb33be9..4e676ee34e2 100644 --- a/test/manual/search-index-management.prose.test.ts +++ b/test/manual/search-index-management.prose.test.ts @@ -4,7 +4,7 @@ import { Readable } from 'stream'; import { clearTimeout, setTimeout as setTimeoutCb } from 'timers'; import { setInterval } from 'timers/promises'; -import { type Collection, type Document, isSuperset, type MongoClient, ObjectId } from '../mongodb'; +import { type Collection, type Document, type MongoClient, ObjectId } from '../mongodb'; class TimeoutController extends AbortController { timeoutId: NodeJS.Timeout;