diff --git a/.evergreen/config.in.yml b/.evergreen/config.in.yml index dd30ee38a3e..df9df455f78 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 @@ -1438,6 +1444,34 @@ task_groups: tasks: - test-aws-lambda-deployed + - name: test_atlas_task_group_search_indexes + setup_group: + - func: fetch source + - command: subprocess.exec + params: + 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-search-index-helpers + pre: - func: "fetch source" - func: "windows fix" diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 8b1c7752674..55d2fef4b00 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,33 @@ task_groups: 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: + 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-search-index-helpers pre: - func: fetch source - func: windows fix @@ -4063,8 +4085,8 @@ buildvariants: tasks: - test-lambda-example - test-lambda-aws-auth-example - - name: rhel8-test-seach-index-management-helpers - display_name: Search Index Management Helpers Tests + - name: rhel8-test-search-indexes + display_name: Search Index Tests run_on: rhel80-large tasks: - - test-search-index-helpers + - test_atlas_task_group_search_indexes diff --git a/.evergreen/generate_evergreen_tasks.js b/.evergreen/generate_evergreen_tasks.js index 2ef05d4fe5c..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 @@ -688,26 +689,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({ @@ -776,11 +757,11 @@ BUILD_VARIANTS.push({ }); BUILD_VARIANTS.push({ - name: 'rhel8-test-seach-index-management-helpers', - display_name: 'Search Index Management Helpers Tests', + name: 'rhel8-test-search-indexes', + display_name: 'Search Index Tests', run_on: DEFAULT_OS, - tasks: ['test-search-index-helpers'] -}) + tasks: ['test_atlas_task_group_search_indexes'] +}); // TODO(NODE-4575): unskip zstd and snappy on node 16 for (const variant of BUILD_VARIANTS.filter( 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 05ce0b5ddd8..db79bde634e 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,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..4e676ee34e2 --- /dev/null +++ b/test/manual/search-index-management.prose.test.ts @@ -0,0 +1,287 @@ +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(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; + let collection: Collection; + + /** + * waits until the search indexes for `collection` satisfy `predicate`. + * + * This optionally pre-filtering + * for indexes with name = `indexName` + */ + function waitForIndexes({ + predicate, + indexNames + }: { + predicate: (arg0: Array) => boolean; + indexNames: string | string[]; + }): Promise> { + const names = new Set([indexNames].flat()); + return Readable.from( + setInterval(5000, undefined, { signal: timeoutController.signal, ref: false }) + ) + .map(() => collection.listSearchIndexes().toArray()) + .map((indexes: Document[]) => indexes.filter(index => names.has(index.name))) + .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(); + + // 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); + }); + + afterEach(async () => { + await collection.drop(); + await client?.close(); + timeoutController?.clear(false); + }); + + it( + '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: { + mappings: { dynamic: false } + } + }); + + // 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), + 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') + .to.deep.equal({ mappings: { dynamic: false } }); + } + ); + + it( + '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', + definition: { + mappings: { dynamic: false } + } + }, + { + name: 'test-search-index-2', + definition: { + mappings: { dynamic: false } + } + } + ]; + + 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), + indexNames: ['test-search-index-1', 'test-search-index-2'] + }); + + const index1 = indexes.find(({ name }) => name === 'test-search-index-1'); + const index2 = indexes.find(({ name }) => name === 'test-search-index-2'); + + // 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: { + mappings: { dynamic: false } + } + }); + + // 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), + 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, + 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: { + mappings: { dynamic: false } + } + }); + + // 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), + 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 } }); + + // 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'), + indexNames: 'test-search-index' + }); + + // 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 } }); + }); + + it( + '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'); + } + ); + }); +}); 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 375b909a744..a07f6373ccc 100644 --- a/test/tools/runner/config.ts +++ b/test/tools/runner/config.ts @@ -74,7 +74,7 @@ export class TestConfiguration { }; serverApi: ServerApi; - 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); @@ -354,4 +354,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!; + } }