1818
1919from bson import json_util
2020from pymongo .errors import OperationFailure
21- from pymongo .logger import _DEFAULT_DOCUMENT_LENGTH
21+ from pymongo .logger import _DEFAULT_DOCUMENT_LENGTH , _CommandStatusMessage
2222from test import unittest
2323from test .asynchronous import AsyncIntegrationTest , async_client_context
2424
2727
2828# https://github.com/mongodb/specifications/tree/master/source/command-logging-and-monitoring/tests#prose-tests
2929class TestLogger (AsyncIntegrationTest ):
30+ def _get_command_log (self , records , command_name , status ):
31+ # PyPy's GC is non-deterministic, so cleanup commands from earlier tests can pollute the logs,
32+ # filter for the specific command and status we want
33+ for record in records :
34+ log = json_util .loads (record .getMessage ())
35+ if log .get ("commandName" ) == command_name and log .get ("message" ) == status :
36+ return log
37+ self .fail (f"no { status !r} log found for command { command_name !r} " )
38+
3039 async def test_default_truncation_limit (self ):
3140 docs = [{"x" : "y" } for _ in range (100 )]
3241 db = self .db
@@ -36,15 +45,21 @@ async def test_default_truncation_limit(self):
3645 with self .assertLogs ("pymongo.command" , level = "DEBUG" ) as cm :
3746 await db .test .insert_many (docs )
3847
39- cmd_started_log = json_util .loads (cm .records [0 ].getMessage ())
48+ cmd_started_log = self ._get_command_log (
49+ cm .records , "insert" , _CommandStatusMessage .STARTED
50+ )
4051 self .assertEqual (len (cmd_started_log ["command" ]), _DEFAULT_DOCUMENT_LENGTH + 3 )
4152
42- cmd_succeeded_log = json_util .loads (cm .records [1 ].getMessage ())
53+ cmd_succeeded_log = self ._get_command_log (
54+ cm .records , "insert" , _CommandStatusMessage .SUCCEEDED
55+ )
4356 self .assertLessEqual (len (cmd_succeeded_log ["reply" ]), _DEFAULT_DOCUMENT_LENGTH + 3 )
4457
4558 with self .assertLogs ("pymongo.command" , level = "DEBUG" ) as cm :
4659 await db .test .find ({}).to_list ()
47- cmd_succeeded_log = json_util .loads (cm .records [1 ].getMessage ())
60+ cmd_succeeded_log = self ._get_command_log (
61+ cm .records , "find" , _CommandStatusMessage .SUCCEEDED
62+ )
4863 self .assertEqual (len (cmd_succeeded_log ["reply" ]), _DEFAULT_DOCUMENT_LENGTH + 3 )
4964
5065 async def test_configured_truncation_limit (self ):
@@ -54,14 +69,20 @@ async def test_configured_truncation_limit(self):
5469 with self .assertLogs ("pymongo.command" , level = "DEBUG" ) as cm :
5570 await db .command (cmd )
5671
57- cmd_started_log = json_util .loads (cm .records [0 ].getMessage ())
72+ cmd_started_log = self ._get_command_log (
73+ cm .records , "hello" , _CommandStatusMessage .STARTED
74+ )
5875 self .assertEqual (len (cmd_started_log ["command" ]), 5 + 3 )
5976
60- cmd_succeeded_log = json_util .loads (cm .records [1 ].getMessage ())
77+ cmd_succeeded_log = self ._get_command_log (
78+ cm .records , "hello" , _CommandStatusMessage .SUCCEEDED
79+ )
6180 self .assertLessEqual (len (cmd_succeeded_log ["reply" ]), 5 + 3 )
6281 with self .assertRaises (OperationFailure ):
6382 await db .command ({"notARealCommand" : True })
64- cmd_failed_log = json_util .loads (cm .records [- 1 ].getMessage ())
83+ cmd_failed_log = self ._get_command_log (
84+ cm .records , "notARealCommand" , _CommandStatusMessage .FAILED
85+ )
6586 self .assertEqual (len (cmd_failed_log ["failure" ]), 5 + 3 )
6687
6788 async def test_truncation_multi_byte_codepoints (self ):
@@ -77,7 +98,9 @@ async def test_truncation_multi_byte_codepoints(self):
7798 with patch .dict ("os.environ" , {"MONGOB_LOG_MAX_DOCUMENT_LENGTH" : length }):
7899 with self .assertLogs ("pymongo.command" , level = "DEBUG" ) as cm :
79100 await self .db .test .insert_one ({"x" : multi_byte_char_str })
80- cmd_started_log = json_util .loads (cm .records [0 ].getMessage ())["command" ]
101+ cmd_started_log = self ._get_command_log (
102+ cm .records , "insert" , _CommandStatusMessage .STARTED
103+ )["command" ]
81104
82105 cmd_started_log = cmd_started_log [:- 3 ]
83106 last_3_bytes = cmd_started_log .encode ()[- 3 :].decode ()
0 commit comments