From ab44a21b46a2089d1de68e3c84f73e7d5bed9d28 Mon Sep 17 00:00:00 2001 From: Jeffrey 'Alex' Clark Date: Fri, 24 Apr 2026 09:04:02 -0400 Subject: [PATCH 1/6] PYTHON-5780 Increase code coverage for pyopenssl_context.py (#2773) --- test/test_pyopenssl_context.py | 271 +++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 test/test_pyopenssl_context.py diff --git a/test/test_pyopenssl_context.py b/test/test_pyopenssl_context.py new file mode 100644 index 000000000..c3afaf015 --- /dev/null +++ b/test/test_pyopenssl_context.py @@ -0,0 +1,271 @@ +# Copyright 2026-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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for pyopenssl_context.py. + +These tests require PyOpenSSL (install via: pip install pymongo[ocsp]). +Tests are automatically skipped when PyOpenSSL is not available. +""" + +from __future__ import annotations + +import ssl +import sys +from unittest.mock import patch + +sys.path[0:0] = [""] + +from test import unittest + +try: + from pymongo import pyopenssl_context as _ctx_module + from pymongo.pyopenssl_context import ( + PROTOCOL_SSLv23, + SSLContext, + _is_ip_address, + _ragged_eof, + ) + + _HAVE_PYOPENSSL = True +except ImportError: + _HAVE_PYOPENSSL = False + + +# --------------------------------------------------------------------------- +# Pure functions (no SSL context required) +# --------------------------------------------------------------------------- + + +class TestIsIpAddress(unittest.TestCase): + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_ipv4(self): + self.assertTrue(_is_ip_address("192.168.1.1")) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_ipv6(self): + self.assertTrue(_is_ip_address("::1")) + self.assertTrue(_is_ip_address("2001:db8::1")) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_hostname_is_not_ip(self): + self.assertFalse(_is_ip_address("example.com")) + self.assertFalse(_is_ip_address("localhost")) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_invalid_string_returns_false(self): + self.assertFalse(_is_ip_address("not-an-ip")) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_unicode_error_returns_false(self): + # UnicodeError path: some inputs that can't be decoded. + # ip_address raises UnicodeError for byte strings with non-ASCII. + self.assertFalse(_is_ip_address(b"\xff\xfe")) + + +class TestRaggedEof(unittest.TestCase): + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_matching_args_returns_true(self): + from OpenSSL.SSL import SysCallError + + exc = SysCallError(-1, "Unexpected EOF") + self.assertTrue(_ragged_eof(exc)) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_non_matching_args_returns_false(self): + from OpenSSL.SSL import SysCallError + + exc = SysCallError(0, "something else") + self.assertFalse(_ragged_eof(exc)) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_wrong_code_returns_false(self): + from OpenSSL.SSL import SysCallError + + exc = SysCallError(5, "Unexpected EOF") + self.assertFalse(_ragged_eof(exc)) + + +# --------------------------------------------------------------------------- +# SSLContext — construction and properties +# --------------------------------------------------------------------------- + + +class TestSSLContextConstruction(unittest.TestCase): + def _make(self): + return SSLContext(PROTOCOL_SSLv23) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_protocol_property(self): + ctx = self._make() + self.assertEqual(ctx.protocol, PROTOCOL_SSLv23) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_default_check_hostname(self): + ctx = self._make() + self.assertTrue(ctx.check_hostname) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_set_check_hostname_false(self): + ctx = self._make() + ctx.check_hostname = False + self.assertFalse(ctx.check_hostname) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_set_check_hostname_invalid_raises(self): + ctx = self._make() + with self.assertRaises(TypeError): + ctx.check_hostname = "yes" + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_default_check_ocsp_endpoint(self): + ctx = self._make() + self.assertTrue(ctx.check_ocsp_endpoint) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_set_check_ocsp_endpoint_false(self): + ctx = self._make() + ctx.check_ocsp_endpoint = False + self.assertFalse(ctx.check_ocsp_endpoint) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_verify_mode_roundtrip(self): + ctx = self._make() + ctx.verify_mode = ssl.CERT_REQUIRED + self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_verify_mode_cert_none(self): + ctx = self._make() + ctx.verify_mode = ssl.CERT_NONE + self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_options_setter_and_getter(self): + ctx = self._make() + from pymongo.pyopenssl_context import OP_NO_SSLv3 + + ctx.options = OP_NO_SSLv3 + self.assertTrue(ctx.options & OP_NO_SSLv3) + + +# --------------------------------------------------------------------------- +# SSLContext._load_certifi +# --------------------------------------------------------------------------- + + +class TestLoadCertifi(unittest.TestCase): + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_raises_when_certifi_unavailable(self): + from pymongo.errors import ConfigurationError + + ctx = SSLContext(PROTOCOL_SSLv23) + with patch.object(_ctx_module, "_HAVE_CERTIFI", False): + with self.assertRaises(ConfigurationError) as exc_ctx: + ctx._load_certifi() + self.assertIn("certifi", str(exc_ctx.exception)) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_loads_when_certifi_available(self): + if not _ctx_module._HAVE_CERTIFI: + self.skipTest("certifi not installed") + ctx = SSLContext(PROTOCOL_SSLv23) + ctx.verify_mode = ssl.CERT_NONE + # Should not raise. + ctx._load_certifi() + + +# --------------------------------------------------------------------------- +# SSLContext.load_default_certs — platform branching +# --------------------------------------------------------------------------- + + +class TestLoadDefaultCerts(unittest.TestCase): + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_darwin_calls_load_certifi(self): + with patch.object(_ctx_module._sys, "platform", "darwin"): + with patch.object(SSLContext, "_load_certifi") as mock_certifi: + with patch("OpenSSL.SSL.Context.set_default_verify_paths"): + ctx = SSLContext(PROTOCOL_SSLv23) + ctx.load_default_certs() + mock_certifi.assert_called() + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_win32_calls_load_wincerts(self): + with patch.object(_ctx_module._sys, "platform", "win32"): + with patch.object(SSLContext, "_load_wincerts") as mock_wincerts: + with patch("OpenSSL.SSL.Context.set_default_verify_paths"): + ctx = SSLContext(PROTOCOL_SSLv23) + ctx.load_default_certs() + calls = [call.args[0] for call in mock_wincerts.call_args_list] + self.assertIn("CA", calls) + self.assertIn("ROOT", calls) + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_win32_falls_back_to_certifi_on_exception(self): + with patch.object(_ctx_module._sys, "platform", "win32"): + with patch.object(SSLContext, "_load_wincerts", side_effect=Exception("no certs")): + with patch.object(SSLContext, "_load_certifi") as mock_certifi: + with patch("OpenSSL.SSL.Context.set_default_verify_paths"): + ctx = SSLContext(PROTOCOL_SSLv23) + ctx.load_default_certs() + mock_certifi.assert_called() + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_linux_no_certifi_call(self): + with patch.object(_ctx_module._sys, "platform", "linux"): + with patch.object(SSLContext, "_load_certifi") as mock_certifi: + with patch("OpenSSL.SSL.Context.set_default_verify_paths"): + ctx = SSLContext(PROTOCOL_SSLv23) + ctx.load_default_certs() + mock_certifi.assert_not_called() + + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_calls_set_default_verify_paths(self): + with patch.object(_ctx_module._sys, "platform", "linux"): + ctx = SSLContext(PROTOCOL_SSLv23) + with patch.object(ctx._ctx, "set_default_verify_paths") as mock_sdvp: + ctx.load_default_certs() + mock_sdvp.assert_called_once() + + +# --------------------------------------------------------------------------- +# SSLContext.set_default_verify_paths +# --------------------------------------------------------------------------- + + +class TestSetDefaultVerifyPaths(unittest.TestCase): + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_delegates_to_ctx(self): + ctx = SSLContext(PROTOCOL_SSLv23) + with patch.object(ctx._ctx, "set_default_verify_paths") as mock_sdvp: + ctx.set_default_verify_paths() + mock_sdvp.assert_called_once() + + +# --------------------------------------------------------------------------- +# SSLContext.load_verify_locations +# --------------------------------------------------------------------------- + + +class TestLoadVerifyLocations(unittest.TestCase): + @unittest.skipUnless(_HAVE_PYOPENSSL, "PyOpenSSL is not available.") + def test_delegates_to_ctx(self): + ctx = SSLContext(PROTOCOL_SSLv23) + with patch.object(ctx._ctx, "load_verify_locations") as mock_lvl: + ctx.load_verify_locations(cafile="/tmp/ca.pem") + mock_lvl.assert_called_once_with("/tmp/ca.pem", None) + + +if __name__ == "__main__": + unittest.main() From b3f1c4befba72de19452a98cefc1237824c86855 Mon Sep 17 00:00:00 2001 From: Jeffrey 'Alex' Clark Date: Mon, 27 Apr 2026 15:55:18 -0400 Subject: [PATCH 2/6] [Spec Resync] Remove stale spec patches for closed tickets (#2782) --- .evergreen/spec-patch/PYTHON-2673.patch | 64 ------------------------- .evergreen/spec-patch/PYTHON-3712.patch | 14 ------ .evergreen/spec-patch/PYTHON-4261.patch | 61 ----------------------- 3 files changed, 139 deletions(-) delete mode 100644 .evergreen/spec-patch/PYTHON-2673.patch delete mode 100644 .evergreen/spec-patch/PYTHON-3712.patch delete mode 100644 .evergreen/spec-patch/PYTHON-4261.patch diff --git a/.evergreen/spec-patch/PYTHON-2673.patch b/.evergreen/spec-patch/PYTHON-2673.patch deleted file mode 100644 index 868538f7b..000000000 --- a/.evergreen/spec-patch/PYTHON-2673.patch +++ /dev/null @@ -1,64 +0,0 @@ -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": {} - } - ] - } diff --git a/.evergreen/spec-patch/PYTHON-3712.patch b/.evergreen/spec-patch/PYTHON-3712.patch deleted file mode 100644 index b48c05124..000000000 --- a/.evergreen/spec-patch/PYTHON-3712.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/test/discovery_and_monitoring/unified/serverMonitoringMode.json b/test/discovery_and_monitoring/unified/serverMonitoringMode.json -index e44fad1b..4b492f7d 100644 ---- a/test/discovery_and_monitoring/unified/serverMonitoringMode.json -+++ b/test/discovery_and_monitoring/unified/serverMonitoringMode.json -@@ -5,7 +5,8 @@ - { - "topologies": [ - "single", -- "sharded" -+ "sharded", -+ "sharded-replicaset" - ], - "serverless": "forbid" - } diff --git a/.evergreen/spec-patch/PYTHON-4261.patch b/.evergreen/spec-patch/PYTHON-4261.patch deleted file mode 100644 index e4ffc5ce9..000000000 --- a/.evergreen/spec-patch/PYTHON-4261.patch +++ /dev/null @@ -1,61 +0,0 @@ -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", From 64edd22d73e801e61b6a46c0b19e99e61bfdc517 Mon Sep 17 00:00:00 2001 From: "mongodb-drivers-pr-bot[bot]" <147046816+mongodb-drivers-pr-bot[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:56:10 -0400 Subject: [PATCH 3/6] [Spec Resync] 04-20-2026 (#2766) Co-authored-by: Cloud User Co-authored-by: Jeffrey 'Alex' Clark --- .evergreen/spec-patch/PYTHON-5517.patch | 31 -- .../change-streams-disambiguatedPaths.json | 85 +++ .../unified/fle2v2-InsertFind-keyAltName.json | 485 ++++++++++++++++++ .../pool-create-min-size-error.json | 4 +- ...ressure-network-error-fail-replicaset.json | 142 ----- ...ackpressure-network-error-fail-single.json | 142 ----- ...ssure-network-timeout-fail-replicaset.json | 145 ------ ...kpressure-network-timeout-fail-single.json | 145 ------ ...ged-on-min-pool-size-population-error.json | 106 ---- 9 files changed, 573 insertions(+), 712 deletions(-) delete mode 100644 .evergreen/spec-patch/PYTHON-5517.patch create mode 100644 test/client-side-encryption/spec/unified/fle2v2-InsertFind-keyAltName.json delete mode 100644 test/discovery_and_monitoring/unified/backpressure-network-error-fail-replicaset.json delete mode 100644 test/discovery_and_monitoring/unified/backpressure-network-error-fail-single.json delete mode 100644 test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-replicaset.json delete mode 100644 test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-single.json delete mode 100644 test/discovery_and_monitoring/unified/backpressure-server-description-unchanged-on-min-pool-size-population-error.json diff --git a/.evergreen/spec-patch/PYTHON-5517.patch b/.evergreen/spec-patch/PYTHON-5517.patch deleted file mode 100644 index adf453fd1..000000000 --- a/.evergreen/spec-patch/PYTHON-5517.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/test/discovery_and_monitoring/errors/error_handling_handshake.json b/test/discovery_and_monitoring/errors/error_handling_handshake.json -index 56ca7d113..bf83f46f6 100644 ---- a/test/discovery_and_monitoring/errors/error_handling_handshake.json -+++ b/test/discovery_and_monitoring/errors/error_handling_handshake.json -@@ -97,14 +97,22 @@ - "outcome": { - "servers": { - "a:27017": { -- "type": "Unknown", -- "topologyVersion": null, -+ "type": "RSPrimary", -+ "setName": "rs", -+ "topologyVersion": { -+ "processId": { -+ "$oid": "000000000000000000000001" -+ }, -+ "counter": { -+ "$numberLong": "1" -+ } -+ }, - "pool": { -- "generation": 1 -+ "generation": 0 - } - } - }, -- "topologyType": "ReplicaSetNoPrimary", -+ "topologyType": "ReplicaSetWithPrimary", - "logicalSessionTimeoutMinutes": null, - "setName": "rs" - } diff --git a/test/change_streams/unified/change-streams-disambiguatedPaths.json b/test/change_streams/unified/change-streams-disambiguatedPaths.json index a8667b543..df7422295 100644 --- a/test/change_streams/unified/change-streams-disambiguatedPaths.json +++ b/test/change_streams/unified/change-streams-disambiguatedPaths.json @@ -42,6 +42,91 @@ } ], "tests": [ + { + "description": "disambiguatedPaths is not present when showExpandedEvents is false/unset", + "runOnRequirements": [ + { + "minServerVersion": "6.1.0", + "maxServerVersion": "8.1.99", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + }, + { + "minServerVersion": "8.2.1", + "topologies": [ + "replicaset", + "load-balanced", + "sharded" + ], + "serverless": "forbid" + } + ], + "operations": [ + { + "name": "insertOne", + "object": "collection0", + "arguments": { + "document": { + "_id": 1, + "a": { + "1": 1 + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [] + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "a.1": 2 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "database0", + "coll": "collection0" + }, + "updateDescription": { + "updatedFields": { + "$$exists": true + }, + "removedFields": { + "$$exists": true + }, + "truncatedArrays": { + "$$exists": true + }, + "disambiguatedPaths": { + "$$exists": false + } + } + } + } + ] + }, { "description": "disambiguatedPaths is present on updateDescription when an ambiguous path is present", "operations": [ diff --git a/test/client-side-encryption/spec/unified/fle2v2-InsertFind-keyAltName.json b/test/client-side-encryption/spec/unified/fle2v2-InsertFind-keyAltName.json new file mode 100644 index 000000000..ef13a3b2d --- /dev/null +++ b/test/client-side-encryption/spec/unified/fle2v2-InsertFind-keyAltName.json @@ -0,0 +1,485 @@ +{ + "description": "fle2v2-InsertFind-keyAltName", + "schemaVersion": "1.25", + "runOnRequirements": [ + { + "minServerVersion": "7.0.0", + "topologies": [ + "replicaset", + "sharded", + "load-balanced" + ], + "csfle": { + "minLibmongocryptVersion": "1.18.0" + } + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "autoEncryptOpts": { + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" + } + }, + "encryptedFieldsMap": { + "default.default": { + "fields": [ + { + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + }, + "keyAltName": "altname" + } + ] + } + } + }, + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "db", + "client": "client0", + "databaseName": "default" + } + }, + { + "collection": { + "id": "coll", + "database": "db", + "collectionName": "default" + } + }, + { + "client": { + "id": "client_unencrypted", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "db_unencrypted", + "client": "client_unencrypted", + "databaseName": "default" + } + }, + { + "collection": { + "id": "coll_unencrypted", + "database": "db_unencrypted", + "collectionName": "default" + } + } + ], + "initialData": [ + { + "databaseName": "default", + "collectionName": "default", + "documents": [], + "createOptions": { + "encryptedFields": { + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + }, + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + }, + "keyAltNames": [ + "altname" + ] + } + ] + } + ], + "tests": [ + { + "description": "Insert and find FLE2 indexed field", + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "123" + } + }, + "object": "coll" + }, + { + "name": "find", + "arguments": { + "filter": { + "encryptedIndexed": "123" + } + }, + "object": "coll", + "expectResult": [ + { + "_id": 1, + "encryptedIndexed": "123" + } + ] + }, + { + "name": "find", + "object": "coll_unencrypted", + "arguments": { + "filter": {} + }, + "expectResult": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "__safeContent__": [ + { + "$binary": { + "base64": "31eCYlbQoVboc5zwC8IoyJVSkag9PxREka8dkmbXJeY=", + "subType": "00" + } + } + ] + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [] + } + }, + { + "keyAltNames": { + "$in": [ + "altname" + ] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "commandName": "find" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } + }, + "commandName": "insert" + } + }, + { + "commandStartedEvent": { + "command": { + "find": "default", + "filter": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "DIkAAAAFZAAgAAAAAPGmZcUzdE/FPILvRSyAScGvZparGI2y9rJ/vSBxgCujBXMAIAAAAACi1RjmndKqgnXy7xb22RzUbnZl1sOZRXPOC0KcJkAxmQVsACAAAAAApJtKPW4+o9B7gAynNLL26jtlB4+hq5TXResijcYet8USY20AAAAAAAAAAAAA", + "subType": "06" + } + } + } + }, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } + }, + "commandName": "find" + } + } + ] + } + ] + }, + { + "description": "Create translates keyAltName", + "operations": [ + { + "name": "dropCollection", + "object": "db", + "arguments": { + "collection": "default" + } + }, + { + "name": "createCollection", + "object": "db", + "arguments": { + "collection": "default" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "drop": "enxcol_.default.esc" + }, + "commandName": "drop" + } + }, + { + "commandStartedEvent": { + "command": { + "drop": "enxcol_.default.ecoc" + }, + "commandName": "drop" + } + }, + { + "commandStartedEvent": { + "command": { + "drop": "default" + }, + "commandName": "drop" + } + }, + { + "commandStartedEvent": { + "command": { + "create": "enxcol_.default.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "commandName": "create" + } + }, + { + "commandStartedEvent": { + "command": { + "create": "enxcol_.default.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "commandName": "create" + } + }, + { + "commandStartedEvent": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [] + } + }, + { + "keyAltNames": { + "$in": [ + "altname" + ] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "commandName": "find" + } + }, + { + "commandStartedEvent": { + "command": { + "create": "default", + "encryptedFields": { + "fields": [ + { + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + }, + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + } + ] + } + }, + "commandName": "create" + } + }, + { + "commandStartedEvent": { + "command": { + "createIndexes": "default", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "commandName": "createIndexes" + } + } + ] + } + ] + } + ] +} diff --git a/test/connection_monitoring/pool-create-min-size-error.json b/test/connection_monitoring/pool-create-min-size-error.json index 4334ce257..5c8ad02db 100644 --- a/test/connection_monitoring/pool-create-min-size-error.json +++ b/test/connection_monitoring/pool-create-min-size-error.json @@ -9,7 +9,9 @@ ], "failPoint": { "configureFailPoint": "failCommand", - "mode": "alwaysOn", + "mode": { + "times": 50 + }, "data": { "failCommands": [ "isMaster", diff --git a/test/discovery_and_monitoring/unified/backpressure-network-error-fail-replicaset.json b/test/discovery_and_monitoring/unified/backpressure-network-error-fail-replicaset.json deleted file mode 100644 index ccaea8d13..000000000 --- a/test/discovery_and_monitoring/unified/backpressure-network-error-fail-replicaset.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "description": "backpressure-network-error-fail-replicaset", - "schemaVersion": "1.17", - "runOnRequirements": [ - { - "minServerVersion": "4.4", - "serverless": "forbid", - "topologies": [ - "replicaset" - ] - } - ], - "createEntities": [ - { - "client": { - "id": "setupClient", - "useMultipleMongoses": false - } - } - ], - "initialData": [ - { - "collectionName": "backpressure-network-error-fail", - "databaseName": "sdam-tests", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - ], - "tests": [ - { - "description": "apply backpressure on network connection errors during connection establishment", - "operations": [ - { - "name": "createEntities", - "object": "testRunner", - "arguments": { - "entities": [ - { - "client": { - "id": "client", - "useMultipleMongoses": false, - "observeEvents": [ - "serverDescriptionChangedEvent", - "poolClearedEvent" - ], - "uriOptions": { - "retryWrites": false, - "heartbeatFrequencyMS": 1000000, - "serverMonitoringMode": "poll", - "appname": "backpressureNetworkErrorFailTest" - } - } - }, - { - "database": { - "id": "database", - "client": "client", - "databaseName": "sdam-tests" - } - }, - { - "collection": { - "id": "collection", - "database": "database", - "collectionName": "backpressure-network-error-fail" - } - } - ] - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "client": "client", - "event": { - "serverDescriptionChangedEvent": { - "newDescription": { - "type": "RSPrimary" - } - } - }, - "count": 1 - } - }, - { - "name": "failPoint", - "object": "testRunner", - "arguments": { - "client": "setupClient", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": "alwaysOn", - "data": { - "failCommands": [ - "isMaster", - "hello" - ], - "appName": "backpressureNetworkErrorFailTest", - "closeConnection": true - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "expectError": { - "isError": true, - "errorLabelsContain": [ - "SystemOverloadedError", - "RetryableError" - ] - } - } - ], - "expectEvents": [ - { - "client": "client", - "eventType": "cmap", - "events": [] - } - ] - } - ] -} diff --git a/test/discovery_and_monitoring/unified/backpressure-network-error-fail-single.json b/test/discovery_and_monitoring/unified/backpressure-network-error-fail-single.json deleted file mode 100644 index c1ff67c73..000000000 --- a/test/discovery_and_monitoring/unified/backpressure-network-error-fail-single.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "description": "backpressure-network-error-fail-single", - "schemaVersion": "1.17", - "runOnRequirements": [ - { - "minServerVersion": "4.4", - "serverless": "forbid", - "topologies": [ - "single" - ] - } - ], - "createEntities": [ - { - "client": { - "id": "setupClient", - "useMultipleMongoses": false - } - } - ], - "initialData": [ - { - "collectionName": "backpressure-network-error-fail", - "databaseName": "sdam-tests", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - ], - "tests": [ - { - "description": "apply backpressure on network connection errors during connection establishment", - "operations": [ - { - "name": "createEntities", - "object": "testRunner", - "arguments": { - "entities": [ - { - "client": { - "id": "client", - "useMultipleMongoses": false, - "observeEvents": [ - "serverDescriptionChangedEvent", - "poolClearedEvent" - ], - "uriOptions": { - "retryWrites": false, - "heartbeatFrequencyMS": 1000000, - "serverMonitoringMode": "poll", - "appname": "backpressureNetworkErrorFailTest" - } - } - }, - { - "database": { - "id": "database", - "client": "client", - "databaseName": "sdam-tests" - } - }, - { - "collection": { - "id": "collection", - "database": "database", - "collectionName": "backpressure-network-error-fail" - } - } - ] - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "client": "client", - "event": { - "serverDescriptionChangedEvent": { - "newDescription": { - "type": "Standalone" - } - } - }, - "count": 1 - } - }, - { - "name": "failPoint", - "object": "testRunner", - "arguments": { - "client": "setupClient", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": "alwaysOn", - "data": { - "failCommands": [ - "isMaster", - "hello" - ], - "appName": "backpressureNetworkErrorFailTest", - "closeConnection": true - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "expectError": { - "isError": true, - "errorLabelsContain": [ - "SystemOverloadedError", - "RetryableError" - ] - } - } - ], - "expectEvents": [ - { - "client": "client", - "eventType": "cmap", - "events": [] - } - ] - } - ] -} diff --git a/test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-replicaset.json b/test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-replicaset.json deleted file mode 100644 index 35b088f42..000000000 --- a/test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-replicaset.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "description": "backpressure-network-timeout-error-replicaset", - "schemaVersion": "1.17", - "runOnRequirements": [ - { - "minServerVersion": "4.4", - "serverless": "forbid", - "topologies": [ - "replicaset" - ] - } - ], - "createEntities": [ - { - "client": { - "id": "setupClient", - "useMultipleMongoses": false - } - } - ], - "initialData": [ - { - "collectionName": "backpressure-network-timeout-error", - "databaseName": "sdam-tests", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - ], - "tests": [ - { - "description": "apply backpressure on network timeout error during connection establishment", - "operations": [ - { - "name": "createEntities", - "object": "testRunner", - "arguments": { - "entities": [ - { - "client": { - "id": "client", - "useMultipleMongoses": false, - "observeEvents": [ - "serverDescriptionChangedEvent", - "poolClearedEvent" - ], - "uriOptions": { - "retryWrites": false, - "heartbeatFrequencyMS": 1000000, - "appname": "backpressureNetworkTimeoutErrorTest", - "serverMonitoringMode": "poll", - "connectTimeoutMS": 250, - "socketTimeoutMS": 250 - } - } - }, - { - "database": { - "id": "database", - "client": "client", - "databaseName": "sdam-tests" - } - }, - { - "collection": { - "id": "collection", - "database": "database", - "collectionName": "backpressure-network-timeout-error" - } - } - ] - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "client": "client", - "event": { - "serverDescriptionChangedEvent": { - "newDescription": { - "type": "RSPrimary" - } - } - }, - "count": 1 - } - }, - { - "name": "failPoint", - "object": "testRunner", - "arguments": { - "client": "setupClient", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": "alwaysOn", - "data": { - "failCommands": [ - "isMaster", - "hello" - ], - "blockConnection": true, - "blockTimeMS": 500, - "appName": "backpressureNetworkTimeoutErrorTest" - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "expectError": { - "isError": true, - "errorLabelsContain": [ - "SystemOverloadedError", - "RetryableError" - ] - } - } - ], - "expectEvents": [ - { - "client": "client", - "eventType": "cmap", - "events": [] - } - ] - } - ] -} diff --git a/test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-single.json b/test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-single.json deleted file mode 100644 index 54b11d4d5..000000000 --- a/test/discovery_and_monitoring/unified/backpressure-network-timeout-fail-single.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "description": "backpressure-network-timeout-error-single", - "schemaVersion": "1.17", - "runOnRequirements": [ - { - "minServerVersion": "4.4", - "serverless": "forbid", - "topologies": [ - "single" - ] - } - ], - "createEntities": [ - { - "client": { - "id": "setupClient", - "useMultipleMongoses": false - } - } - ], - "initialData": [ - { - "collectionName": "backpressure-network-timeout-error", - "databaseName": "sdam-tests", - "documents": [ - { - "_id": 1 - }, - { - "_id": 2 - } - ] - } - ], - "tests": [ - { - "description": "apply backpressure on network timeout error during connection establishment", - "operations": [ - { - "name": "createEntities", - "object": "testRunner", - "arguments": { - "entities": [ - { - "client": { - "id": "client", - "useMultipleMongoses": false, - "observeEvents": [ - "serverDescriptionChangedEvent", - "poolClearedEvent" - ], - "uriOptions": { - "retryWrites": false, - "heartbeatFrequencyMS": 1000000, - "appname": "backpressureNetworkTimeoutErrorTest", - "serverMonitoringMode": "poll", - "connectTimeoutMS": 250, - "socketTimeoutMS": 250 - } - } - }, - { - "database": { - "id": "database", - "client": "client", - "databaseName": "sdam-tests" - } - }, - { - "collection": { - "id": "collection", - "database": "database", - "collectionName": "backpressure-network-timeout-error" - } - } - ] - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "client": "client", - "event": { - "serverDescriptionChangedEvent": { - "newDescription": { - "type": "Standalone" - } - } - }, - "count": 1 - } - }, - { - "name": "failPoint", - "object": "testRunner", - "arguments": { - "client": "setupClient", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": "alwaysOn", - "data": { - "failCommands": [ - "isMaster", - "hello" - ], - "blockConnection": true, - "blockTimeMS": 500, - "appName": "backpressureNetworkTimeoutErrorTest" - } - } - } - }, - { - "name": "insertMany", - "object": "collection", - "arguments": { - "documents": [ - { - "_id": 3 - }, - { - "_id": 4 - } - ] - }, - "expectError": { - "isError": true, - "errorLabelsContain": [ - "SystemOverloadedError", - "RetryableError" - ] - } - } - ], - "expectEvents": [ - { - "client": "client", - "eventType": "cmap", - "events": [] - } - ] - } - ] -} diff --git a/test/discovery_and_monitoring/unified/backpressure-server-description-unchanged-on-min-pool-size-population-error.json b/test/discovery_and_monitoring/unified/backpressure-server-description-unchanged-on-min-pool-size-population-error.json deleted file mode 100644 index f0597124b..000000000 --- a/test/discovery_and_monitoring/unified/backpressure-server-description-unchanged-on-min-pool-size-population-error.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "description": "backpressure-server-description-unchanged-on-min-pool-size-population-error", - "schemaVersion": "1.17", - "runOnRequirements": [ - { - "minServerVersion": "4.4", - "serverless": "forbid", - "topologies": [ - "single" - ] - } - ], - "createEntities": [ - { - "client": { - "id": "setupClient", - "useMultipleMongoses": false - } - } - ], - "tests": [ - { - "description": "the server description is not changed on handshake error during minPoolSize population", - "operations": [ - { - "name": "failPoint", - "object": "testRunner", - "arguments": { - "client": "setupClient", - "failPoint": { - "configureFailPoint": "failCommand", - "mode": { - "skip": 1 - }, - "data": { - "failCommands": [ - "hello", - "isMaster" - ], - "appName": "authErrorTest", - "closeConnection": true - } - } - } - }, - { - "name": "createEntities", - "object": "testRunner", - "arguments": { - "entities": [ - { - "client": { - "id": "client", - "observeEvents": [ - "serverDescriptionChangedEvent", - "connectionClosedEvent" - ], - "uriOptions": { - "appname": "authErrorTest", - "minPoolSize": 5, - "maxConnecting": 1, - "serverMonitoringMode": "poll", - "heartbeatFrequencyMS": 1000000 - } - } - } - ] - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "client": "client", - "event": { - "serverDescriptionChangedEvent": {} - }, - "count": 1 - } - }, - { - "name": "waitForEvent", - "object": "testRunner", - "arguments": { - "client": "client", - "event": { - "connectionClosedEvent": {} - }, - "count": 1 - } - } - ], - "expectEvents": [ - { - "client": "client", - "eventType": "sdam", - "events": [ - { - "serverDescriptionChangedEvent": {} - } - ] - } - ] - } - ] -} From e67931dff778dd57a1282c48b82899544da6a61c Mon Sep 17 00:00:00 2001 From: Jeffrey 'Alex' Clark Date: Mon, 27 Apr 2026 19:45:36 -0400 Subject: [PATCH 4/6] PYTHON-5776 Add documentation comments to justfile recipes (#2784) --- justfile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/justfile b/justfile index 3a8e216db..55ff9e74d 100644 --- a/justfile +++ b/justfile @@ -16,64 +16,78 @@ default: resync: @uv sync --quiet +# Set up the development environment install: bash .evergreen/scripts/setup-dev-env.sh +# Build the HTML documentation [group('docs')] docs: && resync {{docs_run}} sphinx-build -W -b html doc {{doc_build}}/html +# Serve the docs locally with live-reload [group('docs')] docs-serve: && resync {{docs_run}} sphinx-autobuild -W -b html doc --watch ./pymongo --watch ./bson --watch ./gridfs {{doc_build}}/serve +# Check documentation hyperlinks for broken URLs [group('docs')] docs-linkcheck: && resync {{docs_run}} sphinx-build -E -b linkcheck doc {{doc_build}}/linkcheck +# Run mypy and pyright [group('typing')] typing: && resync just typing-mypy just typing-pyright +# Run mypy against the library source and test suite [group('typing')] typing-mypy: && resync {{typing_run}} python -m mypy {{mypy_args}} bson gridfs tools pymongo {{typing_run}} python -m mypy {{mypy_args}} --config-file mypy_test.ini test {{typing_run}} python -m mypy {{mypy_args}} test/test_typing.py test/test_typing_strict.py +# Run pyright against the typing test files [group('typing')] typing-pyright: && resync {{typing_run}} python -m pyright test/test_typing.py test/test_typing_strict.py {{typing_run}} python -m pyright -p strict_pyrightconfig.json test/test_typing_strict.py +# Run all pre-commit hooks across the repository [group('lint')] lint *args="": && resync uvx pre-commit run --all-files {{args}} +# Run shellcheck, doc8, and slotscheck [group('lint')] lint-manual *args="": && resync uvx pre-commit run --all-files --hook-stage manual {{args}} +# Run pytest (e.g. just test test/test_uri_parser.py) [group('test')] test *args="-v --durations=5 --maxfail=10": && resync #!/usr/bin/env bash set -euo pipefail uv run ${USE_ACTIVE_VENV:+--active} --extra test python -m pytest {{args}} +# Run the BSON test suite with numpy [group('test')] test-numpy *args="": && resync just setup-tests numpy {{args}} just run-tests test/test_bson.py +# Run tests via the Evergreen test runner script [group('test')] run-tests *args: && resync bash ./.evergreen/run-tests.sh {{args}} +# Set up the test environment (auth, TLS, etc.) [group('test')] setup-tests *args="": bash .evergreen/scripts/setup-tests.sh {{args}} +# Tear down resources created by setup-tests [group('test')] teardown-tests: bash .evergreen/scripts/teardown-tests.sh @@ -82,25 +96,30 @@ teardown-tests: integration-tests: bash integration_tests/run.sh +# Run the full test suite with coverage [group('test')] test-coverage *args="": just setup-tests --cov just run-tests {{args}} +# Print the coverage summary to the terminal [group('coverage')] coverage-report: uv tool run --with "coverage[toml]" coverage report +# Generate an HTML coverage report in htmlcov/ [group('coverage')] coverage-html: uv tool run --with "coverage[toml]" coverage html @echo "Coverage report generated in htmlcov/index.html" +# Generate an XML coverage report at coverage.xml [group('coverage')] coverage-xml: uv tool run --with "coverage[toml]" coverage xml @echo "Coverage report generated in coverage.xml" +# Start a MongoDB server via drivers-evergreen-tools [group('server')] run-server *args="": bash .evergreen/scripts/run-server.sh {{args}} From c30eff1291252a6ab3321fe0d70677adaa5e5616 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Tue, 5 May 2026 11:40:19 -0400 Subject: [PATCH 5/6] =?UTF-8?q?PYTHON-5811=20-=20Change=20stream=20events?= =?UTF-8?q?=20are=20not=20emitted=20for=20timeseries=20as=20=E2=80=A6=20(#?= =?UTF-8?q?2791)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unified/change-streams-nsType.json | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/test/change_streams/unified/change-streams-nsType.json b/test/change_streams/unified/change-streams-nsType.json index 1861c9a5e..877ca9c00 100644 --- a/test/change_streams/unified/change-streams-nsType.json +++ b/test/change_streams/unified/change-streams-nsType.json @@ -63,47 +63,6 @@ } ] }, - { - "description": "nsType is present when creating timeseries", - "operations": [ - { - "name": "dropCollection", - "object": "database0", - "arguments": { - "collection": "foo" - } - }, - { - "name": "createChangeStream", - "object": "database0", - "arguments": { - "pipeline": [], - "showExpandedEvents": true - }, - "saveResultAsEntity": "changeStream0" - }, - { - "name": "createCollection", - "object": "database0", - "arguments": { - "collection": "foo", - "timeseries": { - "timeField": "time", - "metaField": "meta", - "granularity": "minutes" - } - } - }, - { - "name": "iterateUntilDocumentOrError", - "object": "changeStream0", - "expectResult": { - "operationType": "create", - "nsType": "timeseries" - } - } - ] - }, { "description": "nsType is present when creating views", "operations": [ From 575d75f4d3c690bb4b5562e7bd896e5547548f96 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Tue, 5 May 2026 13:41:10 -0400 Subject: [PATCH 6/6] =?UTF-8?q?PYTHON-5813=20-=20Skip=20QE=20prefixPreview?= =?UTF-8?q?=20and=20suffixPreview=20tests=20on=20server=E2=80=A6=20(#2792)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/asynchronous/test_encryption.py | 1 + .../spec/unified/QE-Text-cleanupStructuredEncryptionData.json | 1 + .../spec/unified/QE-Text-compactStructuredEncryptionData.json | 1 + .../spec/unified/QE-Text-prefixPreview.json | 1 + .../spec/unified/QE-Text-substringPreview.json | 2 +- .../spec/unified/QE-Text-suffixPreview.json | 1 + test/test_encryption.py | 1 + 7 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test/asynchronous/test_encryption.py b/test/asynchronous/test_encryption.py index 9650f7043..1503f54c7 100644 --- a/test/asynchronous/test_encryption.py +++ b/test/asynchronous/test_encryption.py @@ -3326,6 +3326,7 @@ class TestAutomaticDecryptionKeys(AsyncEncryptionIntegrationTest): class TestExplicitTextEncryptionProse(AsyncEncryptionIntegrationTest): @async_client_context.require_no_standalone @async_client_context.require_version_min(8, 2, -1) + @async_client_context.require_version_max(8, 99, 99) @async_client_context.require_libmongocrypt_min(1, 15, 1) @async_client_context.require_pymongocrypt_min(1, 16, 0) async def asyncSetUp(self): diff --git a/test/client-side-encryption/spec/unified/QE-Text-cleanupStructuredEncryptionData.json b/test/client-side-encryption/spec/unified/QE-Text-cleanupStructuredEncryptionData.json index 24f33ab3e..fd74573ea 100644 --- a/test/client-side-encryption/spec/unified/QE-Text-cleanupStructuredEncryptionData.json +++ b/test/client-side-encryption/spec/unified/QE-Text-cleanupStructuredEncryptionData.json @@ -4,6 +4,7 @@ "runOnRequirements": [ { "minServerVersion": "8.2.0", + "maxServerVersion": "8.99.99", "topologies": [ "replicaset", "sharded", diff --git a/test/client-side-encryption/spec/unified/QE-Text-compactStructuredEncryptionData.json b/test/client-side-encryption/spec/unified/QE-Text-compactStructuredEncryptionData.json index c7abfe2d4..a89ab96fc 100644 --- a/test/client-side-encryption/spec/unified/QE-Text-compactStructuredEncryptionData.json +++ b/test/client-side-encryption/spec/unified/QE-Text-compactStructuredEncryptionData.json @@ -4,6 +4,7 @@ "runOnRequirements": [ { "minServerVersion": "8.2.0", + "maxServerVersion": "8.99.99", "topologies": [ "replicaset", "sharded", diff --git a/test/client-side-encryption/spec/unified/QE-Text-prefixPreview.json b/test/client-side-encryption/spec/unified/QE-Text-prefixPreview.json index 727938574..c193608e8 100644 --- a/test/client-side-encryption/spec/unified/QE-Text-prefixPreview.json +++ b/test/client-side-encryption/spec/unified/QE-Text-prefixPreview.json @@ -4,6 +4,7 @@ "runOnRequirements": [ { "minServerVersion": "8.2.0", + "maxServerVersion": "8.99.99", "topologies": [ "replicaset", "sharded", diff --git a/test/client-side-encryption/spec/unified/QE-Text-substringPreview.json b/test/client-side-encryption/spec/unified/QE-Text-substringPreview.json index 6a8f133ea..7787194fc 100644 --- a/test/client-side-encryption/spec/unified/QE-Text-substringPreview.json +++ b/test/client-side-encryption/spec/unified/QE-Text-substringPreview.json @@ -126,7 +126,7 @@ ], "tests": [ { - "description": "Insert QE suffixPreview", + "description": "Insert QE substringPreview", "operations": [ { "name": "insertOne", diff --git a/test/client-side-encryption/spec/unified/QE-Text-suffixPreview.json b/test/client-side-encryption/spec/unified/QE-Text-suffixPreview.json index deec5e63b..2de5cde4a 100644 --- a/test/client-side-encryption/spec/unified/QE-Text-suffixPreview.json +++ b/test/client-side-encryption/spec/unified/QE-Text-suffixPreview.json @@ -4,6 +4,7 @@ "runOnRequirements": [ { "minServerVersion": "8.2.0", + "maxServerVersion": "8.99.99", "topologies": [ "replicaset", "sharded", diff --git a/test/test_encryption.py b/test/test_encryption.py index af9f2e3df..099336227 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -3308,6 +3308,7 @@ class TestAutomaticDecryptionKeys(EncryptionIntegrationTest): class TestExplicitTextEncryptionProse(EncryptionIntegrationTest): @client_context.require_no_standalone @client_context.require_version_min(8, 2, -1) + @client_context.require_version_max(8, 99, 99) @client_context.require_libmongocrypt_min(1, 15, 1) @client_context.require_pymongocrypt_min(1, 16, 0) def setUp(self):