PYTHON-5782 Coverage increase for message.py#2772
Open
aclark4life wants to merge 9 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a new unit test module to increase coverage of pymongo/message.py by exercising message-building utilities and related pure-Python helper functions without requiring a live MongoDB server.
Changes:
- Adds
test/test_message.pywith unit tests for message helpers (read preference wrapping, command generation, write-result conversion). - Adds tests covering OP_MSG / OP_QUERY / OP_GET_MORE message construction in both compressed and uncompressed paths.
- Adds tests for error conversion and document-too-large error formatting.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
a6c8f8e to
a8d9f92
Compare
4baf2a6 to
7b31987
Compare
message.py
message.pymessage.py
message.pymessage.py
message.pymessage.py
Comment on lines
+28
to
+44
| from pymongo.compression_support import ZlibContext | ||
| from pymongo.errors import DocumentTooLarge, OperationFailure | ||
| from pymongo.message import ( | ||
| _compress, | ||
| _convert_client_bulk_exception, | ||
| _convert_exception, | ||
| _convert_write_result, | ||
| _gen_find_command, | ||
| _gen_get_more_command, | ||
| _get_more_compressed, | ||
| _get_more_uncompressed, | ||
| _maybe_add_read_preference, | ||
| _op_msg, | ||
| _query_compressed, | ||
| _query_uncompressed, | ||
| _raise_document_too_large, | ||
| ) |
98ecc43 to
3ab7aa5
Compare
- Replace _MockCtx with real ZlibContext(-1) to satisfy the SnappyContext | ZlibContext | ZstdContext union type - Annotate docs list as list to satisfy the Mapping invariance check - Add # type: ignore[arg-type] on _MockConn call sites for _gen_get_more_command (mocking AsyncConnection | Connection fully would require a much heavier stub)
Comment on lines
+109
to
+114
| def test_update_with_upserted_id(self): | ||
| cmd = {"updates": [{"q": {}, "u": {"_id": 42}}]} | ||
| result = _convert_write_result("update", cmd, {"n": 1, "upserted": 42}) | ||
| self.assertIn("upserted", result) | ||
| self.assertEqual(result["upserted"][0]["_id"], 42) | ||
|
|
Comment on lines
+143
to
+147
| class TestOpMsg(unittest.TestCase): | ||
| def test_max_doc_size_zero_without_docs(self): | ||
| max_doc_size = _op_msg(0, {"ping": 1}, "testdb", None, _OPTS)[3] | ||
| self.assertEqual(max_doc_size, 0) | ||
|
|
Address Copilot feedback: add tests for legacy upsert _id fallback in _convert_write_result and for the zlib-compressed _op_msg path.
Comment on lines
+192
to
+197
| def test_op_msg_compressed_zlib_header(self): | ||
| # Verify the compressed path is taken and produces a valid OP_COMPRESSED frame. | ||
| # Header layout (little-endian): [msgLen(4), reqId(4), responseTo(4), opCode(4), | ||
| # originalOpcode(4), uncompressedSize(4), compressorId(1)] | ||
| ctx = ZlibContext(6) | ||
| _, msg, _, _ = _op_msg(0, {"ping": 1}, "testdb", None, _OPTS, ctx=ctx) |
Guard zlib compression test with _have_zlib() skip condition.
Contributor
Author
|
Test failures flaky: |
NoahStapp
requested changes
Jun 10, 2026
| pref = SecondaryPreferred(tag_sets=[{"dc": "east"}]) | ||
| spec: dict = {"find": "col"} | ||
| result = _maybe_add_read_preference(spec, pref) | ||
| self.assertIn("$readPreference", result) |
Contributor
There was a problem hiding this comment.
This should make the same assertions as test_secondary_adds_read_preference for consistency.
| self.assertEqual(result["upserted"][0]["_id"], 42) | ||
|
|
||
| def test_update_legacy_upsert_id_from_update_doc(self): | ||
| # Pre-2.6 servers omit "upserted"; _id is extracted from the update doc (takes |
Contributor
There was a problem hiding this comment.
We don't support servers <4.2, so no need to test them. Any code that still makes a distinction should be removed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PYTHON-5782
Changes in this PR
Adds
test/test_message.pywith unit tests forpymongo/message.py.Tests cover:
Result / error conversion
_convert_exception()— converts anExceptioninto anerrmsg/errtypefailure document for event publishing_convert_client_bulk_exception()— same as above but also captures the errorcode, used by the client-level bulk write API_convert_write_result()— converts a legacy GLE (Get Last Error) write result into write-command format, handling insert/update/delete/upsert, wtimeout, and errInfo branches_raise_document_too_large()— raisesDocumentTooLargewith a size-aware message for inserts or a generic message for other operationsWire-format message construction
_op_msg()— builds an OP_MSG wire message, injecting$dband$readPreference, and temporarily popping document-sequence fields before encodingCommand builders
_gen_find_command()— builds afindcommand document from a query spec, applying projections, skip/limit, batch size, read concern, collation, and cursor options_gen_get_more_command()— builds agetMorecommand document, conditionally including batch size,maxTimeMS, andcomment(gated on wire version ≥ 9)Read preference
_maybe_add_read_preference()— injects$readPreferenceinto a query spec for non-primary modes, skipping plainsecondaryPreferredwhen no tags or maxStalenessSeconds are setTest Plan
Added unit tests using a real
ZlibContextfor compression paths and aMagicMockconnection for_gen_get_more_command. Focuses on the pure-Python code paths without requiring a live MongoDB server.Checklist
Checklist for Author
Checklist for Reviewer