Skip to content

Commit ed8eee3

Browse files
authored
test(NODE-5799): search index management operations fail with a different error message (#3954)
1 parent a4776cf commit ed8eee3

11 files changed

+230
-45
lines changed

test/spec/index-management/README.rst

+177-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ For each of the configurations:
3131
indicated indexes act on
3232

3333
Tests
34-
-----
3534

3635
- Run the driver's method that returns a list of index names, and:
3736

@@ -45,4 +44,180 @@ Tests
4544
- verify the "unique" flags show up for the unique index
4645
- verify there are no duplicates in the returned list
4746
- if the result consists of statically defined index models that include an ``ns`` field, verify
48-
that its value is accurate
47+
that its value is accurate
48+
49+
Search Index Management Helpers
50+
-------------------------------
51+
52+
These tests are intended to smoke test the search management helpers end-to-end against a live Atlas cluster.
53+
54+
The search index management commands are asynchronous and mongod/mongos returns before the changes to a clusters' search indexes have completed. When
55+
these prose tests specify "waiting for the changes", drivers should repeatedly poll the cluster with ``listSearchIndexes``
56+
until the changes are visible. Each test specifies the condition that is considered "ready". For example, when creating a
57+
new search index, waiting until the inserted index has a status ``queryable: true`` indicates that the index was successfully
58+
created.
59+
60+
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
61+
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.
62+
63+
There is a server-side limitation that prevents multiple search indexes from being created with the same name, definition and
64+
collection name. This limitation does not take into account collection uuid. Because these commands are asynchronous, any cleanup
65+
code that may run after a test (cleaning a database or dropping search indexes) may not have completed by the next iteration of the
66+
test (or the next test run, if running locally). To address this issue, each test uses a randomly generated collection name. Drivers
67+
may generate this collection name however they like, but a suggested implementation is a hex representation of an
68+
ObjectId (``new ObjectId().toHexString()`` in Node).
69+
70+
Setup
71+
~~~~~
72+
73+
These tests must run against an Atlas cluster with a 7.0+ server. `Scripts are available <https://github.com/mongodb-labs/drivers-evergreen-tools/tree/master/.evergreen/atlas>`_ in drivers-evergreen-tools which can setup and teardown
74+
Atlas clusters. To ensure that the Atlas cluster is cleaned up after each CI run, drivers should configure evergreen to run these tests
75+
as a part of a task group. Be sure that the cluster gets torn down!
76+
77+
When working locally on these tests, the same Atlas setup and teardown scripts can be used locally to provision a cluster for development.
78+
79+
Case 1: Driver can successfully create and list search indexes
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81+
82+
#. Create a collection with the "create" command using a randomly generated name (referred to as ``coll0``).
83+
#. Create a new search index on ``coll0`` with the ``createSearchIndex`` helper. Use the following definition:
84+
85+
.. code:: typescript
86+
87+
{
88+
name: 'test-search-index',
89+
definition: {
90+
mappings: { dynamic: false }
91+
}
92+
}
93+
94+
#. Assert that the command returns the name of the index: ``"test-search-index"``.
95+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until the following condition is satisfied and store the value in a variable ``index``:
96+
97+
- An index with the ``name`` of ``test-search-index`` is present and the index has a field ``queryable`` with a value of ``true``.
98+
99+
#. Assert that ``index`` has a property ``latestDefinition`` whose value is ``{ 'mappings': { 'dynamic': false } }``
100+
101+
Case 2: Driver can successfully create multiple indexes in batch
102+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103+
104+
#. Create a collection with the "create" command using a randomly generated name (referred to as ``coll0``).
105+
#. Create two new search indexes on ``coll0`` with the ``createSearchIndexes`` helper. Use the following
106+
definitions when creating the indexes. These definitions are referred to as ``indexDefinitions``.
107+
108+
.. code:: typescript
109+
110+
{
111+
name: 'test-search-index-1',
112+
definition: {
113+
mappings: { dynamic: false }
114+
}
115+
}
116+
117+
{
118+
name: 'test-search-index-2',
119+
definition: {
120+
mappings: { dynamic: false }
121+
}
122+
}
123+
124+
#. Assert that the command returns an array containing the new indexes' names: ``["test-search-index-1", "test-search-index-2"]``.
125+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until the following conditions are satisfied.
126+
127+
- 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``.
128+
- 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``.
129+
130+
#. Assert that ``index1`` and ``index2`` have the property ``latestDefinition`` whose value is ``{ "mappings" : { "dynamic" : false } }``
131+
132+
Case 3: Driver can successfully drop search indexes
133+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134+
135+
#. Create a collection with the "create" command using a randomly generated name (referred to as ``coll0``).
136+
#. Create a new search index on ``coll0`` with the following definition:
137+
138+
.. code:: typescript
139+
140+
{
141+
name: 'test-search-index',
142+
definition: {
143+
mappings: { dynamic: false }
144+
}
145+
}
146+
147+
#. Assert that the command returns the name of the index: ``"test-search-index"``.
148+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until the following condition is satisfied:
149+
150+
- An index with the ``name`` of ``test-search-index`` is present and index has a field ``queryable`` with the value of ``true``.
151+
152+
#. Run a ``dropSearchIndex`` on ``coll0``, using ``test-search-index`` for the name.
153+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until ``listSearchIndexes`` returns an empty array.
154+
155+
This test fails if it times out waiting for the deletion to succeed.
156+
157+
Case 4: Driver can update a search index
158+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159+
160+
#. Create a collection with the "create" command using a randomly generated name (referred to as ``coll0``).
161+
#. Create a new search index on ``coll0`` with the following definition:
162+
163+
.. code:: typescript
164+
165+
{
166+
name: 'test-search-index',
167+
definition: {
168+
mappings: { dynamic: false }
169+
}
170+
}
171+
172+
#. Assert that the command returns the name of the index: ``"test-search-index"``.
173+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until the following condition is satisfied:
174+
175+
- An index with the ``name`` of ``test-search-index`` is present and index has a field ``queryable`` with the value of ``true``.
176+
177+
#. Run a ``updateSearchIndex`` on ``coll0``, using the following definition.
178+
179+
.. code:: typescript
180+
181+
{
182+
name: 'test-search-index',
183+
definition: {
184+
mappings: { dynamic: true }
185+
}
186+
}
187+
188+
#. Assert that the command does not error and the server responds with a success.
189+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until the following conditions are satisfied:
190+
191+
- An index with the ``name`` of ``test-search-index`` is present. This index is referred to as ``index``.
192+
- The index has a field ``queryable`` with a value of ``true`` and has a field ``status`` with the value of ``READY``.
193+
194+
#. 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 } }``.
195+
196+
Case 5: ``dropSearchIndex`` suppresses namespace not found errors
197+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
198+
199+
#. Create a driver-side collection object for a randomly generated collection name. Do not create this collection on the server.
200+
#. Run a ``dropSearchIndex`` command and assert that no error is thrown.
201+
202+
Case 6: Driver can successfully create and list search indexes with non-default readConcern and writeConcern
203+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204+
205+
#. Create a collection with the "create" command using a randomly generated name (referred to as ``coll0``).
206+
#. Apply a write concern ``WriteConcern(w=1)`` and a read concern with ``ReadConcern(level="majority")`` to ``coll0``.
207+
#. Create a new search index on ``coll0`` with the ``createSearchIndex`` helper. Use the following definition:
208+
209+
.. code:: typescript
210+
211+
{
212+
name: 'test-search-index-case6',
213+
definition: {
214+
mappings: { dynamic: false }
215+
}
216+
}
217+
218+
#. Assert that the command returns the name of the index: ``"test-search-index-case6"``.
219+
#. Run ``coll0.listSearchIndexes()`` repeatedly every 5 seconds until the following condition is satisfied and store the value in a variable ``index``:
220+
221+
- An index with the ``name`` of ``test-search-index-case6`` is present and the index has a field ``queryable`` with a value of ``true``.
222+
223+
#. Assert that ``index`` has a property ``latestDefinition`` whose value is ``{ 'mappings': { 'dynamic': false } }``

test/spec/index-management/createSearchIndex.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
},
5656
"expectError": {
5757
"isError": true,
58-
"errorContains": "Search index commands are only supported with Atlas"
58+
"errorContains": "Atlas"
5959
}
6060
}
6161
],
@@ -102,7 +102,7 @@
102102
},
103103
"expectError": {
104104
"isError": true,
105-
"errorContains": "Search index commands are only supported with Atlas"
105+
"errorContains": "Atlas"
106106
}
107107
}
108108
],

test/spec/index-management/createSearchIndex.yml

+9-7
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ tests:
2828
arguments:
2929
model: { definition: &definition { mappings: { dynamic: true } } }
3030
expectError:
31-
# Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing
32-
# against an Atlas cluster and the expectError will be removed.
31+
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting
32+
# that the driver constructs and sends the correct command.
33+
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages.
3334
isError: true
34-
errorContains: Search index commands are only supported with Atlas
35+
errorContains: Atlas
3536
expectEvents:
3637
- client: *client0
3738
events:
@@ -48,15 +49,16 @@ tests:
4849
arguments:
4950
model: { definition: &definition { mappings: { dynamic: true } } , name: 'test index' }
5051
expectError:
51-
# Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing
52-
# against an Atlas cluster and the expectError will be removed.
52+
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting
53+
# that the driver constructs and sends the correct command.
54+
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages.
5355
isError: true
54-
errorContains: Search index commands are only supported with Atlas
56+
errorContains: Atlas
5557
expectEvents:
5658
- client: *client0
5759
events:
5860
- commandStartedEvent:
5961
command:
6062
createSearchIndexes: *collection0
6163
indexes: [ { definition: *definition, name: 'test index' } ]
62-
$db: *database0
64+
$db: *database0

test/spec/index-management/createSearchIndexes.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
},
5050
"expectError": {
5151
"isError": true,
52-
"errorContains": "Search index commands are only supported with Atlas"
52+
"errorContains": "Atlas"
5353
}
5454
}
5555
],
@@ -89,7 +89,7 @@
8989
},
9090
"expectError": {
9191
"isError": true,
92-
"errorContains": "Search index commands are only supported with Atlas"
92+
"errorContains": "Atlas"
9393
}
9494
}
9595
],
@@ -138,7 +138,7 @@
138138
},
139139
"expectError": {
140140
"isError": true,
141-
"errorContains": "Search index commands are only supported with Atlas"
141+
"errorContains": "Atlas"
142142
}
143143
}
144144
],

test/spec/index-management/createSearchIndexes.yml

+13-10
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ tests:
2828
arguments:
2929
models: []
3030
expectError:
31-
# Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing
32-
# against an Atlas cluster and the expectError will be removed.
31+
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting
32+
# that the driver constructs and sends the correct command.
33+
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages.
3334
isError: true
34-
errorContains: Search index commands are only supported with Atlas
35+
errorContains: Atlas
3536
expectEvents:
3637
- client: *client0
3738
events:
@@ -49,10 +50,11 @@ tests:
4950
arguments:
5051
models: [ { definition: &definition { mappings: { dynamic: true } } } ]
5152
expectError:
52-
# Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing
53-
# against an Atlas cluster and the expectError will be removed.
53+
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting
54+
# that the driver constructs and sends the correct command.
55+
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages.
5456
isError: true
55-
errorContains: Search index commands are only supported with Atlas
57+
errorContains: Atlas
5658
expectEvents:
5759
- client: *client0
5860
events:
@@ -69,15 +71,16 @@ tests:
6971
arguments:
7072
models: [ { definition: &definition { mappings: { dynamic: true } } , name: 'test index' } ]
7173
expectError:
72-
# Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing
73-
# against an Atlas cluster and the expectError will be removed.
74+
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting
75+
# that the driver constructs and sends the correct command.
76+
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages.
7477
isError: true
75-
errorContains: Search index commands are only supported with Atlas
78+
errorContains: Atlas
7679
expectEvents:
7780
- client: *client0
7881
events:
7982
- commandStartedEvent:
8083
command:
8184
createSearchIndexes: *collection0
8285
indexes: [ { definition: *definition, name: 'test index' } ]
83-
$db: *database0
86+
$db: *database0

test/spec/index-management/dropSearchIndex.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
},
5050
"expectError": {
5151
"isError": true,
52-
"errorContains": "Search index commands are only supported with Atlas"
52+
"errorContains": "Atlas"
5353
}
5454
}
5555
],

test/spec/index-management/dropSearchIndex.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ tests:
2828
arguments:
2929
name: &indexName 'test index'
3030
expectError:
31-
# Search indexes are only available on 7.0+ atlas clusters. DRIVERS-2630 will add e2e testing
32-
# against an Atlas cluster and the expectError will be removed.
31+
# This test always errors in a non-Atlas environment. The test functions as a unit test by asserting
32+
# that the driver constructs and sends the correct command.
33+
# The expected error message was changed in SERVER-83003. Check for the substring "Atlas" shared by both error messages.
3334
isError: true
34-
errorContains: Search index commands are only supported with Atlas
35+
errorContains: Atlas
3536
expectEvents:
3637
- client: *client0
3738
events:

test/spec/index-management/listSearchIndexes.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"object": "collection0",
4747
"expectError": {
4848
"isError": true,
49-
"errorContains": "Search index commands are only supported with Atlas"
49+
"errorContains": "Atlas"
5050
}
5151
}
5252
],
@@ -81,7 +81,7 @@
8181
},
8282
"expectError": {
8383
"isError": true,
84-
"errorContains": "Search index commands are only supported with Atlas"
84+
"errorContains": "Atlas"
8585
}
8686
}
8787
],
@@ -122,7 +122,7 @@
122122
},
123123
"expectError": {
124124
"isError": true,
125-
"errorContains": "Search index commands are only supported with Atlas"
125+
"errorContains": "Atlas"
126126
}
127127
}
128128
],

0 commit comments

Comments
 (0)