These prose tests are ported from the legacy enumerate-indexes spec.
- standalone node
- replica set primary node
- replica set secondary node
- mongos node
For each of the configurations:
- Create a (new) database
- Create a collection
- Create a single column index, a compound index, and a unique index
- Insert at least one document containing all the fields that the above indicated indexes act on
- Run the driver's method that returns a list of index names, and:
- verify that all index names are represented in the result
- verify that there are no duplicate index names
- verify there are no returned indexes that do not exist
- Run the driver's method that returns a list of index information records, and:
- verify all the indexes are represented in the result
- verify the "unique" flags show up for the unique index
- verify there are no duplicates in the returned list
- if the result consists of statically defined index models that include an
ns
field, verify that its value is accurate
These tests are intended to smoke test the search management helpers end-to-end against a live Atlas cluster.
The search index management commands are asynchronous and mongod/mongos returns before the changes to a clusters' search
indexes have completed. When these prose tests specify "waiting for the changes", drivers should repeatedly poll the
cluster with listSearchIndexes
until the changes are visible. Each test specifies the condition that is considered
"ready". For example, when creating a new search index, waiting until the inserted index has a status queryable: true
indicates that the index was successfully created.
The commands tested in these prose tests take a while to successfully complete. Drivers should raise the timeout for each test to avoid timeout errors if the test timeout is too low. 5 minutes is a sufficiently large timeout that any timeout that occurs indicates a real failure, but this value is not required and can be tweaked per-driver.
There is a server-side limitation that prevents multiple search indexes from being created with the same name,
definition and collection name. This limitation does not take into account collection uuid. Because these commands are
asynchronous, any cleanup code that may run after a test (cleaning a database or dropping search indexes) may not have
completed by the next iteration of the test (or the next test run, if running locally). To address this issue, each test
uses a randomly generated collection name. Drivers may generate this collection name however they like, but a suggested
implementation is a hex representation of an ObjectId (new ObjectId().toHexString()
in Node).
These tests must run against an Atlas cluster with a 7.0+ server. Scripts are available in drivers-evergreen-tools which can setup and teardown Atlas clusters. To ensure that the Atlas cluster is cleaned up after each CI run, drivers should configure evergreen to run these tests as a part of a task group. Be sure that the cluster gets torn down!
When working locally on these tests, the same Atlas setup and teardown scripts can be used locally to provision a cluster for development.
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Create a new search index on
coll0
with thecreateSearchIndex
helper. Use the following definition:{ name: 'test-search-index', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns the name of the index:
"test-search-index"
. -
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds until the following condition is satisfied and store the value in a variableindex
:- An index with the
name
oftest-search-index
is present and the index has a fieldqueryable
with a value oftrue
.
- An index with the
-
Assert that
index
has a propertylatestDefinition
whose value is{ 'mappings': { 'dynamic': false } }
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Create two new search indexes on
coll0
with thecreateSearchIndexes
helper. Use the following definitions when creating the indexes. These definitions are referred to asindexDefinitions
.{ name: 'test-search-index-1', definition: { mappings: { dynamic: false } } } { name: 'test-search-index-2', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns an array containing the new indexes' names:
["test-search-index-1", "test-search-index-2"]
. -
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds until the following conditions are satisfied.- An index with the
name
oftest-search-index-1
is present and index has a fieldqueryable
with the value oftrue
. Store result inindex1
. - An index with the
name
oftest-search-index-2
is present and index has a fieldqueryable
with the value oftrue
. Store result inindex2
.
- An index with the
-
Assert that
index1
andindex2
have the propertylatestDefinition
whose value is{ "mappings" : { "dynamic" : false } }
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Create a new search index on
coll0
with the following definition:{ name: 'test-search-index', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns the name of the index:
"test-search-index"
. -
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds until the following condition is satisfied:- An index with the
name
oftest-search-index
is present and index has a fieldqueryable
with the value oftrue
.
- An index with the
-
Run a
dropSearchIndex
oncoll0
, usingtest-search-index
for the name. -
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds untillistSearchIndexes
returns an empty array.
This test fails if it times out waiting for the deletion to succeed.
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Create a new search index on
coll0
with the following definition:{ name: 'test-search-index', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns the name of the index:
"test-search-index"
. -
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds until the following condition is satisfied:- An index with the
name
oftest-search-index
is present and index has a fieldqueryable
with the value oftrue
.
- An index with the
-
Run a
updateSearchIndex
oncoll0
, using the following definition.{ name: 'test-search-index', definition: { mappings: { dynamic: true } } }
-
Assert that the command does not error and the server responds with a success.
-
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds until the following conditions are satisfied:- An index with the
name
oftest-search-index
is present. This index is referred to asindex
. - The index has a field
queryable
with a value oftrue
and has a fieldstatus
with the value ofREADY
.
- An index with the
-
Assert that an index is present with the name
test-search-index
and the definition has a propertylatestDefinition
whose value is{ 'mappings': { 'dynamic': true } }
.
- Create a driver-side collection object for a randomly generated collection name. Do not create this collection on the server.
- Run a
dropSearchIndex
command and assert that no error is thrown.
Case 6: Driver can successfully create and list search indexes with non-default readConcern and writeConcern
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Apply a write concern
WriteConcern(w=1)
and a read concern withReadConcern(level="majority")
tocoll0
. -
Create a new search index on
coll0
with thecreateSearchIndex
helper. Use the following definition:{ name: 'test-search-index-case6', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns the name of the index:
"test-search-index-case6"
. -
Run
coll0.listSearchIndexes()
repeatedly every 5 seconds until the following condition is satisfied and store the value in a variableindex
:- An index with the
name
oftest-search-index-case6
is present and the index has a fieldqueryable
with a value oftrue
.
- An index with the
-
Assert that
index
has a propertylatestDefinition
whose value is{ 'mappings': { 'dynamic': false } }
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Create a new search index on
coll0
with thecreateSearchIndex
helper. Use the following definition:{ name: 'test-search-index-case7-implicit', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns the name of the index:
"test-search-index-case7-implicit"
. -
Run
coll0.listSearchIndexes('test-search-index-case7-implicit')
repeatedly every 5 seconds until the following condition is satisfied and store the value in a variableindex1
:- An index with the
name
oftest-search-index-case7-implicit
is present and the index has a fieldqueryable
with a value oftrue
.
- An index with the
-
Assert that
index1
has a propertytype
whose value issearch
. -
Create a new search index on
coll0
with thecreateSearchIndex
helper. Use the following definition:{ name: 'test-search-index-case7-explicit', type: 'search', definition: { mappings: { dynamic: false } } }
-
Assert that the command returns the name of the index:
"test-search-index-case7-explicit"
. -
Run
coll0.listSearchIndexes('test-search-index-case7-explicit')
repeatedly every 5 seconds until the following condition is satisfied and store the value in a variableindex2
:- An index with the
name
oftest-search-index-case7-explicit
is present and the index has a fieldqueryable
with a value oftrue
.
- An index with the
-
Assert that
index2
has a propertytype
whose value issearch
. -
Create a new vector search index on
coll0
with thecreateSearchIndex
helper. Use the following definition:{ name: 'test-search-index-case7-vector', type: 'vectorSearch', definition: { fields: [ { type: 'vector', path: 'plot_embedding', numDimensions: 1536, similarity: 'euclidean', }, ] } }
-
Assert that the command returns the name of the index:
"test-search-index-case7-vector"
. -
Run
coll0.listSearchIndexes('test-search-index-case7-vector')
repeatedly every 5 seconds until the following condition is satisfied and store the value in a variableindex3
:- An index with the
name
oftest-search-index-case7-vector
is present and the index has a fieldqueryable
with a value oftrue
.
- An index with the
-
Assert that
index3
has a propertytype
whose value isvectorSearch
.
-
Create a collection with the "create" command using a randomly generated name (referred to as
coll0
). -
Create a new vector search index on
coll0
with thecreateSearchIndex
helper. Use the following definition:{ name: 'test-search-index-case8-error', definition: { fields: [ { type: 'vector', path: 'plot_embedding', numDimensions: 1536, similarity: 'euclidean', }, ] } }
-
Assert that the command throws an exception containing the string "Attribute mappings missing" due to the
mappings
field missing.