Skip to content

Commit ec6a028

Browse files
committed
chore(txns): add transactions yaml tests to repo
NODE-1374
1 parent 14d7f93 commit ec6a028

37 files changed

+12139
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
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+
Test Format
21+
===========
22+
23+
Each YAML file has the following keys:
24+
25+
- ``data``: The data that should exist in the collection under test before each
26+
test run. (TODO: not used yet.)
27+
28+
- ``tests``: An array of tests that are to be run independently of each other.
29+
Each test will have some or all of the following fields:
30+
31+
- ``description``: The name of the test.
32+
33+
- ``clientOptions``: Optional, parameters to pass to MongoClient().
34+
35+
- ``sessionOptions``: Optional, parameters to pass to
36+
MongoClient.startSession().
37+
38+
- ``operations``: Array of documents, each describing an operation to be
39+
executed. Each document has the following fields:
40+
41+
- ``name``: The name of the operation.
42+
43+
- ``arguments``: The names and values of arguments.
44+
45+
- ``result``: The return value from the operation, if any. If the
46+
operation is expected to return an error, the ``result`` has one field,
47+
``errorContains``, which is a substring of the expected error message
48+
or ``errorCodeName``, which is the expected server error "codeName".
49+
50+
- ``expectations``: Optional list of command-started events.
51+
52+
- ``outcome``: Document describing the return value and/or expected state of
53+
the collection after the operation is executed. Contains the following
54+
fields:
55+
56+
- ``collection``:
57+
58+
- ``data``: The data that should exist in the collection after the
59+
operations have run.
60+
61+
Use as integration tests
62+
========================
63+
64+
Run a MongoDB replica set with a primary, two secondaries, and an arbiter,
65+
server version 4.0 or later. (Including two secondaries ensures that transaction
66+
pinning works properly. Include an arbiter to ensure no new bugs have been
67+
introduced related to arbiters.)
68+
69+
For each YAML file, for each element in ``tests``:
70+
71+
#. Create a MongoClient and call
72+
``client.admin.runCommand({killAllSessions: []})`` to clean up any open
73+
transactions from previous test failures. The command will fail with message
74+
"operation was interrupted", because it kills its own implicit session. Catch
75+
the exception and continue.
76+
#. Drop the test collection, using writeConcern "majority".
77+
#. Execute the "create" command to recreate the collection, using writeConcern
78+
"majority". (Creating the collection inside a transaction is prohibited, so
79+
create it explicitly.)
80+
#. If the YAML file contains a ``data`` array, insert the documents in ``data``
81+
into the test collection, using writeConcern "majority".
82+
#. Create a **new** MongoClient ``client``, with Command Monitoring listeners
83+
enabled. (Using a new MongoClient for each test ensures a fresh session pool
84+
that hasn't executed any transactions previously, so the tests can assert
85+
actual txnNumbers, starting from 1.) Pass this test's ``clientOptions`` if
86+
present.
87+
#. Call ``client.startSession`` twice to create ClientSession objects
88+
``session0`` and ``session1``, using the test's "sessionOptions" if they
89+
are present. Save their lsids so they are available after calling
90+
``endSession``, see `Logical Session Id`.
91+
#. For each element in ``operations``:
92+
93+
- Enter a "try" block or your programming language's closest equivalent.
94+
- If ``name`` is "startTransaction", "commitTransaction", or
95+
"abortTransaction", call the named method on ``session0`` or
96+
``session1``, depending on the "session" argument.
97+
- Otherwise, ``name`` refers to a CRUD method, such as ``insertOne``.
98+
Execute the named method on the "transactions-tests" database on the "test"
99+
collection, passing the arguments listed. Pass ``session0`` or ``session1``
100+
to the method, depending on which session's name is in the arguments list.
101+
If ``arguments`` contains no "session", pass no explicit session to the
102+
method. If ``arguments`` includes "readPreference", configure the specified
103+
read preference in whatever manner the driver supports.
104+
- If the driver throws an exception / returns an error while executing this
105+
series of operations, store the error message and server error code.
106+
- If the result document has an "errorContains" field, verify that the
107+
method threw an exception or returned an error, and that the value of the
108+
"errorContains" field matches the error string. If the result document has
109+
an "errorCodeName" field, verify that the method threw a command failed
110+
exception or returned an error, and that the value of the "errorCodeName"
111+
field matches the "codeName" in the server error response.
112+
Otherwise, compare the method's return value to ``result`` using the same
113+
logic as the CRUD Spec Tests runner. key is a substring (case-insensitive)
114+
of the actual error message.
115+
116+
#. Call ``session0.endSession()`` and ``session1.endSession``.
117+
#. If the test includes a list of command-started events in ``expectations``,
118+
compare them to the actual command-started events using the
119+
same logic as the Command Monitoring Spec Tests runner, plus the rules in
120+
the Command-Started Events instructions below.
121+
#. For each element in ``outcome``:
122+
123+
- If ``name`` is "collection", verify that the test collection contains
124+
exactly the documents in the ``data`` array.
125+
126+
TODO:
127+
128+
- drivers MUST NOT retry writes in a transaction even when retryWrites=true, needs to use failpoint.
129+
- drivers MUST retry commit/abort, needs to use failpoint.
130+
- test writeConcernErrors
131+
132+
Command-Started Events
133+
``````````````````````
134+
135+
Logical Session Id
136+
~~~~~~~~~~~~~~~~~~
137+
138+
Each command-started event in ``expectations`` includes an ``lsid`` with the
139+
value "session0" or "session1". Tests MUST assert that the command's actual
140+
``lsid`` matches the id of the correct ClientSession named ``session0`` or
141+
``session1``.
142+
143+
Null Values
144+
~~~~~~~~~~~
145+
146+
Some command-started events in ``expectations`` include ``null`` values for
147+
fields such as ``txnNumber``, ``autocommit``, ``writeConcern``, and ``stmtId``.
148+
Tests MUST assert that the actual command **omits** any field that has a
149+
``null`` value in the expected command.
150+
151+
Cursor Id
152+
^^^^^^^^^
153+
154+
A ``getMore`` value of ``"42"`` in a command-started event is a fake cursorId
155+
that MUST be ignored. (In the Command Monitoring Spec tests, fake cursorIds are
156+
correlated with real ones, but that is not necessary for Transactions Spec
157+
tests.)
158+
159+
afterClusterTime
160+
^^^^^^^^^^^^^^^^
161+
162+
A ``readConcern.afterClusterTime`` value of ``42`` in a command-started event
163+
is a fake cluster time. Drivers MUST assert that the actual command includes an
164+
afterClusterTime.

0 commit comments

Comments
 (0)