1==========
2CRUD Tests
3==========
4
5.. contents::
6
7----
8
9Introduction
10============
11
12The YAML and JSON files in this directory tree are platform-independent tests
13that drivers can use to prove their conformance to the CRUD spec.
14
15Running these integration tests will require a running MongoDB server or
16cluster with server versions 2.6.0 or later. Some tests have specific server
17version requirements as noted by the ``runOn`` section, if provided.
18
19Subdirectories for Test Formats
20-------------------------------
21
22This document describes a current test format, which should be used for any new
23CRUD tests. Additionally, it refers to a "legacy" format, which dates back to
24the initial version of the CRUD specification. Until such time that all original
25tests have been ported to the current format, tests in each format will be
26grouped in their own subdirectory:
27
28- ``v1/``: Legacy format tests
29- ``v2/``: Current format tests
30
31Since some drivers may not have a unified test runner capable of executing tests
32in both formats, segregating tests in this manner will make it easier for
33drivers to sync and feed test files to different test runners.
34
35Test Format
36===========
37
38*Note: this section pertains to test files in the "v2" directory.*
39
40Each YAML file has the following keys:
41
42- ``runOn`` (optional): An array of server version and/or topology requirements
43 for which the tests can be run. If the test environment satisfies one or more
44 of these requirements, the tests may be executed; otherwise, this file should
45 be skipped. If this field is omitted, the tests can be assumed to have no
46 particular requirements and should be executed. Each element will have some or
47 all of the following fields:
48
49 - ``minServerVersion`` (optional): The minimum server version (inclusive)
50 required to successfully run the tests. If this field is omitted, it should
51 be assumed that there is no lower bound on the required server version.
52
53 - ``maxServerVersion`` (optional): The maximum server version (inclusive)
54 against which the tests can be run successfully. If this field is omitted,
55 it should be assumed that there is no upper bound on the required server
56 version.
57
58 - ``topology`` (optional): An array of server topologies against which the
59 tests can be run successfully. Valid topologies are "single", "replicaset",
60 and "sharded". If this field is omitted, the default is all topologies (i.e.
61 ``["single", "replicaset", "sharded"]``).
62
63- ``collection_name`` (optional): The collection to use for testing.
64
65- ``database_name`` (optional): The database to use for testing.
66
67- ``data`` (optional): The data that should exist in the collection under test before each
68 test run.
69
70- ``tests``: An array of tests that are to be run independently of each other.
71 Each test will have some or all of the following fields:
72
73 - ``description``: The name of the test.
74
75 - ``skipReason`` (optional): If present, the test should be skipped and the
76 string value will specify a reason.
77
78 - ``failPoint`` (optional): The ``configureFailPoint`` command document to run
79 to configure a fail point on the primary server.
80
81 - ``clientOptions`` (optional): Names and values of options used to construct
82 the MongoClient for this test.
83
84 - ``operations``: Array of documents, each describing an operation to be
85 executed. Each document has the following fields:
86
87 - ``object`` (optional): The name of the object to perform the operation on. Can be
88 "database" or "collection". Defaults to "collection" if undefined.
89
90 - ``collectionOptions`` (optional): Names and values of options used to
91 construct the collection object for this test.
92
93 - ``name``: The name of the operation as defined in the specification.
94
95 - ``arguments``: The names and values of arguments from the specification.
96
97 - ``error`` (optional): If ``true``, the test should expect the operation
98 to emit an error or exception. If ``false`` or omitted, drivers MUST
99 assert that no error occurred.
100
101 - ``result`` (optional): The result of executing the operation. This will
102 correspond to operation's return value as defined in the specification.
103 This field may be omitted if ``error`` is ``true``. If this field is
104 present and ``error`` is ``true`` (generally for multi-statement tests),
105 the result reports information about statements that succeeded before an
106 unrecoverable failure. In that case, drivers may choose to check the
107 result object if their BulkWriteException (or equivalent) provides access
108 to a write result object.
109
110 - ``expectations`` (optional): Array of documents, each describing a
111 `CommandStartedEvent <../../command-monitoring/command-monitoring.rst#api>`_
112 from the
113 `Command Monitoring <../../command-monitoring/command-monitoring.rst>`_
114 specification. If present, drivers should use command monitoring to observe
115 events emitted during execution of the test operation(s) and assert that
116 they match the expected CommandStartedEvent(s). Each document will have the
117 following field:
118
119 - ``command_started_event``: Document corresponding to an expected
120 `CommandStartedEvent <../../command-monitoring/command-monitoring.rst#api>`_.
121
122 - ``outcome`` (optional): Document describing the expected state of the
123 collection after the operation is executed. Contains the following fields:
124
125 - ``collection``:
126
127 - ``name`` (optional): The name of the collection to verify. If this isn't
128 present then use the collection under test.
129
130 - ``data``: The data that should exist in the collection after the
131 operation has been run, sorted by "_id".
132
133Legacy Test Format for Single Operations
134----------------------------------------
135
136*Note: this section pertains to test files in the "v1" directory.*
137
138The test format above supports both multiple operations and APM expectations,
139and is consistent with the formats used by other specifications. Previously, the
140CRUD spec tests used a simplified format that only allowed for executing a
141single operation. Notable differences from the current format are as follows:
142
143- Instead of a ``tests[i].operations`` array, a single operation was defined as
144 a document in ``tests[i].operation``. That document consisted of only the
145 ``name``, ``arguments``, and an optional ``object`` field.
146
147- Instead of ``error`` and ``result`` fields within each element in the
148 ``tests[i].operations`` array, the single operation's error and result were
149 defined under the ``tests[i].outcome.error`` and ``tests[i].outcome.result``
150 fields.
151
152- Instead of a top-level ``runOn`` field, server requirements are denoted by
153 separate top-level ``minServerVersion`` and ``maxServerVersion`` fields. The
154 minimum server version is an inclusive lower bound for running the test. The
155 maximum server version is an exclusive upper bound for running the test. If a
156 field is not present, it should be assumed that there is no corresponding bound
157 on the required server version.
158
159The legacy format should not conflict with the newer, multi-operation format
160used by other specs (e.g. Transactions). It is possible to create a unified test
161runner capable of executing both formats (as some drivers do).
162
163Error Assertions for Bulk Write Operations
164==========================================
165
166When asserting errors (e.g. ``errorContains``, ``errorCodeName``) for bulk write
167operations, the test harness should inspect the ``writeConcernError`` and/or
168``writeErrors`` properties of the bulk write exception. This may not be needed for
169``errorContains`` if a driver concatenates all write and write concern error
170messages into the bulk write exception's top-level message.
171
172Test Runner Implementation
173==========================
174
175This section provides guidance for implementing a test runner.
176
177Before running the tests:
178
179- Create a global MongoClient (``globalMongoClient``) and connect to the server.
180 This client will be used for executing meta operations, such as checking
181 server versions and preparing data fixtures.
182
183For each test file:
184
185- Using ``globalMongoClient``, check that the current server version satisfies
186 one of the configurations provided in the top-level ``runOn`` field in the test
187 file (if applicable). If the
188 requirements are not satisifed, the test file should be skipped.
189
190- Determine the collection and database under test, utilizing the top-level
191 ``collection_name`` and/or ``database_name`` fields if present.
192
193- For each element in the ``tests`` array:
194
195 - Using ``globalMongoClient``, ensure that the collection and/or database
196 under test is in a "clean" state, as needed. This may be accomplished by
197 dropping the database; however, drivers may also decide to drop individual
198 collections as needed (this may be more performant).
199
200 - If the top-level ``data`` field is present in the test file, insert the
201 corresponding data into the collection under test using
202 ``globalMongoClient``.
203
204 - If the the ``failPoint`` field is present, use ``globalMongoClient`` to
205 configure the fail point on the primary server. See
206 `Server Fail Point <../../transactions/tests#server-fail-point>`_ in the
207 Transactions spec test documentation for more information.
208
209 - Create a local MongoClient (``localMongoClient``) and connect to the server.
210 This client will be used for executing the test case.
211
212 - If ``clientOptions`` is present, those options should be used to create
213 the client. Drivers MAY merge these options atop existing defaults (e.g.
214 reduced ``serverSelectionTimeoutMS`` value for faster test failures) at
215 their own discretion.
216
217 - Activate command monitoring for ``localMongoClient`` and begin capturing
218 events. Note that some events may need to be filtered out if the driver
219 uses global listeners or reports internal commands (e.g. ``isMaster``,
220 authentication).
221
222 - For each element in the ``operations`` array:
223
224 - Using ``localMongoClient``, select the appropriate ``object`` to execute
225 the operation. Default to the collection under test if this field is not
226 present.
227
228 - If ``collectionOptions`` is present, those options should be used to
229 construct the collection object.
230
231 - Given the ``name`` and ``arguments``, execute the operation on the object
232 under test. Capture the result of the operation, if any, and observe
233 whether an error occurred. If an error is encountered that includes a
234 result (e.g. BulkWriteException), extract the result object.
235
236 - If ``error`` is present and true, assert that the operation encountered an
237 error. Otherwise, assert that no error was encountered.
238
239 - if ``result`` is present, assert that it matches the operation's result.
240
241 - Deactivate command monitoring for ``localMongoClient``.
242
243 - If the ``expectations`` array is present, assert that the sequence of
244 emitted CommandStartedEvents from executing the operation(s) matches the
245 sequence of ``command_started_event`` objects in the ``expectations`` array.
246
247 - If the ``outcome`` field is present, assert the contents of the specified
248 collection using ``globalMongoClient``.
249 Note the server does not guarantee that documents returned by a find
250 command will be in inserted order. This find MUST sort by ``{_id:1}``.
251
252Evaluating Matches
253------------------
254
255The expected values for results (e.g. ``result`` for an operation
256operation, ``command_started_event.command``, elements in ``outcome.data``) are
257written in `Extended JSON <../../extended-json.rst>`_. Drivers may adopt any of
258the following approaches to comparisons, as long as they are consistent:
259
260- Convert ``actual`` to Extended JSON and compare to ``expected``
261- Convert ``expected`` and ``actual`` to BSON, and compare them
262- Convert ``expected`` and ``actual`` to native representations, and compare
263 them
264
265Extra Fields in Actual Documents
266~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
267
268When comparing ``actual`` and ``expected`` *documents*, drivers should permit
269``actual`` documents to contain additional fields not present in ``expected``.
270For example, the following documents match:
271
272- ``expected`` is ``{ "x": 1 }``
273- ``actual`` is ``{ "_id": { "$oid" : "000000000000000000000001" }, "x": 1 }``
274
275In this sense, ``expected`` may be a subset of ``actual``. It may also be
276helpful to think of ``expected`` as a form of query criteria. The intention
277behind this rule is that it is not always feasible for the test to express all
278fields in the expected document(s) (e.g. session and cluster time information
279in a ``command_started_event.command`` document).
280
281This rule for allowing extra fields in ``actual`` only applies for values that
282correspond to a document. For instance, an actual result of ``[1, 2, 3, 4]`` for
283a ``distinct`` operation would not match an expected result of ``[1, 2, 3]``.
284Likewise with the ``find`` operation, this rule would only apply when matching
285documents *within* the expected result array and actual cursor.
286
287Note that in the case of result objects for some CRUD operations, ``expected``
288may condition additional, optional fields (see:
289`Optional Fields in Expected Result Objects`_).
290
291Fields that must NOT be present in Actual Documents
292~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
293
294Some command-started events in ``expectations`` include ``null`` values for
295optional fields such as ``allowDiskUse``.
296Tests MUST assert that the actual command **omits** any field that has a
297``null`` value in the expected command.
298
299Optional Fields in Expected Result Objects
300~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301
302Some ``expected`` results may include fields that are optional in the CRUD
303specification, such as ``insertedId`` (for InsertOneResult), ``insertedIds``
304(for InsertManyResult), and ``upsertedCount`` (for UpdateResult). Drivers that
305do not implement these fields should ignore them when comparing ``actual`` with
306``expected``.
307
308Prose Tests
309===========
310
311The following tests have not yet been automated, but MUST still be tested.
312
313"errInfo" is propagated
314-----------------------
315Test that a writeConcernError "errInfo" is propagated to the user in whatever way is idiomatic to the driver (exception, error object, etc.). Using a 4.0+ server, set the following failpoint:
316
317.. code:: javascript
318
319 {
320 "configureFailPoint": "failCommand",
321 "data": {
322 "failCommands": ["insert"],
323 "writeConcernError": {
324 "code": 100,
325 "codeName": "UnsatisfiableWriteConcern",
326 "errmsg": "Not enough data-bearing nodes",
327 "errInfo": {
328 "writeConcern": {
329 "w": 2,
330 "wtimeout": 0,
331 "provenance": "clientSupplied"
332 }
333 }
334 }
335 },
336 "mode": { "times": 1 }
337 }
338Then, perform an insert on the same database. Assert that an error occurs and that the "errInfo" is accessible and matches the one set in the failpoint.