2424
2525from test import unittest
2626
27- from bson import CodecOptions
27+ from bson import CodecOptions , encode
2828from pymongo .compression_support import ZlibContext
2929from pymongo .errors import DocumentTooLarge , OperationFailure
3030from pymongo .message import (
3939 _maybe_add_read_preference ,
4040 _op_msg ,
4141 _query_compressed ,
42- _query_impl ,
4342 _query_uncompressed ,
4443 _raise_document_too_large ,
4544)
@@ -98,6 +97,11 @@ def test_client_bulk_exception_includes_code(self):
9897
9998
10099class TestConvertWriteResult (unittest .TestCase ):
100+ """Tests for _convert_write_result.
101+
102+ In the update command spec, `q` is the query/filter and `u` is the update document.
103+ """
104+
101105 def test_insert_basic (self ):
102106 cmd = {"documents" : [{"_id" : 1 }, {"_id" : 2 }]}
103107 result = _convert_write_result ("insert" , cmd , {"n" : 0 })
@@ -116,12 +120,12 @@ def test_update_with_upserted_id(self):
116120 self .assertIn ("upserted" , result )
117121 self .assertEqual (result ["upserted" ][0 ]["_id" ], 42 )
118122
119- def test_update_implicit_upsert_from_updatedExisting_false (self ):
120- cmd = { "updates" : [{ "q" : { "_id" : 99 }, "u" : { "$set" : { "x" : 1 }}}]}
121- result = _convert_write_result (
122- "update" , cmd , { "n " : 1 , "updatedExisting " : False , "upserted " : None }
123- )
124- self .assertIn ( "upserted" , result )
123+ def test_update_upsert_id_precedence (self ):
124+ # When _id is in both the update document and the query spec,
125+ # the update document's _id wins.
126+ cmd = { "updates" : [{ "q" : { "_id " : 99 } , "u " : { "_id " : 42 }}] }
127+ result = _convert_write_result ( "update" , cmd , { "n" : 1 , "updatedExisting" : False } )
128+ self .assertEqual ( result [ "upserted" ][ 0 ][ "_id" ], 42 )
125129
126130 def test_update_upsert_no_upserted_id_from_query (self ):
127131 cmd = {"updates" : [{"q" : {"_id" : 77 }, "u" : {"$set" : {"x" : 1 }}}]}
@@ -159,25 +163,26 @@ def test_write_error_with_err_info(self):
159163
160164class TestCompress (unittest .TestCase ):
161165 def test_compressed_message_has_op_compressed_header (self ):
162- _request_id , msg = _compress (2013 , b"hello world" , _ZLIB_CTX )
166+ msg = _compress (2013 , b"hello world" , _ZLIB_CTX )[ 1 ]
163167 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
164168 self .assertEqual (op_code , 2012 ) # OP_COMPRESSED
165169
166170
167171class TestOpMsg (unittest .TestCase ):
168172 def test_uncompressed_op_code (self ):
169- _ , msg , _ , _ = _op_msg (0 , {"ping" : 1 }, "testdb" , None , _OPTS )
173+ msg = _op_msg (0 , {"ping" : 1 }, "testdb" , None , _OPTS )[ 1 ]
170174 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
171175 self .assertEqual (op_code , 2013 ) # OP_MSG
172176
173177 def test_max_doc_size_zero_without_docs (self ):
174- _ , _ , _ , max_doc_size = _op_msg (0 , {"ping" : 1 }, "testdb" , None , _OPTS )
178+ max_doc_size = _op_msg (0 , {"ping" : 1 }, "testdb" , None , _OPTS )[ 3 ]
175179 self .assertEqual (max_doc_size , 0 )
176180
177- def test_max_doc_size_nonzero_with_docs (self ):
178- cmd : dict = {"insert" : "col" , "documents" : [{"_id" : 1 , "x" : 2 }, {"_id" : 3 , "x" : 4 }]}
179- _ , _ , _ , max_doc_size = _op_msg (0 , cmd , "testdb" , None , _OPTS )
180- self .assertGreater (max_doc_size , 0 )
181+ def test_max_doc_size_matches_largest_encoded_doc (self ):
182+ docs = [{"_id" : 1 , "x" : 2 }, {"_id" : 3 , "x" : 4 }]
183+ cmd : dict = {"insert" : "col" , "documents" : docs }
184+ max_doc_size = _op_msg (0 , cmd , "testdb" , None , _OPTS )[3 ]
185+ self .assertEqual (max_doc_size , max (len (encode (d )) for d in docs ))
181186
182187 def test_read_preference_added_for_non_primary (self ):
183188 cmd : dict = {"find" : "col" }
@@ -190,7 +195,7 @@ def test_read_preference_skipped_if_already_present(self):
190195 self .assertEqual (cmd ["$readPreference" ]["mode" ], "nearest" )
191196
192197 def test_with_compression_context (self ):
193- _ , msg , _ , _ = _op_msg (0 , {"ping" : 1 }, "testdb" , None , _OPTS , _ZLIB_CTX )
198+ msg = _op_msg (0 , {"ping" : 1 }, "testdb" , None , _OPTS , _ZLIB_CTX )[ 1 ]
194199 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
195200 self .assertEqual (op_code , 2012 ) # OP_COMPRESSED
196201
@@ -202,30 +207,26 @@ def test_command_with_documents_field_is_restored(self):
202207 self .assertEqual (cmd ["documents" ], docs )
203208
204209
205- class TestQuery (unittest .TestCase ):
206- def test_basic (self ):
207- _ , max_bson_size = _query_impl (0 , "db.col" , 0 , 0 , {"x" : 1 }, None , _OPTS )
208- self .assertGreater (max_bson_size , 0 )
210+ class TestLegacyWireOps (unittest .TestCase ):
211+ """Tests for pre-OP_MSG wire ops (OP_QUERY and OP_GET_MORE), compressed and uncompressed."""
209212
210- def test_uncompressed_op_code (self ):
211- _rid , msg , _mbs = _query_uncompressed (0 , "db.col" , 0 , 0 , {}, None , _OPTS )
213+ def test_query_uncompressed_op_code (self ):
214+ msg = _query_uncompressed (0 , "db.col" , 0 , 0 , {}, None , _OPTS )[ 1 ]
212215 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
213216 self .assertEqual (op_code , 2004 ) # OP_QUERY
214217
215- def test_compressed_op_code (self ):
216- _rid , msg , _mbs = _query_compressed (0 , "db.col" , 0 , 0 , {}, None , _OPTS , _ZLIB_CTX )
218+ def test_query_compressed_op_code (self ):
219+ msg = _query_compressed (0 , "db.col" , 0 , 0 , {}, None , _OPTS , _ZLIB_CTX )[ 1 ]
217220 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
218221 self .assertEqual (op_code , 2012 ) # OP_COMPRESSED
219222
220-
221- class TestGetMore (unittest .TestCase ):
222- def test_uncompressed_op_code (self ):
223- _rid , msg = _get_more_uncompressed ("db.col" , 0 , 0 )
223+ def test_get_more_uncompressed_op_code (self ):
224+ msg = _get_more_uncompressed ("db.col" , 0 , 0 )[1 ]
224225 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
225226 self .assertEqual (op_code , 2005 ) # OP_GET_MORE
226227
227- def test_compressed_op_code (self ):
228- _rid , msg = _get_more_compressed ("db.col" , 0 , 0 , _ZLIB_CTX )
228+ def test_get_more_compressed_op_code (self ):
229+ msg = _get_more_compressed ("db.col" , 0 , 0 , _ZLIB_CTX )[ 1 ]
229230 op_code = struct .unpack ("<i" , msg [12 :16 ])[0 ]
230231 self .assertEqual (op_code , 2012 ) # OP_COMPRESSED
231232
@@ -252,7 +253,7 @@ def test_basic(self):
252253
253254 def test_with_projection (self ):
254255 cmd = _gen_find_command ("col" , {}, {"x" : 1 }, 0 , 0 , None , None , ReadConcern ())
255- self .assertIn ( "projection" , cmd )
256+ self .assertEqual ( cmd [ "projection" ], { "x" : 1 } )
256257
257258 def test_with_skip (self ):
258259 cmd = _gen_find_command ("col" , {}, None , 5 , 0 , None , None , ReadConcern ())
@@ -279,7 +280,7 @@ def test_batch_size_not_adjusted_when_different(self):
279280
280281 def test_read_concern_level_included (self ):
281282 cmd = _gen_find_command ("col" , {}, None , 0 , 0 , None , None , ReadConcern ("majority" ))
282- self .assertIn ( "readConcern" , cmd )
283+ self .assertEqual ( cmd [ "readConcern" ], { "level" : "majority" } )
283284
284285 def test_query_with_dollar_query_modifier (self ):
285286 spec = {"$query" : {"x" : 1 }, "$orderby" : {"x" : 1 }}
0 commit comments