Skip to content

Commit e76044c

Browse files
RUST-2154 Update tests that use WriteConcernFailed code name (#1331)
1 parent 4e1969c commit e76044c

20 files changed

+301
-291
lines changed

src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@
739739
]
740740
},
741741
{
742-
"description": "InsertOne fails after WriteConcernError WriteConcernFailed",
742+
"description": "InsertOne fails after WriteConcernError WriteConcernTimeout",
743743
"operations": [
744744
{
745745
"name": "failPoint",
@@ -757,7 +757,6 @@
757757
],
758758
"writeConcernError": {
759759
"code": 64,
760-
"codeName": "WriteConcernFailed",
761760
"errmsg": "waiting for replication timed out",
762761
"errInfo": {
763762
"wtimeout": true

src/test/spec/json/retryable-writes/unified/insertOne-serverErrors.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ tests:
339339
- { _id: 2, x: 22 }
340340
- { _id: 3, x: 33 } # The write was still applied.
341341
-
342-
description: 'InsertOne fails after WriteConcernError WriteConcernFailed'
342+
description: 'InsertOne fails after WriteConcernError WriteConcernTimeout'
343343
operations:
344344
-
345345
name: failPoint
@@ -353,7 +353,6 @@ tests:
353353
failCommands: [ insert ]
354354
writeConcernError:
355355
code: 64
356-
codeName: WriteConcernFailed
357356
errmsg: 'waiting for replication timed out'
358357
errInfo:
359358
wtimeout: true
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Convenient API for Transactions Tests
2+
3+
______________________________________________________________________
4+
5+
## Introduction
6+
7+
The YAML and JSON files in this directory are platform-independent tests meant to exercise a driver's implementation of
8+
the Convenient API for Transactions spec. These tests utilize the
9+
[Unified Test Format](../../unified-test-format/unified-test-format.md).
10+
11+
Several prose tests, which are not easily expressed in YAML, are also presented in this file. Those tests will need to
12+
be manually implemented by each driver.
13+
14+
## Prose Tests
15+
16+
### Callback Raises a Custom Error
17+
18+
Write a callback that raises a custom exception or error that does not include either UnknownTransactionCommitResult or
19+
TransientTransactionError error labels. Execute this callback using `withTransaction` and assert that the callback's
20+
error bypasses any retry logic within `withTransaction` and is propagated to the caller of `withTransaction`.
21+
22+
### Callback Returns a Value
23+
24+
Write a callback that returns a custom value (e.g. boolean, string, object). Execute this callback using
25+
`withTransaction` and assert that the callback's return value is propagated to the caller of `withTransaction`.
26+
27+
### Retry Timeout is Enforced
28+
29+
Drivers should test that `withTransaction` enforces a non-configurable timeout before retrying both commits and entire
30+
transactions. Specifically, three cases should be checked:
31+
32+
- If the callback raises an error with the TransientTransactionError label and the retry timeout has been exceeded,
33+
`withTransaction` should propagate the error to its caller.
34+
- If committing raises an error with the UnknownTransactionCommitResult label, and the retry timeout has been exceeded,
35+
`withTransaction` should propagate the error to its caller.
36+
- If committing raises an error with the TransientTransactionError label and the retry timeout has been exceeded,
37+
`withTransaction` should propagate the error to its caller. This case may occur if the commit was internally retried
38+
against a new primary after a failover and the second primary returned a NoSuchTransaction error response.
39+
40+
If possible, drivers should implement these tests without requiring the test runner to block for the full duration of
41+
the retry timeout. This might be done by internally modifying the timeout value used by `withTransaction` with some
42+
private API or using a mock timer.
43+
44+
## Changelog
45+
46+
- 2024-09-06: Migrated from reStructuredText to Markdown.
47+
- 2024-02-08: Converted legacy tests to unified format.
48+
- 2021-04-29: Remove text about write concern timeouts from prose test.

src/test/spec/json/transactions-convenient-api/README.rst

Lines changed: 0 additions & 68 deletions
This file was deleted.

src/test/spec/json/transactions-convenient-api/unified/commit-writeconcernerror.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
],
5757
"tests": [
5858
{
59-
"description": "commitTransaction is retried after WriteConcernFailed timeout error",
59+
"description": "commitTransaction is retried after WriteConcernTimeout timeout error",
6060
"operations": [
6161
{
6262
"name": "failPoint",
@@ -74,7 +74,6 @@
7474
],
7575
"writeConcernError": {
7676
"code": 64,
77-
"codeName": "WriteConcernFailed",
7877
"errmsg": "waiting for replication timed out",
7978
"errInfo": {
8079
"wtimeout": true
@@ -236,7 +235,7 @@
236235
]
237236
},
238237
{
239-
"description": "commitTransaction is retried after WriteConcernFailed non-timeout error",
238+
"description": "commitTransaction is retried after WriteConcernTimeout non-timeout error",
240239
"operations": [
241240
{
242241
"name": "failPoint",
@@ -254,7 +253,6 @@
254253
],
255254
"writeConcernError": {
256255
"code": 64,
257-
"codeName": "WriteConcernFailed",
258256
"errmsg": "multiple errors reported"
259257
}
260258
}

src/test/spec/json/transactions-convenient-api/unified/commit-writeconcernerror.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ initialData:
3232

3333
tests:
3434
-
35-
description: commitTransaction is retried after WriteConcernFailed timeout error
35+
description: commitTransaction is retried after WriteConcernTimeout timeout error
3636
operations:
3737
- name: failPoint
3838
object: testRunner
@@ -47,7 +47,6 @@ tests:
4747
# with writeConcernError (see: SERVER-39292)
4848
writeConcernError:
4949
code: 64
50-
codeName: WriteConcernFailed
5150
errmsg: "waiting for replication timed out"
5251
errInfo: { wtimeout: true }
5352
- &operation
@@ -126,10 +125,10 @@ tests:
126125
- { _id: 1 }
127126
-
128127
# This test configures the fail point to return an error with the
129-
# WriteConcernFailed code but without errInfo that would identify it as a
128+
# WriteConcernTimeout code but without errInfo that would identify it as a
130129
# wtimeout error. This tests that drivers do not assume that all
131-
# WriteConcernFailed errors are due to a replication timeout.
132-
description: commitTransaction is retried after WriteConcernFailed non-timeout error
130+
# WriteConcernTimeout errors are due to a replication timeout.
131+
description: commitTransaction is retried after WriteConcernTimeout non-timeout error
133132
operations:
134133
- name: failPoint
135134
object: testRunner
@@ -144,7 +143,6 @@ tests:
144143
# with writeConcernError (see: SERVER-39292)
145144
writeConcernError:
146145
code: 64
147-
codeName: WriteConcernFailed
148146
errmsg: "multiple errors reported"
149147
- *operation
150148
expectEvents: *expectEvents_with_retries

src/test/spec/json/transactions/README.md

Lines changed: 73 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -19,63 +19,82 @@ These tests use a cursor's address field to track which server an operation was
1919
driver, use command monitoring instead.
2020

2121
1. Test that starting a new transaction on a pinned ClientSession unpins the session and normal server selection is
22-
performed for the next operation.
23-
24-
```python
25-
@require_server_version(4, 1, 6)
26-
@require_mongos_count_at_least(2)
27-
def test_unpin_for_next_transaction(self):
28-
# Increase localThresholdMS and wait until both nodes are discovered
29-
# to avoid false positives.
30-
client = MongoClient(mongos_hosts, localThresholdMS=1000)
31-
wait_until(lambda: len(client.nodes) > 1)
32-
# Create the collection.
33-
client.test.test.insert_one({})
34-
with client.start_session() as s:
35-
# Session is pinned to Mongos.
36-
with s.start_transaction():
37-
client.test.test.insert_one({}, session=s)
38-
39-
addresses = set()
40-
for _ in range(50):
41-
with s.start_transaction():
42-
cursor = client.test.test.find({}, session=s)
43-
assert next(cursor)
44-
addresses.add(cursor.address)
45-
46-
assert len(addresses) > 1
47-
```
22+
performed for the next operation.
23+
24+
```python
25+
@require_server_version(4, 1, 6)
26+
@require_mongos_count_at_least(2)
27+
def test_unpin_for_next_transaction(self):
28+
# Increase localThresholdMS and wait until both nodes are discovered
29+
# to avoid false positives.
30+
client = MongoClient(mongos_hosts, localThresholdMS=1000)
31+
wait_until(lambda: len(client.nodes) > 1)
32+
# Create the collection.
33+
client.test.test.insert_one({})
34+
with client.start_session() as s:
35+
# Session is pinned to Mongos.
36+
with s.start_transaction():
37+
client.test.test.insert_one({}, session=s)
38+
39+
addresses = set()
40+
for _ in range(50):
41+
with s.start_transaction():
42+
cursor = client.test.test.find({}, session=s)
43+
assert next(cursor)
44+
addresses.add(cursor.address)
45+
46+
assert len(addresses) > 1
47+
```
4848

4949
2. Test non-transaction operations using a pinned ClientSession unpins the session and normal server selection is
50-
performed.
51-
52-
```python
53-
@require_server_version(4, 1, 6)
54-
@require_mongos_count_at_least(2)
55-
def test_unpin_for_non_transaction_operation(self):
56-
# Increase localThresholdMS and wait until both nodes are discovered
57-
# to avoid false positives.
58-
client = MongoClient(mongos_hosts, localThresholdMS=1000)
59-
wait_until(lambda: len(client.nodes) > 1)
60-
# Create the collection.
61-
client.test.test.insert_one({})
62-
with client.start_session() as s:
63-
# Session is pinned to Mongos.
64-
with s.start_transaction():
65-
client.test.test.insert_one({}, session=s)
66-
67-
addresses = set()
68-
for _ in range(50):
69-
cursor = client.test.test.find({}, session=s)
70-
assert next(cursor)
71-
addresses.add(cursor.address)
72-
73-
assert len(addresses) > 1
74-
```
50+
performed.
51+
52+
```python
53+
@require_server_version(4, 1, 6)
54+
@require_mongos_count_at_least(2)
55+
def test_unpin_for_non_transaction_operation(self):
56+
# Increase localThresholdMS and wait until both nodes are discovered
57+
# to avoid false positives.
58+
client = MongoClient(mongos_hosts, localThresholdMS=1000)
59+
wait_until(lambda: len(client.nodes) > 1)
60+
# Create the collection.
61+
client.test.test.insert_one({})
62+
with client.start_session() as s:
63+
# Session is pinned to Mongos.
64+
with s.start_transaction():
65+
client.test.test.insert_one({}, session=s)
66+
67+
addresses = set()
68+
for _ in range(50):
69+
cursor = client.test.test.find({}, session=s)
70+
assert next(cursor)
71+
addresses.add(cursor.address)
72+
73+
assert len(addresses) > 1
74+
```
75+
76+
3. Test that `PoolClearedError` has `TransientTransactionError` label. Since there is no simple way to trigger
77+
`PoolClearedError`, this test should be implemented in a way that suites each driver the best.
78+
79+
## Options Inside Transaction Prose Tests.
80+
81+
These prose tests ensure drivers handle options inside a transaction where the unified tests do not suffice. Ensure
82+
these tests do not run against a standalone server.
83+
84+
### 1.0 Write concern not inherited from collection object inside transaction.
85+
86+
- Create a MongoClient running against a configured sharded/replica set/load balanced cluster.
87+
- Start a new session on the client.
88+
- Start a transaction on the session.
89+
- Instantiate a collection object in the driver with a default write concern of `{ w: 0 }`.
90+
- Insert the document `{ n: 1 }` on the instantiated collection.
91+
- Commit the transaction.
92+
- End the session.
93+
- Ensure the document was inserted and no error was thrown from the transaction.
7594

7695
## Changelog
7796

97+
- 2024-10-31: Add test for PoolClearedError.
7898
- 2024-02-15: Migrated from reStructuredText to Markdown.
79-
- 2024-02-07: Converted legacy transaction tests to unified format and moved the\
80-
legacy test format docs to a separate
81-
file.
99+
- 2024-02-07: Converted legacy transaction tests to unified format and moved the legacy test format docs to a separate
100+
file.

0 commit comments

Comments
 (0)