|  | 
|  | 1 | +# Copyright 2024-present MongoDB, Inc. | 
|  | 2 | +# | 
|  | 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | +# you may not use this file except in compliance with the License. | 
|  | 5 | +# You may obtain a copy of the License at | 
|  | 6 | +# | 
|  | 7 | +# http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | +# | 
|  | 9 | +# Unless required by applicable law or agreed to in writing, software | 
|  | 10 | +# distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | +# See the License for the specific language governing permissions and | 
|  | 13 | +# limitations under the License. | 
|  | 14 | + | 
|  | 15 | +from __future__ import annotations | 
|  | 16 | + | 
|  | 17 | +from test import PyMongoTestCase | 
|  | 18 | + | 
|  | 19 | +import pytest | 
|  | 20 | + | 
|  | 21 | +from pymongo import InsertOne | 
|  | 22 | + | 
|  | 23 | +try: | 
|  | 24 | +    from mockupdb import MockupDB, OpMsg, go, going | 
|  | 25 | + | 
|  | 26 | +    _HAVE_MOCKUPDB = True | 
|  | 27 | +except ImportError: | 
|  | 28 | +    _HAVE_MOCKUPDB = False | 
|  | 29 | + | 
|  | 30 | + | 
|  | 31 | +from bson.objectid import ObjectId | 
|  | 32 | + | 
|  | 33 | +pytestmark = pytest.mark.mockupdb | 
|  | 34 | + | 
|  | 35 | + | 
|  | 36 | +# https://github.com/mongodb/specifications/blob/master/source/crud/tests/README.md#16-generated-document-identifiers-are-the-first-field-in-their-document | 
|  | 37 | +class TestIdOrdering(PyMongoTestCase): | 
|  | 38 | +    def test_16_generated_document_ids_are_first_field(self): | 
|  | 39 | +        server = MockupDB() | 
|  | 40 | +        server.autoresponds( | 
|  | 41 | +            "hello", | 
|  | 42 | +            isWritablePrimary=True, | 
|  | 43 | +            msg="isdbgrid", | 
|  | 44 | +            minWireVersion=0, | 
|  | 45 | +            maxWireVersion=25, | 
|  | 46 | +            helloOk=True, | 
|  | 47 | +            serviceId=ObjectId(), | 
|  | 48 | +        ) | 
|  | 49 | +        server.run() | 
|  | 50 | +        self.addCleanup(server.stop) | 
|  | 51 | + | 
|  | 52 | +        # We also verify that the original document contains an _id field after each insert | 
|  | 53 | +        document = {"x": 1} | 
|  | 54 | + | 
|  | 55 | +        client = self.simple_client(server.uri, loadBalanced=True) | 
|  | 56 | +        collection = client.db.coll | 
|  | 57 | +        with going(collection.insert_one, document): | 
|  | 58 | +            request = server.receives() | 
|  | 59 | +            self.assertEqual("_id", next(iter(request["documents"][0]))) | 
|  | 60 | +            request.reply({"ok": 1}) | 
|  | 61 | +        self.assertIn("_id", document) | 
|  | 62 | + | 
|  | 63 | +        document = {"x1": 1} | 
|  | 64 | + | 
|  | 65 | +        with going(collection.bulk_write, [InsertOne(document)]): | 
|  | 66 | +            request = server.receives() | 
|  | 67 | +            self.assertEqual("_id", next(iter(request["documents"][0]))) | 
|  | 68 | +            request.reply({"ok": 1}) | 
|  | 69 | +        self.assertIn("_id", document) | 
|  | 70 | + | 
|  | 71 | +        document = {"x2": 1} | 
|  | 72 | +        with going(client.bulk_write, [InsertOne(namespace="db.coll", document=document)]): | 
|  | 73 | +            request = server.receives() | 
|  | 74 | +            self.assertEqual("_id", next(iter(request["ops"][0]["document"]))) | 
|  | 75 | +            request.reply({"ok": 1}) | 
|  | 76 | +        self.assertIn("_id", document) | 
|  | 77 | + | 
|  | 78 | +        # Re-ordering user-supplied _id fields is not required by the spec, but PyMongo does it for performance reasons | 
|  | 79 | +        with going(collection.insert_one, {"x": 1, "_id": 111}): | 
|  | 80 | +            request = server.receives() | 
|  | 81 | +            self.assertEqual("_id", next(iter(request["documents"][0]))) | 
|  | 82 | +            request.reply({"ok": 1}) | 
|  | 83 | + | 
|  | 84 | +        with going(collection.bulk_write, [InsertOne({"x1": 1, "_id": 1111})]): | 
|  | 85 | +            request = server.receives() | 
|  | 86 | +            self.assertEqual("_id", next(iter(request["documents"][0]))) | 
|  | 87 | +            request.reply({"ok": 1}) | 
|  | 88 | + | 
|  | 89 | +        with going( | 
|  | 90 | +            client.bulk_write, [InsertOne(namespace="db.coll", document={"x2": 1, "_id": 11111})] | 
|  | 91 | +        ): | 
|  | 92 | +            request = server.receives() | 
|  | 93 | +            self.assertEqual("_id", next(iter(request["ops"][0]["document"]))) | 
|  | 94 | +            request.reply({"ok": 1}) | 
0 commit comments