Skip to content

Commit 65ff27c

Browse files
committed
Add Transactions Spec Tests
GODRIVER-286 Change-Id: I778f6b7b22324e83749bea3a21515a02e6a729c3
1 parent 99bff7b commit 65ff27c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+24554
-589
lines changed

data/transactions/README.rst

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
==================
2+
Transactions Tests
3+
==================
4+
5+
.. contents::
6+
7+
----
8+
9+
Introduction
10+
============
11+
12+
The YAML and JSON files in this directory are platform-independent tests that
13+
drivers can use to prove their conformance to the Transactions Spec. They are
14+
designed with the intention of sharing some test-runner code with the CRUD Spec
15+
tests and the Command Monitoring Spec tests.
16+
17+
Several prose tests, which are not easily expressed in YAML, are also presented
18+
in this file. Those tests will need to be manually implemented by each driver.
19+
20+
Server Fail Point
21+
=================
22+
23+
Some tests depend on a server fail point, expressed in the ``failPoint`` field.
24+
For example the ``failCommand`` fail point allows the client to force the
25+
server to return an error. Keep in mind that the fail point only triggers for
26+
commands listed in the "failCommands" field. See `SERVER-35004`_ and
27+
`SERVER-35083`_ for more information.
28+
29+
.. _SERVER-35004: https://jira.mongodb.org/browse/SERVER-35004
30+
.. _SERVER-35083: https://jira.mongodb.org/browse/SERVER-35083
31+
32+
The ``failCommand`` fail point may be configured like so::
33+
34+
db.adminCommand({
35+
configureFailPoint: "failCommand",
36+
mode: <string|document>,
37+
data: {
38+
failCommands: ["commandName", "commandName2"],
39+
closeConnection: <true|false>,
40+
errorCode: <Number>,
41+
writeConcernError: <document>
42+
}
43+
});
44+
45+
``mode`` is a generic fail point option and may be assigned a string or document
46+
value. The string values ``"alwaysOn"`` and ``"off"`` may be used to enable or
47+
disable the fail point, respectively. A document may be used to specify either
48+
``times`` or ``skip``, which are mutually exclusive:
49+
50+
- ``{ times: <integer> }`` may be used to limit the number of times the fail
51+
point may trigger before transitioning to ``"off"``.
52+
- ``{ skip: <integer> }`` may be used to defer the first trigger of a fail
53+
point, after which it will transition to ``"alwaysOn"``.
54+
55+
The ``data`` option is a document that may be used to specify options that
56+
control the fail point's behavior. ``failCommand`` supports the following
57+
``data`` options, which may be combined if desired:
58+
59+
- ``failCommands``: Required, the list of command names to fail.
60+
- ``closeConnection``: Boolean option, which defaults to ``false``. If
61+
``true``, the connection on which the command is executed will be closed
62+
and the client will see a network error.
63+
- ``errorCode``: Integer option, which is unset by default. If set, the
64+
specified command error code will be returned as a command error.
65+
- ``writeConcernError``: A document, which is unset by default. If set, the
66+
server will return this document in the "writeConcernError" field. This
67+
failure response only applies to commands that support write concern and
68+
happens *after* the command finishes (regardless of success or failure).
69+
70+
Test Format
71+
===========
72+
73+
Each YAML file has the following keys:
74+
75+
- ``database_name`` and ``collection_name``: The database and collection to use
76+
for testing.
77+
78+
- ``data``: The data that should exist in the collection under test before each
79+
test run.
80+
81+
- ``tests``: An array of tests that are to be run independently of each other.
82+
Each test will have some or all of the following fields:
83+
84+
- ``description``: The name of the test.
85+
86+
- ``clientOptions``: Optional, parameters to pass to MongoClient().
87+
88+
- ``failPoint``: Optional, a server failpoint to enable expressed as the
89+
configureFailPoint command to run on the admin database.
90+
91+
- ``sessionOptions``: Optional, parameters to pass to
92+
MongoClient.startSession().
93+
94+
- ``operations``: Array of documents, each describing an operation to be
95+
executed. Each document has the following fields:
96+
97+
- ``name``: The name of the operation on ``object``.
98+
99+
- ``object``: The name of the object to perform the operation on. Can be
100+
"database", "collection", "session0", or "session1".
101+
102+
- ``collectionOptions``: Optional, parameters to pass to the Collection()
103+
used for this operation.
104+
105+
- ``command_name``: Present only when ``name`` is "runCommand". The name
106+
of the command to run. Required for languages that are unable preserve
107+
the order keys in the "command" argument when parsing JSON/YAML.
108+
109+
- ``arguments``: Optional, the names and values of arguments.
110+
111+
- ``result``: The return value from the operation, if any. This field may
112+
be a single document or an array of documents in the case of a
113+
multi-document read. If the operation is expected to return an error, the
114+
``result`` is a single document that has one or more of the following
115+
fields:
116+
117+
- ``errorContains``: A substring of the expected error message.
118+
119+
- ``errorCodeName``: The expected "codeName" field in the server
120+
error response.
121+
122+
- ``errorLabelsContain``: A list of error label strings that the
123+
error is expected to have.
124+
125+
- ``errorLabelsOmit``: A list of error label strings that the
126+
error is expected not to have.
127+
128+
- ``expectations``: Optional list of command-started events.
129+
130+
- ``outcome``: Document describing the return value and/or expected state of
131+
the collection after the operation is executed. Contains the following
132+
fields:
133+
134+
- ``collection``:
135+
136+
- ``data``: The data that should exist in the collection after the
137+
operations have run.
138+
139+
Use as integration tests
140+
========================
141+
142+
Run a MongoDB replica set with a primary, a secondary, and an arbiter,
143+
**server version 4.0.0-rc4 or later**. (Including a secondary ensures that
144+
server selection in a transaction works properly. Including an arbiter helps
145+
ensure that no new bugs have been introduced related to arbiters.)
146+
147+
Load each YAML (or JSON) file using a Canonical Extended JSON parser.
148+
149+
Then for each element in ``tests``:
150+
151+
#. Create a MongoClient and call
152+
``client.admin.runCommand({killAllSessions: []})`` to clean up any open
153+
transactions from previous test failures. The command will fail with message
154+
"operation was interrupted", because it kills its own implicit session. Catch
155+
the exception and continue.
156+
#. Create a collection object from the MongoClient, using the ``database_name``
157+
and ``collection_name`` fields of the YAML file.
158+
#. Drop the test collection, using writeConcern "majority".
159+
#. Execute the "create" command to recreate the collection, using writeConcern
160+
"majority". (Creating the collection inside a transaction is prohibited, so
161+
create it explicitly.)
162+
#. If the YAML file contains a ``data`` array, insert the documents in ``data``
163+
into the test collection, using writeConcern "majority".
164+
#. If ``failPoint`` is specified, its value is a configureFailPoint command.
165+
Run the command on the admin database to enable the fail point.
166+
#. Create a **new** MongoClient ``client``, with Command Monitoring listeners
167+
enabled. (Using a new MongoClient for each test ensures a fresh session pool
168+
that hasn't executed any transactions previously, so the tests can assert
169+
actual txnNumbers, starting from 1.) Pass this test's ``clientOptions`` if
170+
present.
171+
#. Call ``client.startSession`` twice to create ClientSession objects
172+
``session0`` and ``session1``, using the test's "sessionOptions" if they
173+
are present. Save their lsids so they are available after calling
174+
``endSession``, see `Logical Session Id`.
175+
#. For each element in ``operations``:
176+
177+
- Enter a "try" block or your programming language's closest equivalent.
178+
- Create a Database object from the MongoClient, using the ``database_name``
179+
field at the top level of the test file.
180+
- Create a Collection object from the Database, using the
181+
``collection_name`` field at the top level of the test file.
182+
If ``collectionOptions`` is present create the Collection object with the
183+
provided options. Otherwise create the object with the default options.
184+
- Execute the named method on the provided ``object``, passing the
185+
arguments listed. Pass ``session0`` or ``session1`` to the method,
186+
depending on which session's name is in the arguments list.
187+
If ``arguments`` contains no "session", pass no explicit session to the
188+
method.
189+
- If the driver throws an exception / returns an error while executing this
190+
series of operations, store the error message and server error code.
191+
- If the result document has an "errorContains" field, verify that the
192+
method threw an exception or returned an error, and that the value of the
193+
"errorContains" field matches the error string. "errorContains" is a
194+
substring (case-insensitive) of the actual error message.
195+
196+
If the result document has an "errorCodeName" field, verify that the
197+
method threw a command failed exception or returned an error, and that
198+
the value of the "errorCodeName" field matches the "codeName" in the
199+
server error response.
200+
201+
If the result document has an "errorLabelsContain" field, verify that the
202+
method threw an exception or returned an error. Verify that all of the
203+
error labels in "errorLabelsContain" are present in the error or exception
204+
using the ``hasErrorLabel`` method.
205+
206+
If the result document has an "errorLabelsOmit" field, verify that the
207+
method threw an exception or returned an error. Verify that none of the
208+
error labels in "errorLabelsOmit" are present in the error or exception
209+
using the ``hasErrorLabel`` method.
210+
- If the operation returns a raw command response, eg from ``runCommand``,
211+
then compare only the fields present in the expected result document.
212+
Otherwise, compare the method's return value to ``result`` using the same
213+
logic as the CRUD Spec Tests runner.
214+
215+
#. Call ``session0.endSession()`` and ``session1.endSession``.
216+
#. If the test includes a list of command-started events in ``expectations``,
217+
compare them to the actual command-started events using the
218+
same logic as the Command Monitoring Spec Tests runner, plus the rules in
219+
the Command-Started Events instructions below.
220+
#. If ``failPoint`` is specified, disable the fail point to avoid spurious
221+
failures in subsequent tests. The fail point may be disabled like so::
222+
223+
db.adminCommand({
224+
configureFailPoint: <fail point name>,
225+
mode: "off"
226+
});
227+
228+
#. For each element in ``outcome``:
229+
230+
- If ``name`` is "collection", verify that the test collection contains
231+
exactly the documents in the ``data`` array. Ensure this find uses
232+
Primary read preference even when the MongoClient is configured with
233+
another read preference.
234+
235+
Command-Started Events
236+
``````````````````````
237+
238+
The event listener used for these tests MUST ignore the security commands
239+
listed in the Command Monitoring Spec.
240+
241+
Logical Session Id
242+
~~~~~~~~~~~~~~~~~~
243+
244+
Each command-started event in ``expectations`` includes an ``lsid`` with the
245+
value "session0" or "session1". Tests MUST assert that the command's actual
246+
``lsid`` matches the id of the correct ClientSession named ``session0`` or
247+
``session1``.
248+
249+
Null Values
250+
~~~~~~~~~~~
251+
252+
Some command-started events in ``expectations`` include ``null`` values for
253+
fields such as ``txnNumber``, ``autocommit``, and ``writeConcern``.
254+
Tests MUST assert that the actual command **omits** any field that has a
255+
``null`` value in the expected command.
256+
257+
Cursor Id
258+
^^^^^^^^^
259+
260+
A ``getMore`` value of ``"42"`` in a command-started event is a fake cursorId
261+
that MUST be ignored. (In the Command Monitoring Spec tests, fake cursorIds are
262+
correlated with real ones, but that is not necessary for Transactions Spec
263+
tests.)
264+
265+
afterClusterTime
266+
^^^^^^^^^^^^^^^^
267+
268+
A ``readConcern.afterClusterTime`` value of ``42`` in a command-started event
269+
is a fake cluster time. Drivers MUST assert that the actual command includes an
270+
afterClusterTime.

0 commit comments

Comments
 (0)