Merge branch 'master' of github.com:mongodb/mongo-python-driver

This commit is contained in:
Steven Silvester 2025-07-31 11:51:30 -05:00
commit 56affb496e
No known key found for this signature in database
GPG Key ID: B1BF5EC3A8B32F91
34 changed files with 292 additions and 1391 deletions

View File

@ -41,4 +41,17 @@ rm $PYMONGO/test/crud/unified/updateMany-rawdata.json
rm $PYMONGO/test/crud/unified/updateOne-rawdata.json
rm $PYMONGO/test/index_management/index-rawdata.json
echo "Done removing unimplemented tests\n"
# PyMongo does not support modifyCollection
rm $PYMONGO/test/collection_management/modifyCollection-*.json
# PYTHON-5248 - Remove support for MongoDB 4.0
rm $PYMONGO/test/**/pre-42-*.json
# PYTHON-3359 - Remove Database and Collection level timeout override
rm $PYMONGO/test/csot/override-collection-timeoutMS.json
rm $PYMONGO/test/csot/override-database-timeoutMS.json
# PYTHON-2943 - Socks5 Proxy Support
rm $PYMONGO/test/uri_options/proxy-options.json
echo "Done removing unimplemented tests"

View File

@ -33,7 +33,11 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> None:
def apply_patches():
print("Beginning to apply patches") # noqa: T201
subprocess.run(["bash", "./.evergreen/remove-unimplemented-tests.sh"], check=True) # noqa: S603, S607
subprocess.run(["git apply -R --allow-empty ./.evergreen/spec-patch/*"], shell=True, check=True) # noqa: S602, S607
subprocess.run(
["git apply -R --allow-empty --whitespace=fix ./.evergreen/spec-patch/*"], # noqa: S607
shell=True, # noqa: S602
check=True,
)
def check_new_spec_directories(directory: pathlib.Path) -> list[str]:

View File

@ -0,0 +1,64 @@
diff --git a/test/load_balancer/cursors.json b/test/load_balancer/cursors.json
index 43e4fbb4f..4e2a55fd4 100644
--- a/test/load_balancer/cursors.json
+++ b/test/load_balancer/cursors.json
@@ -376,7 +376,7 @@
]
},
{
+ "description": "pinned connections are not returned after an network error during getMore",
- "description": "pinned connections are returned after an network error during getMore",
"operations": [
{
"name": "failPoint",
@@ -440,7 +440,7 @@
"object": "testRunner",
"arguments": {
"client": "client0",
+ "connections": 1
- "connections": 0
}
},
{
@@ -659,7 +659,7 @@
]
},
{
+ "description": "pinned connections are not returned to the pool after a non-network error on getMore",
- "description": "pinned connections are returned to the pool after a non-network error on getMore",
"operations": [
{
"name": "failPoint",
@@ -715,7 +715,7 @@
"object": "testRunner",
"arguments": {
"client": "client0",
+ "connections": 1
- "connections": 0
}
},
{
diff --git a/test/load_balancer/sdam-error-handling.json b/test/load_balancer/sdam-error-handling.json
index 63aabc04d..462fa0aac 100644
--- a/test/load_balancer/sdam-error-handling.json
+++ b/test/load_balancer/sdam-error-handling.json
@@ -366,6 +366,9 @@
{
"connectionCreatedEvent": {}
},
+ {
+ "poolClearedEvent": {}
+ },
{
"connectionClosedEvent": {
"reason": "error"
@@ -378,9 +375,6 @@
"connectionCheckOutFailedEvent": {
"reason": "connectionError"
}
- },
- {
- "poolClearedEvent": {}
}
]
}

View File

@ -0,0 +1,14 @@
diff --git a/test/discovery_and_monitoring/unified/serverMonitoringMode.json b/test/discovery_and_monitoring/unified/serverMonitoringMode.json
index 4b492f7d8..e44fad1bc 100644
--- a/test/discovery_and_monitoring/unified/serverMonitoringMode.json
+++ b/test/discovery_and_monitoring/unified/serverMonitoringMode.json
@@ -5,8 +5,7 @@
{
"topologies": [
"single",
+ "sharded"
- "sharded",
- "sharded-replicaset"
],
"serverless": "forbid"
}

View File

@ -0,0 +1,61 @@
diff --git a/test/server_selection_logging/replica-set.json b/test/server_selection_logging/replica-set.json
index 830b1ea51..5eba784bf 100644
--- a/test/server_selection_logging/replica-set.json
+++ b/test/server_selection_logging/replica-set.json
@@ -184,7 +184,7 @@
}
},
{
- "level": "debug",
+ "level": "info",
"component": "serverSelection",
"data": {
"message": "Waiting for suitable server to become available",
diff --git a/test/server_selection_logging/standalone.json b/test/server_selection_logging/standalone.json
index 830b1ea51..5eba784bf 100644
--- a/test/server_selection_logging/standalone.json
+++ b/test/server_selection_logging/standalone.json
@@ -191,7 +191,7 @@
}
},
{
- "level": "debug",
+ "level": "info",
"component": "serverSelection",
"data": {
"message": "Waiting for suitable server to become available",
diff --git a/test/server_selection_logging/sharded.json b/test/server_selection_logging/sharded.json
index 830b1ea51..5eba784bf 100644
--- a/test/server_selection_logging/sharded.json
+++ b/test/server_selection_logging/sharded.json
@@ -193,7 +193,7 @@
}
},
{
- "level": "debug",
+ "level": "info",
"component": "serverSelection",
"data": {
"message": "Waiting for suitable server to become available",
diff --git a/test/server_selection_logging/sharded.json b/test/server_selection_logging/operation-id.json
index 830b1ea51..5eba784bf 100644
--- a/test/server_selection_logging/operation-id.json
+++ b/test/server_selection_logging/operation-id.json
@@ -197,7 +197,7 @@
}
},
{
- "level": "debug",
+ "level": "info",
"component": "serverSelection",
"data": {
"message": "Waiting for suitable server to become available",
@@ -383,7 +383,7 @@
}
},
{
- "level": "debug",
+ "level": "info",
"component": "serverSelection",
"data": {
"message": "Waiting for suitable server to become available",

View File

@ -46,7 +46,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3
uses: github/codeql-action/init@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@ -63,6 +63,6 @@ jobs:
pip install -e .
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3
uses: github/codeql-action/analyze@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3
with:
category: "/language:${{matrix.language}}"

View File

@ -25,7 +25,7 @@ jobs:
- name: Install just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
enable-cache: true
python-version: "3.9"
@ -65,7 +65,7 @@ jobs:
- name: Install just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
@ -88,7 +88,7 @@ jobs:
- name: Install just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
enable-cache: true
python-version: "3.9"
@ -111,7 +111,7 @@ jobs:
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
enable-cache: true
python-version: "3.9"
@ -130,7 +130,7 @@ jobs:
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
enable-cache: true
python-version: "3.9"
@ -152,7 +152,7 @@ jobs:
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
enable-cache: true
python-version: "${{matrix.python}}"
@ -231,7 +231,7 @@ jobs:
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
python-version: '3.9'
- name: Start MongoDB
@ -257,7 +257,7 @@ jobs:
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@7edac99f961f18b581bbd960d59d049f04c0002f # v5
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v5
with:
python-version: '3.9'
- name: Start MongoDB

View File

@ -18,4 +18,4 @@ jobs:
with:
persist-credentials: false
- name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@1c7106082dbc1753372e3924b7da1b9417011a21
uses: zizmorcore/zizmor-action@87e33752ad17c7c7fc16fe27c858900c59b18d77

View File

@ -189,7 +189,7 @@ class TestDatabase(AsyncIntegrationTest):
filter={"name": {"$regex": r"^(?!system\.)"}}
)
for coll in no_system_collections:
self.assertTrue(not coll.startswith("system."))
self.assertFalse(coll.startswith("system."))
self.assertIn("systemcoll.test", no_system_collections)
# Force more than one batch.
@ -265,19 +265,13 @@ class TestDatabase(AsyncIntegrationTest):
try:
# Found duplicate.
coll_cnt[coll] += 1
self.assertTrue(False)
self.fail("Found duplicate")
except KeyError:
coll_cnt[coll] = 1
coll_cnt: dict = {}
# Checking if is there any collection which don't exists.
if (
len(set(colls) - {"test", "test.mike"}) == 0
or len(set(colls) - {"test", "test.mike", "system.indexes"}) == 0
):
self.assertTrue(True)
else:
self.assertTrue(False)
# Check if there are any collections which don't exist.
self.assertLessEqual(set(colls), {"test", "test.mike", "system.indexes"})
colls = await (await db.list_collections(filter={"name": {"$regex": "^test$"}})).to_list()
self.assertEqual(1, len(colls))
@ -307,16 +301,13 @@ class TestDatabase(AsyncIntegrationTest):
try:
# Found duplicate.
coll_cnt[coll] += 1
self.assertTrue(False)
self.fail("Found duplicate")
except KeyError:
coll_cnt[coll] = 1
coll_cnt = {}
# Checking if is there any collection which don't exists.
if len(set(colls) - {"test"}) == 0 or len(set(colls) - {"test", "system.indexes"}) == 0:
self.assertTrue(True)
else:
self.assertTrue(False)
# Check if there are any collections which don't exist.
self.assertLessEqual(set(colls), {"test", "system.indexes"})
await self.client.drop_database("pymongo_test")

View File

@ -164,17 +164,16 @@ class TestGridfs(AsyncIntegrationTest):
await files.drop()
await self.fs.upload_from_stream("filename", b"junk")
self.assertTrue(
any(
info.get("key") == [("files_id", 1), ("n", 1)]
for info in (await chunks.index_information()).values()
)
self.assertIn(
[("files_id", 1), ("n", 1)],
[info.get("key") for info in (await chunks.index_information()).values()],
"Missing required index on chunks collection: {files_id: 1, n: 1}",
)
self.assertTrue(
any(
info.get("key") == [("filename", 1), ("uploadDate", 1)]
for info in (await files.index_information()).values()
)
self.assertIn(
[("filename", 1), ("uploadDate", 1)],
[info.get("key") for info in (await files.index_information()).values()],
"Missing required index on files collection: {filename: 1, uploadDate: 1}",
)
async def test_ensure_index_shell_compat(self):
@ -192,11 +191,10 @@ class TestGridfs(AsyncIntegrationTest):
# No error.
await self.fs.upload_from_stream("filename", b"data")
self.assertTrue(
any(
info.get("key") == [("filename", 1), ("uploadDate", 1)]
for info in (await files.index_information()).values()
)
self.assertIn(
[("filename", 1), ("uploadDate", 1)],
[info.get("key") for info in (await files.index_information()).values()],
"Missing required index on files collection: {filename: 1, uploadDate: 1}",
)
await files.drop()

View File

@ -512,9 +512,8 @@ class AsyncTestCommandMonitoring(AsyncIntegrationTest):
self.assertEqual(cursor.address, succeeded.connection_id)
# There could be more than one cursor_id here depending on
# when the thread last ran.
self.assertTrue(
cursor_id in succeeded.reply["cursorsUnknown"]
or cursor_id in succeeded.reply["cursorsKilled"]
self.assertIn(
cursor_id, succeeded.reply["cursorsUnknown"] + succeeded.reply["cursorsKilled"]
)
async def test_non_bulk_writes(self):
@ -1066,7 +1065,7 @@ class AsyncTestCommandMonitoring(AsyncIntegrationTest):
self.assertEqual(2, len(errors))
fields = {"index", "code", "errmsg"}
for error in errors:
self.assertTrue(fields.issubset(set(error)))
self.assertLessEqual(fields, set(error))
async def test_first_batch_helper(self):
# Regardless of server version and use of helpers._first_batch

View File

@ -519,6 +519,15 @@ class UnifiedSpecTestMixinV1(AsyncIntegrationTest):
self.skipTest("Implement PYTHON-1894")
if "timeoutMS applied to entire download" in spec["description"]:
self.skipTest("PyMongo's open_download_stream does not cap the stream's lifetime")
if any(
x in spec["description"]
for x in [
"First insertOne is never committed",
"Second updateOne is never committed",
"Third updateOne is never committed",
]
):
self.skipTest("Implement PYTHON-4597")
class_name = self.__class__.__name__.lower()
description = spec["description"].lower()
@ -672,7 +681,7 @@ class UnifiedSpecTestMixinV1(AsyncIntegrationTest):
self.match_evaluator.match_result(expect_result, result)
else:
self.fail(
f"expectResult can only be specified with {BulkWriteError} or {ClientBulkWriteException} exceptions"
f"expectResult can only be specified with {BulkWriteError} or {ClientBulkWriteException} exceptions, got {exception}"
)
return exception
@ -982,13 +991,9 @@ class UnifiedSpecTestMixinV1(AsyncIntegrationTest):
if ignore and isinstance(exc, (PyMongoError,)):
return exc
if expect_error:
if method_name == "_collectionOperation_bulkWrite":
self.skipTest("Skipping test pending PYTHON-4598")
return self.process_error(exc, expect_error)
raise
else:
if method_name == "_collectionOperation_bulkWrite":
self.skipTest("Skipping test pending PYTHON-4598")
if expect_error:
self.fail(f'Excepted error {expect_error} but "{opname}" succeeded: {result}')

View File

@ -312,6 +312,30 @@
"canonical_bson": "18000000136400000000000a5bc138938d44c64d31cc3700",
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}",
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"1.000000000000000000000000000000000E+999\"}}"
},
{
"description": "Clamped zeros with a large positive exponent",
"canonical_bson": "180000001364000000000000000000000000000000FE5F00",
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E+2147483647\"}}",
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E+6111\"}}"
},
{
"description": "Clamped zeros with a large negative exponent",
"canonical_bson": "180000001364000000000000000000000000000000000000",
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E-2147483647\"}}",
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"0E-6176\"}}"
},
{
"description": "Clamped negative zeros with a large positive exponent",
"canonical_bson": "180000001364000000000000000000000000000000FEDF00",
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E+2147483647\"}}",
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E+6111\"}}"
},
{
"description": "Clamped negative zeros with a large negative exponent",
"canonical_bson": "180000001364000000000000000000000000000000008000",
"degenerate_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E-2147483647\"}}",
"canonical_extjson": "{\"d\" : {\"$numberDecimal\" : \"-0E-6176\"}}"
}
]
}

View File

@ -1,111 +0,0 @@
{
"description": "modifyCollection-pre_and_post_images",
"schemaVersion": "1.4",
"runOnRequirements": [
{
"minServerVersion": "6.0",
"serverless": "forbid"
}
],
"createEntities": [
{
"client": {
"id": "client0",
"observeEvents": [
"commandStartedEvent"
]
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "papi-tests"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "test"
}
}
],
"tests": [
{
"description": "modifyCollection to changeStreamPreAndPostImages enabled",
"operations": [
{
"name": "dropCollection",
"object": "database0",
"arguments": {
"collection": "test"
}
},
{
"name": "createCollection",
"object": "database0",
"arguments": {
"collection": "test",
"changeStreamPreAndPostImages": {
"enabled": false
}
}
},
{
"name": "assertCollectionExists",
"object": "testRunner",
"arguments": {
"databaseName": "papi-tests",
"collectionName": "test"
}
},
{
"name": "modifyCollection",
"object": "database0",
"arguments": {
"collection": "test",
"changeStreamPreAndPostImages": {
"enabled": true
}
}
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": {
"drop": "test"
},
"databaseName": "papi-tests"
}
},
{
"commandStartedEvent": {
"command": {
"create": "test",
"changeStreamPreAndPostImages": {
"enabled": false
}
}
}
},
{
"commandStartedEvent": {
"command": {
"collMod": "test",
"changeStreamPreAndPostImages": {
"enabled": true
}
}
}
}
]
}
]
}
]
}

View File

@ -255,7 +255,7 @@
"description": "createCollection with bucketing options",
"runOnRequirements": [
{
"minServerVersion": "7.0"
"minServerVersion": "6.3"
}
],
"operations": [

View File

@ -1,119 +0,0 @@
{
"description": "pre-42-server-connection-id",
"schemaVersion": "1.13",
"runOnRequirements": [
{
"maxServerVersion": "4.0.99"
}
],
"createEntities": [
{
"client": {
"id": "client",
"observeLogMessages": {
"command": "debug"
}
}
},
{
"database": {
"id": "database",
"client": "client",
"databaseName": "logging-server-connection-id-tests"
}
},
{
"collection": {
"id": "collection",
"database": "database",
"collectionName": "logging-tests-collection"
}
}
],
"initialData": [
{
"databaseName": "logging-server-connection-id-tests",
"collectionName": "logging-tests-collection",
"documents": []
}
],
"tests": [
{
"description": "command log messages do not include server connection id",
"operations": [
{
"name": "insertOne",
"object": "collection",
"arguments": {
"document": {
"x": 1
}
}
},
{
"name": "find",
"object": "collection",
"arguments": {
"filter": {
"$or": true
}
},
"expectError": {
"isError": true
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "command",
"data": {
"message": "Command started",
"commandName": "insert",
"serverConnectionId": {
"$$exists": false
}
}
},
{
"level": "debug",
"component": "command",
"data": {
"message": "Command succeeded",
"commandName": "insert",
"serverConnectionId": {
"$$exists": false
}
}
},
{
"level": "debug",
"component": "command",
"data": {
"message": "Command started",
"commandName": "find",
"serverConnectionId": {
"$$exists": false
}
}
},
{
"level": "debug",
"component": "command",
"data": {
"message": "Command failed",
"commandName": "find",
"serverConnectionId": {
"$$exists": false
}
}
}
]
}
]
}
]
}

View File

@ -1,101 +0,0 @@
{
"description": "pre-42-server-connection-id",
"schemaVersion": "1.6",
"runOnRequirements": [
{
"maxServerVersion": "4.0.99"
}
],
"createEntities": [
{
"client": {
"id": "client",
"observeEvents": [
"commandStartedEvent",
"commandSucceededEvent",
"commandFailedEvent"
]
}
},
{
"database": {
"id": "database",
"client": "client",
"databaseName": "server-connection-id-tests"
}
},
{
"collection": {
"id": "collection",
"database": "database",
"collectionName": "coll"
}
}
],
"initialData": [
{
"databaseName": "server-connection-id-tests",
"collectionName": "coll",
"documents": []
}
],
"tests": [
{
"description": "command events do not include server connection id",
"operations": [
{
"name": "insertOne",
"object": "collection",
"arguments": {
"document": {
"x": 1
}
}
},
{
"name": "find",
"object": "collection",
"arguments": {
"filter": {
"$or": true
}
},
"expectError": {
"isError": true
}
}
],
"expectEvents": [
{
"client": "client",
"events": [
{
"commandStartedEvent": {
"commandName": "insert",
"hasServerConnectionId": false
}
},
{
"commandSucceededEvent": {
"commandName": "insert",
"hasServerConnectionId": false
}
},
{
"commandStartedEvent": {
"commandName": "find",
"hasServerConnectionId": false
}
},
{
"commandFailedEvent": {
"commandName": "find",
"hasServerConnectionId": false
}
}
]
}
]
}
]
}

View File

@ -446,6 +446,22 @@
}
}
},
{
"level": "debug",
"component": "connection",
"data": {
"message": "Connection pool cleared",
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
},
{
"level": "debug",
"component": "connection",
@ -498,26 +514,10 @@
]
}
}
},
{
"level": "debug",
"component": "connection",
"data": {
"message": "Connection pool cleared",
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
}
]
}
}

View File

@ -23,6 +23,7 @@
}
},
"poolOptions": {
"maxConnecting": 2,
"maxPoolSize": 10,
"waitQueueTimeoutMS": 5000
},
@ -72,9 +73,8 @@
"connection": "conn0"
},
{
"name": "waitForEvent",
"event": "ConnectionCheckedOut",
"count": 4
"name": "wait",
"ms": 100
}
],
"events": [
@ -104,14 +104,6 @@
"type": "ConnectionCheckedOut",
"connectionId": 1,
"address": 42
},
{
"type": "ConnectionCheckedOut",
"address": 42
},
{
"type": "ConnectionCheckedOut",
"address": 42
}
],
"ignore": [

View File

@ -59,4 +59,4 @@
}
}
]
}
}

View File

@ -112,4 +112,4 @@
}
}
]
}
}

View File

@ -1,5 +1,5 @@
{
"description": "client bulkWrite updateOne-sort",
"description": "client bulkWrite replaceOne-sort",
"schemaVersion": "1.4",
"runOnRequirements": [
{

View File

@ -11,7 +11,7 @@
"helloOk": true,
"isWritablePrimary": true,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
]
],

View File

@ -19,7 +19,7 @@
"b:27017"
],
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
]
],

View File

@ -18,7 +18,7 @@
"b:27017"
],
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
]
],

View File

@ -69,7 +69,7 @@
"a:27017"
],
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
],
[

View File

@ -18,7 +18,7 @@
"b:27017"
],
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
]
],

View File

@ -11,7 +11,7 @@
"helloOk": true,
"isWritablePrimary": true,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
]
],

View File

@ -11,7 +11,7 @@
"helloOk": true,
"isWritablePrimary": true,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
],
[
@ -21,7 +21,7 @@
"helloOk": true,
"isWritablePrimary": true,
"minWireVersion": 0,
"maxWireVersion": 6
"maxWireVersion": 21
}
]
],

View File

@ -47,29 +47,9 @@
}
}
],
"initialData": [
{
"collectionName": "server-selection",
"databaseName": "logging-tests",
"documents": [
{
"_id": 1,
"x": 11
},
{
"_id": 2,
"x": 22
},
{
"_id": 3,
"x": 33
}
]
}
],
"tests": [
{
"description": "A successful insert operation",
"description": "A successful operation",
"operations": [
{
"name": "waitForEvent",
@ -250,912 +230,6 @@
]
}
]
},
{
"description": "A successful find operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "findOne",
"object": "collection",
"arguments": {
"filter": {
"x": 1
}
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "find",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "find",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful findAndModify operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "findOneAndReplace",
"object": "collection",
"arguments": {
"filter": {
"x": 1
},
"replacement": {
"x": 11
}
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "findAndModify",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "findAndModify",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful find and getMore operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "find",
"object": "collection",
"arguments": {
"batchSize": 3
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "find",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "find",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "getMore",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "getMore",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful aggregate operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "aggregate",
"object": "collection",
"arguments": {
"pipeline": [
{
"$match": {
"_id": {
"$gt": 1
}
}
}
]
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "aggregate",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "aggregate",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful count operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "countDocuments",
"object": "collection",
"arguments": {
"filter": {}
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "count",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "count",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful distinct operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "distinct",
"object": "collection",
"arguments": {
"fieldName": "x",
"filter": {}
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "distinct",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "distinct",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "Successful collection management operations",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "createCollection",
"object": "database",
"arguments": {
"collection": "foo"
}
},
{
"name": "listCollections",
"object": "database"
},
{
"name": "dropCollection",
"object": "database",
"arguments": {
"collection": "foo"
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "create",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "create",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "listCollections",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "listCollections",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "drop",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "drop",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "Successful index operations",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "createIndex",
"object": "collection",
"arguments": {
"keys": {
"x": 1
},
"name": "x_1"
}
},
{
"name": "listIndexes",
"object": "collection"
},
{
"name": "dropIndex",
"object": "collection",
"arguments": {
"name": "x_1"
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "createIndexes",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "createIndexes",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "listIndexes",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "listIndexes",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "dropIndexes",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "dropIndexes",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful update operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "updateOne",
"object": "collection",
"arguments": {
"filter": {
"x": 1
},
"update": {
"$inc": {
"x": 1
}
}
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "update",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "update",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
},
{
"description": "A successful delete operation",
"operations": [
{
"name": "waitForEvent",
"object": "testRunner",
"arguments": {
"client": "client",
"event": {
"topologyDescriptionChangedEvent": {}
},
"count": 2
}
},
{
"name": "deleteOne",
"object": "collection",
"arguments": {
"filter": {
"x": 1
}
}
}
],
"expectLogMessages": [
{
"client": "client",
"messages": [
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection started",
"selector": {
"$$exists": true
},
"operation": "delete",
"topologyDescription": {
"$$exists": true
}
}
},
{
"level": "debug",
"component": "serverSelection",
"data": {
"message": "Server selection succeeded",
"selector": {
"$$exists": true
},
"operation": "delete",
"topologyDescription": {
"$$exists": true
},
"serverHost": {
"$$type": "string"
},
"serverPort": {
"$$type": [
"int",
"long"
]
}
}
}
]
}
]
}
]
}

View File

@ -188,7 +188,7 @@ class TestDatabase(IntegrationTest):
filter={"name": {"$regex": r"^(?!system\.)"}}
)
for coll in no_system_collections:
self.assertTrue(not coll.startswith("system."))
self.assertFalse(coll.startswith("system."))
self.assertIn("systemcoll.test", no_system_collections)
# Force more than one batch.
@ -264,19 +264,13 @@ class TestDatabase(IntegrationTest):
try:
# Found duplicate.
coll_cnt[coll] += 1
self.assertTrue(False)
self.fail("Found duplicate")
except KeyError:
coll_cnt[coll] = 1
coll_cnt: dict = {}
# Checking if is there any collection which don't exists.
if (
len(set(colls) - {"test", "test.mike"}) == 0
or len(set(colls) - {"test", "test.mike", "system.indexes"}) == 0
):
self.assertTrue(True)
else:
self.assertTrue(False)
# Check if there are any collections which don't exist.
self.assertLessEqual(set(colls), {"test", "test.mike", "system.indexes"})
colls = (db.list_collections(filter={"name": {"$regex": "^test$"}})).to_list()
self.assertEqual(1, len(colls))
@ -304,16 +298,13 @@ class TestDatabase(IntegrationTest):
try:
# Found duplicate.
coll_cnt[coll] += 1
self.assertTrue(False)
self.fail("Found duplicate")
except KeyError:
coll_cnt[coll] = 1
coll_cnt = {}
# Checking if is there any collection which don't exists.
if len(set(colls) - {"test"}) == 0 or len(set(colls) - {"test", "system.indexes"}) == 0:
self.assertTrue(True)
else:
self.assertTrue(False)
# Check if there are any collections which don't exist.
self.assertLessEqual(set(colls), {"test", "system.indexes"})
self.client.drop_database("pymongo_test")

View File

@ -162,17 +162,16 @@ class TestGridfs(IntegrationTest):
files.drop()
self.fs.upload_from_stream("filename", b"junk")
self.assertTrue(
any(
info.get("key") == [("files_id", 1), ("n", 1)]
for info in (chunks.index_information()).values()
)
self.assertIn(
[("files_id", 1), ("n", 1)],
[info.get("key") for info in (chunks.index_information()).values()],
"Missing required index on chunks collection: {files_id: 1, n: 1}",
)
self.assertTrue(
any(
info.get("key") == [("filename", 1), ("uploadDate", 1)]
for info in (files.index_information()).values()
)
self.assertIn(
[("filename", 1), ("uploadDate", 1)],
[info.get("key") for info in (files.index_information()).values()],
"Missing required index on files collection: {filename: 1, uploadDate: 1}",
)
def test_ensure_index_shell_compat(self):
@ -190,11 +189,10 @@ class TestGridfs(IntegrationTest):
# No error.
self.fs.upload_from_stream("filename", b"data")
self.assertTrue(
any(
info.get("key") == [("filename", 1), ("uploadDate", 1)]
for info in (files.index_information()).values()
)
self.assertIn(
[("filename", 1), ("uploadDate", 1)],
[info.get("key") for info in (files.index_information()).values()],
"Missing required index on files collection: {filename: 1, uploadDate: 1}",
)
files.drop()

View File

@ -510,9 +510,8 @@ class TestCommandMonitoring(IntegrationTest):
self.assertEqual(cursor.address, succeeded.connection_id)
# There could be more than one cursor_id here depending on
# when the thread last ran.
self.assertTrue(
cursor_id in succeeded.reply["cursorsUnknown"]
or cursor_id in succeeded.reply["cursorsKilled"]
self.assertIn(
cursor_id, succeeded.reply["cursorsUnknown"] + succeeded.reply["cursorsKilled"]
)
def test_non_bulk_writes(self):
@ -1064,7 +1063,7 @@ class TestCommandMonitoring(IntegrationTest):
self.assertEqual(2, len(errors))
fields = {"index", "code", "errmsg"}
for error in errors:
self.assertTrue(fields.issubset(set(error)))
self.assertLessEqual(fields, set(error))
def test_first_batch_helper(self):
# Regardless of server version and use of helpers._first_batch

View File

@ -518,6 +518,15 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
self.skipTest("Implement PYTHON-1894")
if "timeoutMS applied to entire download" in spec["description"]:
self.skipTest("PyMongo's open_download_stream does not cap the stream's lifetime")
if any(
x in spec["description"]
for x in [
"First insertOne is never committed",
"Second updateOne is never committed",
"Third updateOne is never committed",
]
):
self.skipTest("Implement PYTHON-4597")
class_name = self.__class__.__name__.lower()
description = spec["description"].lower()
@ -671,7 +680,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
self.match_evaluator.match_result(expect_result, result)
else:
self.fail(
f"expectResult can only be specified with {BulkWriteError} or {ClientBulkWriteException} exceptions"
f"expectResult can only be specified with {BulkWriteError} or {ClientBulkWriteException} exceptions, got {exception}"
)
return exception
@ -973,13 +982,9 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
if ignore and isinstance(exc, (PyMongoError,)):
return exc
if expect_error:
if method_name == "_collectionOperation_bulkWrite":
self.skipTest("Skipping test pending PYTHON-4598")
return self.process_error(exc, expect_error)
raise
else:
if method_name == "_collectionOperation_bulkWrite":
self.skipTest("Skipping test pending PYTHON-4598")
if expect_error:
self.fail(f'Excepted error {expect_error} but "{opname}" succeeded: {result}')