Merge branch 'master' of github.com:mongodb/mongo-python-driver
This commit is contained in:
commit
516ec00c5e
@ -1195,7 +1195,8 @@ class AsyncMongoClient(common.BaseObject, Generic[_DocumentType]):
|
||||
ResourceWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
except AttributeError:
|
||||
except (AttributeError, TypeError):
|
||||
# Ignore errors at interpreter exit.
|
||||
pass
|
||||
|
||||
def _close_cursor_soon(
|
||||
|
||||
@ -1249,6 +1249,9 @@ class Pool:
|
||||
async with self.lock:
|
||||
conn_id = self.next_connection_id
|
||||
self.next_connection_id += 1
|
||||
# Use a temporary context so that interrupt_connections can cancel creating the socket.
|
||||
tmp_context = _CancellationContext()
|
||||
self.active_contexts.add(tmp_context)
|
||||
|
||||
listeners = self.opts._event_listeners
|
||||
if self.enabled_for_cmap:
|
||||
@ -1267,6 +1270,8 @@ class Pool:
|
||||
try:
|
||||
sock = await _configured_socket(self.address, self.opts)
|
||||
except BaseException as error:
|
||||
async with self.lock:
|
||||
self.active_contexts.discard(tmp_context)
|
||||
if self.enabled_for_cmap:
|
||||
assert listeners is not None
|
||||
listeners.publish_connection_closed(
|
||||
@ -1292,6 +1297,9 @@ class Pool:
|
||||
conn = AsyncConnection(sock, self, self.address, conn_id) # type: ignore[arg-type]
|
||||
async with self.lock:
|
||||
self.active_contexts.add(conn.cancel_context)
|
||||
self.active_contexts.discard(tmp_context)
|
||||
if tmp_context.cancelled:
|
||||
conn.cancel_context.cancel()
|
||||
try:
|
||||
if self.handshake:
|
||||
await conn.hello()
|
||||
@ -1301,6 +1309,8 @@ class Pool:
|
||||
|
||||
await conn.authenticate()
|
||||
except BaseException:
|
||||
async with self.lock:
|
||||
self.active_contexts.discard(conn.cancel_context)
|
||||
conn.close_conn(ConnectionClosedReason.ERROR)
|
||||
raise
|
||||
|
||||
|
||||
@ -252,6 +252,10 @@ def _gen_find_command(
|
||||
if limit < 0:
|
||||
cmd["singleBatch"] = True
|
||||
if batch_size:
|
||||
# When limit and batchSize are equal we increase batchSize by 1 to
|
||||
# avoid an unnecessary killCursors.
|
||||
if limit == batch_size:
|
||||
batch_size += 1
|
||||
cmd["batchSize"] = batch_size
|
||||
if read_concern.level and not (session and session.in_transaction):
|
||||
cmd["readConcern"] = read_concern.document
|
||||
|
||||
@ -70,13 +70,14 @@ elif sys.platform == "darwin":
|
||||
"version": platform.mac_ver()[0],
|
||||
}
|
||||
elif sys.platform == "win32":
|
||||
_ver = sys.getwindowsversion()
|
||||
_METADATA["os"] = {
|
||||
"type": platform.system(),
|
||||
# "Windows XP", "Windows 7", "Windows 10", etc.
|
||||
"name": " ".join((platform.system(), platform.release())),
|
||||
"architecture": platform.machine(),
|
||||
# Windows patch level (e.g. 5.1.2600-SP3)
|
||||
"version": "-".join(platform.win32_ver()[1:3]),
|
||||
"type": "Windows",
|
||||
"name": "Windows",
|
||||
# Avoid using platform calls, see PYTHON-4455.
|
||||
"architecture": os.environ.get("PROCESSOR_ARCHITECTURE") or platform.machine(),
|
||||
# Windows patch level (e.g. 10.0.17763-SP0).
|
||||
"version": ".".join(map(str, _ver[:3])) + f"-SP{_ver[-1] or '0'}",
|
||||
}
|
||||
elif sys.platform.startswith("java"):
|
||||
_name, _ver, _arch = platform.java_ver()[-1]
|
||||
|
||||
@ -1193,7 +1193,8 @@ class MongoClient(common.BaseObject, Generic[_DocumentType]):
|
||||
ResourceWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
except AttributeError:
|
||||
except (AttributeError, TypeError):
|
||||
# Ignore errors at interpreter exit.
|
||||
pass
|
||||
|
||||
def _close_cursor_soon(
|
||||
|
||||
@ -1243,6 +1243,9 @@ class Pool:
|
||||
with self.lock:
|
||||
conn_id = self.next_connection_id
|
||||
self.next_connection_id += 1
|
||||
# Use a temporary context so that interrupt_connections can cancel creating the socket.
|
||||
tmp_context = _CancellationContext()
|
||||
self.active_contexts.add(tmp_context)
|
||||
|
||||
listeners = self.opts._event_listeners
|
||||
if self.enabled_for_cmap:
|
||||
@ -1261,6 +1264,8 @@ class Pool:
|
||||
try:
|
||||
sock = _configured_socket(self.address, self.opts)
|
||||
except BaseException as error:
|
||||
with self.lock:
|
||||
self.active_contexts.discard(tmp_context)
|
||||
if self.enabled_for_cmap:
|
||||
assert listeners is not None
|
||||
listeners.publish_connection_closed(
|
||||
@ -1286,6 +1291,9 @@ class Pool:
|
||||
conn = Connection(sock, self, self.address, conn_id) # type: ignore[arg-type]
|
||||
with self.lock:
|
||||
self.active_contexts.add(conn.cancel_context)
|
||||
self.active_contexts.discard(tmp_context)
|
||||
if tmp_context.cancelled:
|
||||
conn.cancel_context.cancel()
|
||||
try:
|
||||
if self.handshake:
|
||||
conn.hello()
|
||||
@ -1295,6 +1303,8 @@ class Pool:
|
||||
|
||||
conn.authenticate()
|
||||
except BaseException:
|
||||
with self.lock:
|
||||
self.active_contexts.discard(conn.cancel_context)
|
||||
conn.close_conn(ConnectionClosedReason.ERROR)
|
||||
raise
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
mypy==1.13.0
|
||||
pyright==1.1.388
|
||||
pyright==1.1.389
|
||||
typing_extensions
|
||||
-r ./encryption.txt
|
||||
-r ./ocsp.txt
|
||||
|
||||
@ -174,9 +174,8 @@ class TestRetryableReads(AsyncIntegrationTest):
|
||||
retryReads=True,
|
||||
)
|
||||
|
||||
async with self.fail_point(fail_command):
|
||||
with self.assertRaises(AutoReconnect):
|
||||
await client.t.t.find_one({})
|
||||
with self.assertRaises(AutoReconnect):
|
||||
await client.t.t.find_one({})
|
||||
|
||||
# Disable failpoints on each mongos
|
||||
for client in mongos_clients:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Copyright 2017 MongoDB, Inc.
|
||||
# Copyright 2017-present MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -43,7 +43,6 @@ from bson.codec_options import DEFAULT_CODEC_OPTIONS
|
||||
from bson.int64 import Int64
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
from bson.son import SON
|
||||
from pymongo.asynchronous.mongo_client import AsyncMongoClient
|
||||
from pymongo.errors import (
|
||||
AutoReconnect,
|
||||
ConnectionFailure,
|
||||
@ -226,47 +225,6 @@ class TestRetryableWrites(IgnoreDeprecationsTest):
|
||||
f"{msg} sent txnNumber with {event.command_name}",
|
||||
)
|
||||
|
||||
@async_client_context.require_no_standalone
|
||||
async def test_supported_single_statement_supported_cluster(self):
|
||||
for method, args, kwargs in retryable_single_statement_ops(self.db.retryable_write_test):
|
||||
msg = f"{method.__name__}(*{args!r}, **{kwargs!r})"
|
||||
self.listener.reset()
|
||||
await method(*args, **kwargs)
|
||||
commands_started = self.listener.started_events
|
||||
self.assertEqual(len(self.listener.succeeded_events), 1, msg)
|
||||
first_attempt = commands_started[0]
|
||||
self.assertIn(
|
||||
"lsid",
|
||||
first_attempt.command,
|
||||
f"{msg} sent no lsid with {first_attempt.command_name}",
|
||||
)
|
||||
initial_session_id = first_attempt.command["lsid"]
|
||||
self.assertIn(
|
||||
"txnNumber",
|
||||
first_attempt.command,
|
||||
f"{msg} sent no txnNumber with {first_attempt.command_name}",
|
||||
)
|
||||
|
||||
# There should be no retry when the failpoint is not active.
|
||||
if async_client_context.is_mongos or not async_client_context.test_commands_enabled:
|
||||
self.assertEqual(len(commands_started), 1)
|
||||
continue
|
||||
|
||||
initial_transaction_id = first_attempt.command["txnNumber"]
|
||||
retry_attempt = commands_started[1]
|
||||
self.assertIn(
|
||||
"lsid",
|
||||
retry_attempt.command,
|
||||
f"{msg} sent no lsid with {first_attempt.command_name}",
|
||||
)
|
||||
self.assertEqual(retry_attempt.command["lsid"], initial_session_id, msg)
|
||||
self.assertIn(
|
||||
"txnNumber",
|
||||
retry_attempt.command,
|
||||
f"{msg} sent no txnNumber with {first_attempt.command_name}",
|
||||
)
|
||||
self.assertEqual(retry_attempt.command["txnNumber"], initial_transaction_id, msg)
|
||||
|
||||
async def test_supported_single_statement_unsupported_cluster(self):
|
||||
if async_client_context.is_rs or async_client_context.is_mongos:
|
||||
raise SkipTest("This cluster supports retryable writes")
|
||||
|
||||
@ -76,6 +76,7 @@ from pymongo.asynchronous.encryption import AsyncClientEncryption
|
||||
from pymongo.asynchronous.helpers import anext
|
||||
from pymongo.encryption_options import _HAVE_PYMONGOCRYPT
|
||||
from pymongo.errors import (
|
||||
AutoReconnect,
|
||||
BulkWriteError,
|
||||
ClientBulkWriteException,
|
||||
ConfigurationError,
|
||||
@ -545,15 +546,6 @@ class UnifiedSpecTestMixinV1(AsyncIntegrationTest):
|
||||
or "Cancel server check" in spec["description"]
|
||||
):
|
||||
self.skipTest("MMAPv1 does not support retryWrites=True")
|
||||
if (
|
||||
"AsyncDatabase-level aggregate with $out includes read preference for 5.0+ server"
|
||||
in spec["description"]
|
||||
):
|
||||
if async_client_context.version[0] == 8:
|
||||
self.skipTest("waiting on PYTHON-4356")
|
||||
if "Aggregate with $out includes read preference for 5.0+ server" in spec["description"]:
|
||||
if async_client_context.version[0] == 8:
|
||||
self.skipTest("waiting on PYTHON-4356")
|
||||
if "Client side error in command starting transaction" in spec["description"]:
|
||||
self.skipTest("Implement PYTHON-1894")
|
||||
if "timeoutMS applied to entire download" in spec["description"]:
|
||||
@ -764,9 +756,10 @@ class UnifiedSpecTestMixinV1(AsyncIntegrationTest):
|
||||
for client in clients:
|
||||
try:
|
||||
await client.admin.command("killAllSessions", [])
|
||||
except OperationFailure:
|
||||
except (OperationFailure, AutoReconnect):
|
||||
# "operation was interrupted" by killing the command's
|
||||
# own session.
|
||||
# On 8.0+ killAllSessions sometimes returns a network error.
|
||||
pass
|
||||
|
||||
async def _databaseOperation_listCollections(self, target, *args, **kwargs):
|
||||
|
||||
@ -46,7 +46,7 @@ from gridfs.asynchronous.grid_file import AsyncGridFSBucket
|
||||
from pymongo.asynchronous import client_session
|
||||
from pymongo.asynchronous.command_cursor import AsyncCommandCursor
|
||||
from pymongo.asynchronous.cursor import AsyncCursor
|
||||
from pymongo.errors import BulkWriteError, OperationFailure, PyMongoError
|
||||
from pymongo.errors import AutoReconnect, BulkWriteError, OperationFailure, PyMongoError
|
||||
from pymongo.read_concern import ReadConcern
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.results import BulkWriteResult, _WriteResult
|
||||
@ -343,9 +343,10 @@ class AsyncSpecRunner(AsyncIntegrationTest):
|
||||
for client in clients:
|
||||
try:
|
||||
await client.admin.command("killAllSessions", [])
|
||||
except OperationFailure:
|
||||
except (OperationFailure, AutoReconnect):
|
||||
# "operation was interrupted" by killing the command's
|
||||
# own session.
|
||||
# On 8.0+ killAllSessions sometimes returns a network error.
|
||||
pass
|
||||
|
||||
def check_command_result(self, expected_result, result):
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
"minServerVersion": "8.0",
|
||||
"serverless": "forbid"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "8.0"
|
||||
"minServerVersion": "8.0",
|
||||
"serverless": "forbid"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
|
||||
139
test/crud/unified/distinct-hint.json
Normal file
139
test/crud/unified/distinct-hint.json
Normal file
@ -0,0 +1,139 @@
|
||||
{
|
||||
"description": "distinct-hint",
|
||||
"schemaVersion": "1.0",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "7.1.0"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "distinct-hint-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "distinct-hint-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "distinct with hint string",
|
||||
"operations": [
|
||||
{
|
||||
"name": "distinct",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"fieldName": "x",
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"hint": "_id_"
|
||||
},
|
||||
"expectResult": [
|
||||
11
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"distinct": "coll0",
|
||||
"key": "x",
|
||||
"query": {
|
||||
"_id": 1
|
||||
},
|
||||
"hint": "_id_"
|
||||
},
|
||||
"commandName": "distinct",
|
||||
"databaseName": "distinct-hint-tests"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "distinct with hint document",
|
||||
"operations": [
|
||||
{
|
||||
"name": "distinct",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"fieldName": "x",
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"hint": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"expectResult": [
|
||||
11
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"distinct": "coll0",
|
||||
"key": "x",
|
||||
"query": {
|
||||
"_id": 1
|
||||
},
|
||||
"hint": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"commandName": "distinct",
|
||||
"databaseName": "distinct-hint-tests"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -249,7 +249,7 @@
|
||||
"name": "estimatedDocumentCount",
|
||||
"object": "collection0",
|
||||
"expectError": {
|
||||
"isError": true
|
||||
"isClientError": true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@ -237,6 +237,68 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Find with batchSize equal to limit",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "find",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": 1
|
||||
},
|
||||
"limit": 4,
|
||||
"batchSize": 4
|
||||
},
|
||||
"expectResult": [
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
},
|
||||
{
|
||||
"_id": 4,
|
||||
"x": 44
|
||||
},
|
||||
{
|
||||
"_id": 5,
|
||||
"x": 55
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "coll0",
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
},
|
||||
"limit": 4,
|
||||
"batchSize": 5
|
||||
},
|
||||
"commandName": "find",
|
||||
"databaseName": "find-tests"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
158
test/crud/unified/findOne.json
Normal file
158
test/crud/unified/findOne.json
Normal file
@ -0,0 +1,158 @@
|
||||
{
|
||||
"description": "findOne",
|
||||
"schemaVersion": "1.0",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "find-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "coll0",
|
||||
"databaseName": "find-tests",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
},
|
||||
{
|
||||
"_id": 4,
|
||||
"x": 44
|
||||
},
|
||||
{
|
||||
"_id": 5,
|
||||
"x": 55
|
||||
},
|
||||
{
|
||||
"_id": 6,
|
||||
"x": 66
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "FindOne with filter",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "findOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": 1
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "coll0",
|
||||
"filter": {
|
||||
"_id": 1
|
||||
},
|
||||
"batchSize": {
|
||||
"$$exists": false
|
||||
},
|
||||
"limit": 1,
|
||||
"singleBatch": true
|
||||
},
|
||||
"commandName": "find",
|
||||
"databaseName": "find-tests"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "FindOne with filter, sort, and skip",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "findOne",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 2
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": 1
|
||||
},
|
||||
"skip": 2
|
||||
},
|
||||
"expectResult": {
|
||||
"_id": 5,
|
||||
"x": 55
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "coll0",
|
||||
"filter": {
|
||||
"_id": {
|
||||
"$gt": 2
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"_id": 1
|
||||
},
|
||||
"skip": 2,
|
||||
"batchSize": {
|
||||
"$$exists": false
|
||||
},
|
||||
"limit": 1,
|
||||
"singleBatch": true
|
||||
},
|
||||
"commandName": "find",
|
||||
"databaseName": "find-tests"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
144
test/retryable_writes/unified/aggregate-out-merge.json
Normal file
144
test/retryable_writes/unified/aggregate-out-merge.json
Normal file
@ -0,0 +1,144 @@
|
||||
{
|
||||
"description": "aggregate with $out/$merge does not set txnNumber",
|
||||
"schemaVersion": "1.3",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6",
|
||||
"topologies": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
"load-balanced"
|
||||
]
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "retryable-writes-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "mergeCollection",
|
||||
"databaseName": "retryable-writes-tests",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "aggregate with $out does not set txnNumber",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "aggregate",
|
||||
"arguments": {
|
||||
"pipeline": [
|
||||
{
|
||||
"$sort": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"$match": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$out": "outCollection"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "aggregate",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "aggregate with $merge does not set txnNumber",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "4.1.11"
|
||||
}
|
||||
],
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "aggregate",
|
||||
"arguments": {
|
||||
"pipeline": [
|
||||
{
|
||||
"$sort": {
|
||||
"x": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"$match": {
|
||||
"_id": {
|
||||
"$gt": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$merge": {
|
||||
"into": "mergeCollection"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "aggregate",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -121,6 +124,53 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "delete",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -510,6 +560,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -926,6 +1003,81 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "collection bulkWrite with updateMany does not set txnNumber",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"updateMany": {
|
||||
"filter": {},
|
||||
"update": {
|
||||
"$set": {
|
||||
"x": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "collection bulkWrite with deleteMany does not set txnNumber",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "bulkWrite",
|
||||
"arguments": {
|
||||
"requests": [
|
||||
{
|
||||
"deleteMany": {
|
||||
"filter": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "delete",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -428,7 +428,10 @@
|
||||
{
|
||||
"ns": "retryable-writes-tests.coll0"
|
||||
}
|
||||
]
|
||||
],
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -779,7 +782,10 @@
|
||||
{
|
||||
"ns": "retryable-writes-tests.coll0"
|
||||
}
|
||||
]
|
||||
],
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -861,7 +867,10 @@
|
||||
{
|
||||
"ns": "retryable-writes-tests.coll0"
|
||||
}
|
||||
]
|
||||
],
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true
|
||||
"useMultipleMongoses": true,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -70,6 +73,23 @@
|
||||
"databaseName": "retryable-writes-tests",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "delete",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -88,6 +91,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "delete",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "delete",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -94,6 +97,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "findAndModify",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "findAndModify",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -98,6 +101,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "findAndModify",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "findAndModify",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -99,6 +102,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "findAndModify",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "findAndModify",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -107,6 +110,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -172,6 +202,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -101,6 +104,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -98,6 +101,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
{
|
||||
"description": "unacknowledged write does not set txnNumber",
|
||||
"schemaVersion": "1.3",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "3.6",
|
||||
"topologies": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
"load-balanced"
|
||||
]
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "retryable-writes-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0",
|
||||
"collectionOptions": {
|
||||
"writeConcern": {
|
||||
"w": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "unacknowledged write does not set txnNumber",
|
||||
"operations": [
|
||||
{
|
||||
"object": "collection0",
|
||||
"name": "insertOne",
|
||||
"arguments": {
|
||||
"document": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "insert",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -15,7 +15,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": true
|
||||
"useMultipleMongoses": true,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -86,6 +89,23 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"useMultipleMongoses": false
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -99,6 +102,33 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client0",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"commandName": "update",
|
||||
"command": {
|
||||
"txnNumber": {
|
||||
"$$exists": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -216,11 +216,6 @@ class TestCMAP(IntegrationTest):
|
||||
|
||||
def run_scenario(self, scenario_def, test):
|
||||
"""Run a CMAP spec test."""
|
||||
if (
|
||||
scenario_def["description"]
|
||||
== "clear with interruptInUseConnections = true closes pending connections"
|
||||
):
|
||||
self.skipTest("Skip pending PYTHON-4414")
|
||||
self.logs: list = []
|
||||
self.assertEqual(scenario_def["version"], 1)
|
||||
self.assertIn(scenario_def["style"], ["unit", "integration"])
|
||||
|
||||
@ -174,9 +174,8 @@ class TestRetryableReads(IntegrationTest):
|
||||
retryReads=True,
|
||||
)
|
||||
|
||||
with self.fail_point(fail_command):
|
||||
with self.assertRaises(AutoReconnect):
|
||||
client.t.t.find_one({})
|
||||
with self.assertRaises(AutoReconnect):
|
||||
client.t.t.find_one({})
|
||||
|
||||
# Disable failpoints on each mongos
|
||||
for client in mongos_clients:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Copyright 2017 MongoDB, Inc.
|
||||
# Copyright 2017-present MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -65,7 +65,6 @@ from pymongo.operations import (
|
||||
UpdateMany,
|
||||
UpdateOne,
|
||||
)
|
||||
from pymongo.synchronous.mongo_client import MongoClient
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
_IS_SYNC = True
|
||||
@ -226,47 +225,6 @@ class TestRetryableWrites(IgnoreDeprecationsTest):
|
||||
f"{msg} sent txnNumber with {event.command_name}",
|
||||
)
|
||||
|
||||
@client_context.require_no_standalone
|
||||
def test_supported_single_statement_supported_cluster(self):
|
||||
for method, args, kwargs in retryable_single_statement_ops(self.db.retryable_write_test):
|
||||
msg = f"{method.__name__}(*{args!r}, **{kwargs!r})"
|
||||
self.listener.reset()
|
||||
method(*args, **kwargs)
|
||||
commands_started = self.listener.started_events
|
||||
self.assertEqual(len(self.listener.succeeded_events), 1, msg)
|
||||
first_attempt = commands_started[0]
|
||||
self.assertIn(
|
||||
"lsid",
|
||||
first_attempt.command,
|
||||
f"{msg} sent no lsid with {first_attempt.command_name}",
|
||||
)
|
||||
initial_session_id = first_attempt.command["lsid"]
|
||||
self.assertIn(
|
||||
"txnNumber",
|
||||
first_attempt.command,
|
||||
f"{msg} sent no txnNumber with {first_attempt.command_name}",
|
||||
)
|
||||
|
||||
# There should be no retry when the failpoint is not active.
|
||||
if client_context.is_mongos or not client_context.test_commands_enabled:
|
||||
self.assertEqual(len(commands_started), 1)
|
||||
continue
|
||||
|
||||
initial_transaction_id = first_attempt.command["txnNumber"]
|
||||
retry_attempt = commands_started[1]
|
||||
self.assertIn(
|
||||
"lsid",
|
||||
retry_attempt.command,
|
||||
f"{msg} sent no lsid with {first_attempt.command_name}",
|
||||
)
|
||||
self.assertEqual(retry_attempt.command["lsid"], initial_session_id, msg)
|
||||
self.assertIn(
|
||||
"txnNumber",
|
||||
retry_attempt.command,
|
||||
f"{msg} sent no txnNumber with {first_attempt.command_name}",
|
||||
)
|
||||
self.assertEqual(retry_attempt.command["txnNumber"], initial_transaction_id, msg)
|
||||
|
||||
def test_supported_single_statement_unsupported_cluster(self):
|
||||
if client_context.is_rs or client_context.is_mongos:
|
||||
raise SkipTest("This cluster supports retryable writes")
|
||||
|
||||
@ -69,6 +69,7 @@ from gridfs import GridFSBucket, GridOut
|
||||
from pymongo import ASCENDING, CursorType, MongoClient, _csot
|
||||
from pymongo.encryption_options import _HAVE_PYMONGOCRYPT
|
||||
from pymongo.errors import (
|
||||
AutoReconnect,
|
||||
BulkWriteError,
|
||||
ClientBulkWriteException,
|
||||
ConfigurationError,
|
||||
@ -543,15 +544,6 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
or "Cancel server check" in spec["description"]
|
||||
):
|
||||
self.skipTest("MMAPv1 does not support retryWrites=True")
|
||||
if (
|
||||
"Database-level aggregate with $out includes read preference for 5.0+ server"
|
||||
in spec["description"]
|
||||
):
|
||||
if client_context.version[0] == 8:
|
||||
self.skipTest("waiting on PYTHON-4356")
|
||||
if "Aggregate with $out includes read preference for 5.0+ server" in spec["description"]:
|
||||
if client_context.version[0] == 8:
|
||||
self.skipTest("waiting on PYTHON-4356")
|
||||
if "Client side error in command starting transaction" in spec["description"]:
|
||||
self.skipTest("Implement PYTHON-1894")
|
||||
if "timeoutMS applied to entire download" in spec["description"]:
|
||||
@ -760,9 +752,10 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
for client in clients:
|
||||
try:
|
||||
client.admin.command("killAllSessions", [])
|
||||
except OperationFailure:
|
||||
except (OperationFailure, AutoReconnect):
|
||||
# "operation was interrupted" by killing the command's
|
||||
# own session.
|
||||
# On 8.0+ killAllSessions sometimes returns a network error.
|
||||
pass
|
||||
|
||||
def _databaseOperation_listCollections(self, target, *args, **kwargs):
|
||||
|
||||
@ -925,35 +925,6 @@ def parse_spec_options(opts):
|
||||
if "maxCommitTimeMS" in opts:
|
||||
opts["max_commit_time_ms"] = opts.pop("maxCommitTimeMS")
|
||||
|
||||
if "hint" in opts:
|
||||
hint = opts.pop("hint")
|
||||
if not isinstance(hint, str):
|
||||
hint = list(hint.items())
|
||||
opts["hint"] = hint
|
||||
|
||||
# Properly format 'hint' arguments for the Bulk API tests.
|
||||
if "requests" in opts:
|
||||
reqs = opts.pop("requests")
|
||||
for req in reqs:
|
||||
if "name" in req:
|
||||
# CRUD v2 format
|
||||
args = req.pop("arguments", {})
|
||||
if "hint" in args:
|
||||
hint = args.pop("hint")
|
||||
if not isinstance(hint, str):
|
||||
hint = list(hint.items())
|
||||
args["hint"] = hint
|
||||
req["arguments"] = args
|
||||
else:
|
||||
# Unified test format
|
||||
bulk_model, spec = next(iter(req.items()))
|
||||
if "hint" in spec:
|
||||
hint = spec.pop("hint")
|
||||
if not isinstance(hint, str):
|
||||
hint = list(hint.items())
|
||||
spec["hint"] = hint
|
||||
opts["requests"] = reqs
|
||||
|
||||
return dict(opts)
|
||||
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ from bson.int64 import Int64
|
||||
from bson.son import SON
|
||||
from gridfs import GridFSBucket
|
||||
from gridfs.synchronous.grid_file import GridFSBucket
|
||||
from pymongo.errors import BulkWriteError, OperationFailure, PyMongoError
|
||||
from pymongo.errors import AutoReconnect, BulkWriteError, OperationFailure, PyMongoError
|
||||
from pymongo.read_concern import ReadConcern
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.results import BulkWriteResult, _WriteResult
|
||||
@ -343,9 +343,10 @@ class SpecRunner(IntegrationTest):
|
||||
for client in clients:
|
||||
try:
|
||||
client.admin.command("killAllSessions", [])
|
||||
except OperationFailure:
|
||||
except (OperationFailure, AutoReconnect):
|
||||
# "operation was interrupted" by killing the command's
|
||||
# own session.
|
||||
# On 8.0+ killAllSessions sometimes returns a network error.
|
||||
pass
|
||||
|
||||
def check_command_result(self, expected_result, result):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user