From a8a366f0331c482a4607dea0538f3f0b640894cd Mon Sep 17 00:00:00 2001 From: Jib Date: Thu, 31 Aug 2023 11:30:10 -0400 Subject: [PATCH 01/15] initial commit adding in databaseName key --- pymongo/message.py | 2 ++ pymongo/monitoring.py | 71 ++++++++++++++++++++++++++++++++++------- pymongo/network.py | 11 +++++-- pymongo/server.py | 6 ++-- test/test_monitoring.py | 15 ++++++--- 5 files changed, 85 insertions(+), 20 deletions(-) diff --git a/pymongo/message.py b/pymongo/message.py index 5a4b1753f9..ec5770929d 100644 --- a/pymongo/message.py +++ b/pymongo/message.py @@ -1100,6 +1100,7 @@ def _succeed(self, request_id: int, reply: _DocumentOut, duration: timedelta) -> self.conn.address, self.op_id, self.conn.service_id, + database_name=self.db_name, ) def _fail(self, request_id: int, failure: _DocumentOut, duration: timedelta) -> None: @@ -1112,6 +1113,7 @@ def _fail(self, request_id: int, failure: _DocumentOut, duration: timedelta) -> self.conn.address, self.op_id, self.conn.service_id, + database_name=self.db_name, ) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 73e15821d3..780b24250d 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -561,7 +561,7 @@ def _is_speculative_authenticate(command_name: str, doc: Mapping[str, Any]) -> b class _CommandEvent: """Base class for command events.""" - __slots__ = ("__cmd_name", "__rqst_id", "__conn_id", "__op_id", "__service_id") + __slots__ = ("__cmd_name", "__rqst_id", "__conn_id", "__op_id", "__service_id", "__db") def __init__( self, @@ -570,12 +570,14 @@ def __init__( connection_id: _Address, operation_id: Optional[int], service_id: Optional[ObjectId] = None, + database_name: Optional[str] = None, ) -> None: self.__cmd_name = command_name self.__rqst_id = request_id self.__conn_id = connection_id self.__op_id = operation_id self.__service_id = service_id + self.__db = database_name @property def command_name(self) -> str: @@ -605,6 +607,14 @@ def operation_id(self) -> Optional[int]: """An id for this series of events or None.""" return self.__op_id + @property + def database_name(self) -> Optional[str]: + """The database_name this command was sent to, or ``None``. + + .. versionadded:: 4.6 + """ + return self.__db + class CommandStartedEvent(_CommandEvent): """Event published when a command starts. @@ -619,7 +629,7 @@ class CommandStartedEvent(_CommandEvent): - `service_id`: The service_id this command was sent to, or ``None``. """ - __slots__ = ("__cmd", "__db") + __slots__ = "__cmd" def __init__( self, @@ -635,14 +645,18 @@ def __init__( # Command name must be first key. command_name = next(iter(command)) super().__init__( - command_name, request_id, connection_id, operation_id, service_id=service_id + command_name, + request_id, + connection_id, + operation_id, + service_id=service_id, + database_name=database_name, ) cmd_name = command_name.lower() if cmd_name in _SENSITIVE_COMMANDS or _is_speculative_authenticate(cmd_name, command): self.__cmd: _DocumentOut = {} else: self.__cmd = command - self.__db = database_name @property def command(self) -> _DocumentOut: @@ -652,7 +666,8 @@ def command(self) -> _DocumentOut: @property def database_name(self) -> str: """The name of the database this command was run against.""" - return self.__db + assert super().database_name + return super().database_name def __repr__(self) -> str: return ("<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}>").format( @@ -677,6 +692,7 @@ class CommandSucceededEvent(_CommandEvent): was sent to. - `operation_id`: An optional identifier for a series of related events. - `service_id`: The service_id this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``None``. """ __slots__ = ("__duration_micros", "__reply") @@ -690,9 +706,15 @@ def __init__( connection_id: _Address, operation_id: Optional[int], service_id: Optional[ObjectId] = None, + database_name: Optional[str] = None, ) -> None: super().__init__( - command_name, request_id, connection_id, operation_id, service_id=service_id + command_name, + request_id, + connection_id, + operation_id, + service_id=service_id, + database_name=database_name, ) self.__duration_micros = _to_micros(duration) cmd_name = command_name.lower() @@ -713,10 +735,11 @@ def reply(self) -> _DocumentOut: def __repr__(self) -> str: return ( - "<{} {} command: {!r}, operation_id: {}, duration_micros: {}, service_id: {}>" + "<{} {} db: {!r}, command: {!r}, operation_id: {}, duration_micros: {}, service_id: {}>" ).format( self.__class__.__name__, self.connection_id, + self.database_name, self.command_name, self.operation_id, self.duration_micros, @@ -736,6 +759,7 @@ class CommandFailedEvent(_CommandEvent): was sent to. - `operation_id`: An optional identifier for a series of related events. - `service_id`: The service_id this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``None``. """ __slots__ = ("__duration_micros", "__failure") @@ -749,9 +773,15 @@ def __init__( connection_id: _Address, operation_id: Optional[int], service_id: Optional[ObjectId] = None, + database_name: Optional[str] = None, ) -> None: super().__init__( - command_name, request_id, connection_id, operation_id, service_id=service_id + command_name, + request_id, + connection_id, + operation_id, + service_id=service_id, + database_name=database_name, ) self.__duration_micros = _to_micros(duration) self.__failure = failure @@ -768,11 +798,12 @@ def failure(self) -> _DocumentOut: def __repr__(self) -> str: return ( - "<{} {} command: {!r}, operation_id: {}, duration_micros: {}, " + "<{} {} db: {!r}, command: {!r}, operation_id: {}, duration_micros: {}, " "failure: {!r}, service_id: {}>" ).format( self.__class__.__name__, self.connection_id, + self.database_name, self.command_name, self.operation_id, self.duration_micros, @@ -1491,6 +1522,7 @@ def publish_command_success( op_id: Optional[int] = None, service_id: Optional[ObjectId] = None, speculative_hello: bool = False, + database_name: Optional[str] = None, ) -> None: """Publish a CommandSucceededEvent to all command listeners. @@ -1504,6 +1536,7 @@ def publish_command_success( - `op_id`: The (optional) operation id for this operation. - `service_id`: The service_id this command was sent to, or ``None``. - `speculative_hello`: Was the command sent with speculative auth? + - `database_name`: The database this command was sent to, or ``None``. """ if op_id is None: op_id = request_id @@ -1512,7 +1545,14 @@ def publish_command_success( # speculativeAuthenticate. reply = {} event = CommandSucceededEvent( - duration, reply, command_name, request_id, connection_id, op_id, service_id + duration, + reply, + command_name, + request_id, + connection_id, + op_id, + service_id, + database_name=database_name, ) for subscriber in self.__command_listeners: try: @@ -1529,6 +1569,7 @@ def publish_command_failure( connection_id: _Address, op_id: Optional[int] = None, service_id: Optional[ObjectId] = None, + database_name: Optional[str] = None, ) -> None: """Publish a CommandFailedEvent to all command listeners. @@ -1542,11 +1583,19 @@ def publish_command_failure( command was sent to. - `op_id`: The (optional) operation id for this operation. - `service_id`: The service_id this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``None``. """ if op_id is None: op_id = request_id event = CommandFailedEvent( - duration, failure, command_name, request_id, connection_id, op_id, service_id=service_id + duration, + failure, + command_name, + request_id, + connection_id, + op_id, + service_id=service_id, + database_name=database_name, ) for subscriber in self.__command_listeners: try: diff --git a/pymongo/network.py b/pymongo/network.py index df540f1a3f..5ad1097a6d 100644 --- a/pymongo/network.py +++ b/pymongo/network.py @@ -167,7 +167,7 @@ def command( assert listeners is not None assert address is not None listeners.publish_command_start( - orig, dbname, request_id, address, service_id=conn.service_id + orig, dbname, request_id, address, service_id=conn.service_id, database_name=dbname ) start = datetime.datetime.now() @@ -204,7 +204,13 @@ def command( assert listeners is not None assert address is not None listeners.publish_command_failure( - duration, failure, name, request_id, address, service_id=conn.service_id + duration, + failure, + name, + request_id, + address, + service_id=conn.service_id, + database_name=dbname, ) raise if publish: @@ -219,6 +225,7 @@ def command( address, service_id=conn.service_id, speculative_hello=speculative_hello, + database_name=dbname, ) if client and client._encrypter and reply: diff --git a/pymongo/server.py b/pymongo/server.py index 2fe2443eec..62aa22ddb2 100644 --- a/pymongo/server.py +++ b/pymongo/server.py @@ -130,6 +130,7 @@ def run_operation( publish = listeners.enabled_for_commands if publish: start = datetime.now() + cmd, dbn = operation.as_command(conn) use_cmd = operation.use_command(conn) more_to_come = operation.conn_mgr and operation.conn_mgr.more_to_come @@ -140,10 +141,9 @@ def run_operation( request_id, data, max_doc_size = self._split_message(message) if publish: - cmd, dbn = operation.as_command(conn) assert listeners is not None listeners.publish_command_start( - cmd, dbn, request_id, conn.address, service_id=conn.service_id + cmd, dbn, request_id, conn.address, service_id=conn.service_id, database_name=dbn ) start = datetime.now() @@ -187,6 +187,7 @@ def run_operation( request_id, conn.address, service_id=conn.service_id, + database_name=dbn, ) raise @@ -212,6 +213,7 @@ def run_operation( request_id, conn.address, service_id=conn.service_id, + database_name=dbn, ) # Decrypt response. diff --git a/test/test_monitoring.py b/test/test_monitoring.py index 7aa3d67ebb..363a334139 100644 --- a/test/test_monitoring.py +++ b/test/test_monitoring.py @@ -1087,7 +1087,12 @@ def test_sensitive_commands(self): listeners.publish_command_start(cmd, "pymongo_test", 12345, self.client.address) # type: ignore[arg-type] delta = datetime.timedelta(milliseconds=100) listeners.publish_command_success( - delta, {"nonce": "e474f4561c5eb40b", "ok": 1.0}, "getnonce", 12345, self.client.address # type: ignore[arg-type] + delta, + {"nonce": "e474f4561c5eb40b", "ok": 1.0}, + "getnonce", + 12345, + self.client.address, + database_name="pymongo_test", # type: ignore[arg-type] ) started = self.listener.started_events[0] succeeded = self.listener.succeeded_events[0] @@ -1148,9 +1153,9 @@ def test_simple(self): class TestEventClasses(unittest.TestCase): def test_command_event_repr(self): - request_id, connection_id, operation_id = 1, ("localhost", 27017), 2 + request_id, connection_id, operation_id, db_name = 1, ("localhost", 27017), 2, "test" event = monitoring.CommandStartedEvent( - {"ping": 1}, "admin", request_id, connection_id, operation_id + {"ping": 1}, "admin", request_id, connection_id, operation_id, database_name=db_name ) self.assertEqual( repr(event), @@ -1159,7 +1164,7 @@ def test_command_event_repr(self): ) delta = datetime.timedelta(milliseconds=100) event = monitoring.CommandSucceededEvent( - delta, {"ok": 1}, "ping", request_id, connection_id, operation_id + delta, {"ok": 1}, "ping", request_id, connection_id, operation_id, database_name=db_name ) self.assertEqual( repr(event), @@ -1168,7 +1173,7 @@ def test_command_event_repr(self): "service_id: None>", ) event = monitoring.CommandFailedEvent( - delta, {"ok": 0}, "ping", request_id, connection_id, operation_id + delta, {"ok": 0}, "ping", request_id, connection_id, operation_id, database_name=db_name ) self.assertEqual( repr(event), From 318714b4458c9457812e6be68f14dda79ee4c9bc Mon Sep 17 00:00:00 2001 From: Jib Date: Thu, 31 Aug 2023 11:53:39 -0400 Subject: [PATCH 02/15] fixed mypy typechecks --- pymongo/monitoring.py | 5 +++-- pymongo/network.py | 2 +- pymongo/server.py | 2 +- test/test_monitoring.py | 6 +++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 780b24250d..468e03decb 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -666,8 +666,9 @@ def command(self) -> _DocumentOut: @property def database_name(self) -> str: """The name of the database this command was run against.""" - assert super().database_name - return super().database_name + db = super().database_name + assert db is not None + return db def __repr__(self) -> str: return ("<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}>").format( diff --git a/pymongo/network.py b/pymongo/network.py index 5ad1097a6d..7f694553f2 100644 --- a/pymongo/network.py +++ b/pymongo/network.py @@ -167,7 +167,7 @@ def command( assert listeners is not None assert address is not None listeners.publish_command_start( - orig, dbname, request_id, address, service_id=conn.service_id, database_name=dbname + orig, dbname, request_id, address, service_id=conn.service_id ) start = datetime.datetime.now() diff --git a/pymongo/server.py b/pymongo/server.py index 62aa22ddb2..a2bc68b87c 100644 --- a/pymongo/server.py +++ b/pymongo/server.py @@ -143,7 +143,7 @@ def run_operation( if publish: assert listeners is not None listeners.publish_command_start( - cmd, dbn, request_id, conn.address, service_id=conn.service_id, database_name=dbn + cmd, dbn, request_id, conn.address, service_id=conn.service_id ) start = datetime.now() diff --git a/test/test_monitoring.py b/test/test_monitoring.py index 363a334139..2285022466 100644 --- a/test/test_monitoring.py +++ b/test/test_monitoring.py @@ -1091,8 +1091,8 @@ def test_sensitive_commands(self): {"nonce": "e474f4561c5eb40b", "ok": 1.0}, "getnonce", 12345, - self.client.address, - database_name="pymongo_test", # type: ignore[arg-type] + self.client.address, # type: ignore[arg-type] + database_name="pymongo_test", ) started = self.listener.started_events[0] succeeded = self.listener.succeeded_events[0] @@ -1155,7 +1155,7 @@ class TestEventClasses(unittest.TestCase): def test_command_event_repr(self): request_id, connection_id, operation_id, db_name = 1, ("localhost", 27017), 2, "test" event = monitoring.CommandStartedEvent( - {"ping": 1}, "admin", request_id, connection_id, operation_id, database_name=db_name + {"ping": 1}, "admin", request_id, connection_id, operation_id ) self.assertEqual( repr(event), From bc2b3a8a0655debfacad7bdd90e3a291a64bdaf4 Mon Sep 17 00:00:00 2001 From: Jib Date: Thu, 31 Aug 2023 13:17:57 -0400 Subject: [PATCH 03/15] fixed failing test_monitoring tests --- test/test_monitoring.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_monitoring.py b/test/test_monitoring.py index 2285022466..8ccc844d32 100644 --- a/test/test_monitoring.py +++ b/test/test_monitoring.py @@ -1153,9 +1153,9 @@ def test_simple(self): class TestEventClasses(unittest.TestCase): def test_command_event_repr(self): - request_id, connection_id, operation_id, db_name = 1, ("localhost", 27017), 2, "test" + request_id, connection_id, operation_id, db_name = 1, ("localhost", 27017), 2, "admin" event = monitoring.CommandStartedEvent( - {"ping": 1}, "admin", request_id, connection_id, operation_id + {"ping": 1}, db_name, request_id, connection_id, operation_id ) self.assertEqual( repr(event), @@ -1168,7 +1168,7 @@ def test_command_event_repr(self): ) self.assertEqual( repr(event), - "", ) @@ -1177,7 +1177,7 @@ def test_command_event_repr(self): ) self.assertEqual( repr(event), - "", ) From 222775d59a28abf182b132a1344108eff1e4c035 Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 10:47:06 -0400 Subject: [PATCH 04/15] changed each unified test in test/command_monitoring to now check for databaseName on events (if commandStartedEvent did so as well) --- test/command_monitoring/bulkWrite.json | 6 +++-- test/command_monitoring/command.json | 3 ++- test/command_monitoring/deleteMany.json | 8 ++++--- test/command_monitoring/deleteOne.json | 6 +++-- test/command_monitoring/find.json | 24 ++++++++++++------- test/command_monitoring/insertMany.json | 6 +++-- test/command_monitoring/insertOne.json | 6 +++-- .../unacknowledgedBulkWrite.json | 3 ++- test/command_monitoring/updateMany.json | 6 +++-- test/command_monitoring/updateOne.json | 11 +++++---- test/unified_format.py | 15 ++++++++---- 11 files changed, 62 insertions(+), 32 deletions(-) diff --git a/test/command_monitoring/bulkWrite.json b/test/command_monitoring/bulkWrite.json index 49c728442e..0c065d2b32 100644 --- a/test/command_monitoring/bulkWrite.json +++ b/test/command_monitoring/bulkWrite.json @@ -106,7 +106,8 @@ "ok": 1, "n": 1 }, - "commandName": "insert" + "commandName": "insert", + "databaseName": "command-monitoring-tests" } }, { @@ -143,7 +144,8 @@ "ok": 1, "n": 1 }, - "commandName": "update" + "commandName": "update", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/command.json b/test/command_monitoring/command.json index c28af95fed..965c4c48d7 100644 --- a/test/command_monitoring/command.json +++ b/test/command_monitoring/command.json @@ -72,7 +72,8 @@ "reply": { "ok": 1 }, - "commandName": "ping" + "commandName": "ping", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/deleteMany.json b/test/command_monitoring/deleteMany.json index 78ebad1f98..9c8e8cecdf 100644 --- a/test/command_monitoring/deleteMany.json +++ b/test/command_monitoring/deleteMany.json @@ -93,7 +93,8 @@ "ok": 1, "n": 2 }, - "commandName": "delete" + "commandName": "delete", + "databaseName": "command-monitoring-tests" } } ] @@ -151,7 +152,8 @@ "$$type": "array" } }, - "commandName": "delete" + "commandName": "delete", + "databaseName": "command-monitoring-tests" } } ] @@ -159,4 +161,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/test/command_monitoring/deleteOne.json b/test/command_monitoring/deleteOne.json index 2420794fe5..64662e8c62 100644 --- a/test/command_monitoring/deleteOne.json +++ b/test/command_monitoring/deleteOne.json @@ -93,7 +93,8 @@ "ok": 1, "n": 1 }, - "commandName": "delete" + "commandName": "delete", + "databaseName": "command-monitoring-tests" } } ] @@ -151,7 +152,8 @@ "$$type": "array" } }, - "commandName": "delete" + "commandName": "delete", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/find.json b/test/command_monitoring/find.json index 4b5f45ae99..3febe01119 100644 --- a/test/command_monitoring/find.json +++ b/test/command_monitoring/find.json @@ -103,7 +103,8 @@ ] } }, - "commandName": "find" + "commandName": "find", + "databaseName": "command-monitoring-tests" } } ] @@ -198,7 +199,8 @@ ] } }, - "commandName": "find" + "commandName": "find", + "databaseName": "command-monitoring-tests" } } ] @@ -262,7 +264,8 @@ ] } }, - "commandName": "find" + "commandName": "find", + "databaseName": "command-monitoring-tests" } } ] @@ -338,7 +341,8 @@ ] } }, - "commandName": "find" + "commandName": "find", + "databaseName": "command-monitoring-tests" } }, { @@ -376,7 +380,8 @@ ] } }, - "commandName": "getMore" + "commandName": "getMore", + "databaseName": "command-monitoring-tests" } } ] @@ -464,7 +469,8 @@ ] } }, - "commandName": "find" + "commandName": "find", + "databaseName": "command-monitoring-tests" } }, { @@ -498,7 +504,8 @@ ] } }, - "commandName": "getMore" + "commandName": "getMore", + "databaseName": "command-monitoring-tests" } } ] @@ -539,7 +546,8 @@ }, { "commandFailedEvent": { - "commandName": "find" + "commandName": "find", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/insertMany.json b/test/command_monitoring/insertMany.json index a80a218c67..d2d0bd9355 100644 --- a/test/command_monitoring/insertMany.json +++ b/test/command_monitoring/insertMany.json @@ -82,7 +82,8 @@ "ok": 1, "n": 1 }, - "commandName": "insert" + "commandName": "insert", + "databaseName": "command-monitoring-tests" } } ] @@ -137,7 +138,8 @@ "$$type": "array" } }, - "commandName": "insert" + "commandName": "insert", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/insertOne.json b/test/command_monitoring/insertOne.json index 6ff732e41b..09885585f0 100644 --- a/test/command_monitoring/insertOne.json +++ b/test/command_monitoring/insertOne.json @@ -80,7 +80,8 @@ "ok": 1, "n": 1 }, - "commandName": "insert" + "commandName": "insert", + "databaseName": "command-monitoring-tests" } } ] @@ -133,7 +134,8 @@ "$$type": "array" } }, - "commandName": "insert" + "commandName": "insert", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/unacknowledgedBulkWrite.json b/test/command_monitoring/unacknowledgedBulkWrite.json index 4c16d6df11..3b577152f9 100644 --- a/test/command_monitoring/unacknowledgedBulkWrite.json +++ b/test/command_monitoring/unacknowledgedBulkWrite.json @@ -97,7 +97,8 @@ "$$exists": false } }, - "commandName": "insert" + "commandName": "insert", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/updateMany.json b/test/command_monitoring/updateMany.json index b15434226c..66b4a5a791 100644 --- a/test/command_monitoring/updateMany.json +++ b/test/command_monitoring/updateMany.json @@ -106,7 +106,8 @@ "ok": 1, "n": 2 }, - "commandName": "update" + "commandName": "update", + "databaseName": "command-monitoring-tests" } } ] @@ -177,7 +178,8 @@ "$$type": "array" } }, - "commandName": "update" + "commandName": "update", + "databaseName": "command-monitoring-tests" } } ] diff --git a/test/command_monitoring/updateOne.json b/test/command_monitoring/updateOne.json index a0ae99e88d..f418dbe401 100644 --- a/test/command_monitoring/updateOne.json +++ b/test/command_monitoring/updateOne.json @@ -108,7 +108,8 @@ "ok": 1, "n": 1 }, - "commandName": "update" + "commandName": "update", + "databaseName": "command-monitoring-tests" } } ] @@ -176,7 +177,8 @@ } ] }, - "commandName": "update" + "commandName": "update", + "databaseName": "command-monitoring-tests" } } ] @@ -249,7 +251,8 @@ "$$type": "array" } }, - "commandName": "update" + "commandName": "update", + "databaseName": "command-monitoring-tests" } } ] @@ -257,4 +260,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/test/unified_format.py b/test/unified_format.py index b66337416f..eee18b85db 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -134,14 +134,14 @@ # Build up a placeholder map. PLACEHOLDER_MAP = {} -for (provider_name, provider_data) in [ +for provider_name, provider_data in [ ("local", {"key": LOCAL_MASTER_KEY}), ("aws", AWS_CREDS), ("azure", AZURE_CREDS), ("gcp", GCP_CREDS), ("kmip", KMIP_CREDS), ]: - for (key, value) in provider_data.items(): + for key, value in provider_data.items(): placeholder = f"/clientEncryptionOpts/kmsProviders/{provider_name}/{key}" PLACEHOLDER_MAP[placeholder] = value @@ -156,6 +156,7 @@ def with_metaclass(meta, *bases): Vendored from six: https://github.com/benjaminp/six/blob/master/six.py """ + # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. @@ -746,6 +747,10 @@ def match_result(self, expectation, actual, in_recursive_call=False): self.test.assertEqual(expectation, actual) return None + def assertHasDatabaseName(self, spec, actual): + if database_name := spec.get("databaseName"): + self.test.assertEqual(database_name, actual.database_name) + def assertHasServiceId(self, spec, actual): if "hasServiceId" in spec: if spec.get("hasServiceId"): @@ -778,7 +783,6 @@ def match_event(self, event_type, expectation, actual): if name == "commandStartedEvent": self.test.assertIsInstance(actual, CommandStartedEvent) command = spec.get("command") - database_name = spec.get("databaseName") if command: if actual.command_name == "update": # TODO: remove this once PYTHON-1744 is done. @@ -787,18 +791,19 @@ def match_event(self, event_type, expectation, actual): update.setdefault("upsert", False) update.setdefault("multi", False) self.match_result(command, actual.command) - if database_name: - self.test.assertEqual(database_name, actual.database_name) + self.assertHasDatabaseName(spec, actual) self.assertHasServiceId(spec, actual) elif name == "commandSucceededEvent": self.test.assertIsInstance(actual, CommandSucceededEvent) reply = spec.get("reply") if reply: self.match_result(reply, actual.reply) + self.assertHasDatabaseName(spec, actual) self.assertHasServiceId(spec, actual) elif name == "commandFailedEvent": self.test.assertIsInstance(actual, CommandFailedEvent) self.assertHasServiceId(spec, actual) + self.assertHasDatabaseName(spec, actual) elif name == "poolCreatedEvent": self.test.assertIsInstance(actual, PoolCreatedEvent) elif name == "poolReadyEvent": From 0417072edba71115383ff730fc9b2402220df75e Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 11:24:50 -0400 Subject: [PATCH 05/15] walrus operator not supported in 3.7 --- test/unified_format.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unified_format.py b/test/unified_format.py index eee18b85db..3386d0770d 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -748,8 +748,8 @@ def match_result(self, expectation, actual, in_recursive_call=False): return None def assertHasDatabaseName(self, spec, actual): - if database_name := spec.get("databaseName"): - self.test.assertEqual(database_name, actual.database_name) + if spec.get("databaseName"): + self.test.assertEqual(spec.get("databaseName"), actual.database_name) def assertHasServiceId(self, spec, actual): if "hasServiceId" in spec: From 133e7cb072b7f31f04fbf5a220ce5e80631e3fc8 Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 11:28:11 -0400 Subject: [PATCH 06/15] NIT: use explicit keying on check --- test/unified_format.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unified_format.py b/test/unified_format.py index 3386d0770d..acd65d574d 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -748,8 +748,8 @@ def match_result(self, expectation, actual, in_recursive_call=False): return None def assertHasDatabaseName(self, spec, actual): - if spec.get("databaseName"): - self.test.assertEqual(spec.get("databaseName"), actual.database_name) + if "databaseName" in spec: + self.test.assertEqual(spec["databaseName"], actual.database_name) def assertHasServiceId(self, spec, actual): if "hasServiceId" in spec: From b5debc22aa5ce843b16823d886ab0bb6803d701b Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 12:43:56 -0400 Subject: [PATCH 07/15] synced with the re-sync scripts from the specifications.git repo --- test/command_monitoring/bulkWrite.json | 6 +- test/command_monitoring/command.json | 3 +- test/command_monitoring/deleteMany.json | 8 +- test/command_monitoring/deleteOne.json | 6 +- test/command_monitoring/find.json | 2 +- test/command_monitoring/insertMany.json | 6 +- test/command_monitoring/insertOne.json | 6 +- .../pre-42-server-connection-id.json | 101 ++++++++++++ .../server-connection-id.json | 101 ++++++++++++ .../unacknowledgedBulkWrite.json | 3 +- test/command_monitoring/updateMany.json | 6 +- test/command_monitoring/updateOne.json | 11 +- .../command_monitoring/writeConcernError.json | 155 ++++++++++++++++++ 13 files changed, 377 insertions(+), 37 deletions(-) create mode 100644 test/command_monitoring/pre-42-server-connection-id.json create mode 100644 test/command_monitoring/server-connection-id.json create mode 100644 test/command_monitoring/writeConcernError.json diff --git a/test/command_monitoring/bulkWrite.json b/test/command_monitoring/bulkWrite.json index 0c065d2b32..49c728442e 100644 --- a/test/command_monitoring/bulkWrite.json +++ b/test/command_monitoring/bulkWrite.json @@ -106,8 +106,7 @@ "ok": 1, "n": 1 }, - "commandName": "insert", - "databaseName": "command-monitoring-tests" + "commandName": "insert" } }, { @@ -144,8 +143,7 @@ "ok": 1, "n": 1 }, - "commandName": "update", - "databaseName": "command-monitoring-tests" + "commandName": "update" } } ] diff --git a/test/command_monitoring/command.json b/test/command_monitoring/command.json index 965c4c48d7..c28af95fed 100644 --- a/test/command_monitoring/command.json +++ b/test/command_monitoring/command.json @@ -72,8 +72,7 @@ "reply": { "ok": 1 }, - "commandName": "ping", - "databaseName": "command-monitoring-tests" + "commandName": "ping" } } ] diff --git a/test/command_monitoring/deleteMany.json b/test/command_monitoring/deleteMany.json index 9c8e8cecdf..78ebad1f98 100644 --- a/test/command_monitoring/deleteMany.json +++ b/test/command_monitoring/deleteMany.json @@ -93,8 +93,7 @@ "ok": 1, "n": 2 }, - "commandName": "delete", - "databaseName": "command-monitoring-tests" + "commandName": "delete" } } ] @@ -152,8 +151,7 @@ "$$type": "array" } }, - "commandName": "delete", - "databaseName": "command-monitoring-tests" + "commandName": "delete" } } ] @@ -161,4 +159,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/test/command_monitoring/deleteOne.json b/test/command_monitoring/deleteOne.json index 64662e8c62..2420794fe5 100644 --- a/test/command_monitoring/deleteOne.json +++ b/test/command_monitoring/deleteOne.json @@ -93,8 +93,7 @@ "ok": 1, "n": 1 }, - "commandName": "delete", - "databaseName": "command-monitoring-tests" + "commandName": "delete" } } ] @@ -152,8 +151,7 @@ "$$type": "array" } }, - "commandName": "delete", - "databaseName": "command-monitoring-tests" + "commandName": "delete" } } ] diff --git a/test/command_monitoring/find.json b/test/command_monitoring/find.json index 3febe01119..bc9668499b 100644 --- a/test/command_monitoring/find.json +++ b/test/command_monitoring/find.json @@ -1,6 +1,6 @@ { "description": "find", - "schemaVersion": "1.1", + "schemaVersion": "1.15", "createEntities": [ { "client": { diff --git a/test/command_monitoring/insertMany.json b/test/command_monitoring/insertMany.json index d2d0bd9355..a80a218c67 100644 --- a/test/command_monitoring/insertMany.json +++ b/test/command_monitoring/insertMany.json @@ -82,8 +82,7 @@ "ok": 1, "n": 1 }, - "commandName": "insert", - "databaseName": "command-monitoring-tests" + "commandName": "insert" } } ] @@ -138,8 +137,7 @@ "$$type": "array" } }, - "commandName": "insert", - "databaseName": "command-monitoring-tests" + "commandName": "insert" } } ] diff --git a/test/command_monitoring/insertOne.json b/test/command_monitoring/insertOne.json index 09885585f0..6ff732e41b 100644 --- a/test/command_monitoring/insertOne.json +++ b/test/command_monitoring/insertOne.json @@ -80,8 +80,7 @@ "ok": 1, "n": 1 }, - "commandName": "insert", - "databaseName": "command-monitoring-tests" + "commandName": "insert" } } ] @@ -134,8 +133,7 @@ "$$type": "array" } }, - "commandName": "insert", - "databaseName": "command-monitoring-tests" + "commandName": "insert" } } ] diff --git a/test/command_monitoring/pre-42-server-connection-id.json b/test/command_monitoring/pre-42-server-connection-id.json new file mode 100644 index 0000000000..141fbe584f --- /dev/null +++ b/test/command_monitoring/pre-42-server-connection-id.json @@ -0,0 +1,101 @@ +{ + "description": "pre-42-server-connection-id", + "schemaVersion": "1.6", + "runOnRequirements": [ + { + "maxServerVersion": "4.0.99" + } + ], + "createEntities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "commandStartedEvent", + "commandSucceededEvent", + "commandFailedEvent" + ] + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "server-connection-id-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "coll" + } + } + ], + "initialData": [ + { + "databaseName": "server-connection-id-tests", + "collectionName": "coll", + "documents": [] + } + ], + "tests": [ + { + "description": "command events do not include server connection id", + "operations": [ + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "x": 1 + } + } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": { + "$or": true + } + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client", + "events": [ + { + "commandStartedEvent": { + "commandName": "insert", + "hasServerConnectionId": false + } + }, + { + "commandSucceededEvent": { + "commandName": "insert", + "hasServerConnectionId": false + } + }, + { + "commandStartedEvent": { + "commandName": "find", + "hasServerConnectionId": false + } + }, + { + "commandFailedEvent": { + "commandName": "find", + "hasServerConnectionId": false + } + } + ] + } + ] + } + ] +} diff --git a/test/command_monitoring/server-connection-id.json b/test/command_monitoring/server-connection-id.json new file mode 100644 index 0000000000..a8f27637fc --- /dev/null +++ b/test/command_monitoring/server-connection-id.json @@ -0,0 +1,101 @@ +{ + "description": "server-connection-id", + "schemaVersion": "1.6", + "runOnRequirements": [ + { + "minServerVersion": "4.2" + } + ], + "createEntities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "commandStartedEvent", + "commandSucceededEvent", + "commandFailedEvent" + ] + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "server-connection-id-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "coll" + } + } + ], + "initialData": [ + { + "databaseName": "server-connection-id-tests", + "collectionName": "coll", + "documents": [] + } + ], + "tests": [ + { + "description": "command events include server connection id", + "operations": [ + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "x": 1 + } + } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": { + "$or": true + } + }, + "expectError": { + "isError": true + } + } + ], + "expectEvents": [ + { + "client": "client", + "events": [ + { + "commandStartedEvent": { + "commandName": "insert", + "hasServerConnectionId": true + } + }, + { + "commandSucceededEvent": { + "commandName": "insert", + "hasServerConnectionId": true + } + }, + { + "commandStartedEvent": { + "commandName": "find", + "hasServerConnectionId": true + } + }, + { + "commandFailedEvent": { + "commandName": "find", + "hasServerConnectionId": true + } + } + ] + } + ] + } + ] +} diff --git a/test/command_monitoring/unacknowledgedBulkWrite.json b/test/command_monitoring/unacknowledgedBulkWrite.json index 3b577152f9..4c16d6df11 100644 --- a/test/command_monitoring/unacknowledgedBulkWrite.json +++ b/test/command_monitoring/unacknowledgedBulkWrite.json @@ -97,8 +97,7 @@ "$$exists": false } }, - "commandName": "insert", - "databaseName": "command-monitoring-tests" + "commandName": "insert" } } ] diff --git a/test/command_monitoring/updateMany.json b/test/command_monitoring/updateMany.json index 66b4a5a791..b15434226c 100644 --- a/test/command_monitoring/updateMany.json +++ b/test/command_monitoring/updateMany.json @@ -106,8 +106,7 @@ "ok": 1, "n": 2 }, - "commandName": "update", - "databaseName": "command-monitoring-tests" + "commandName": "update" } } ] @@ -178,8 +177,7 @@ "$$type": "array" } }, - "commandName": "update", - "databaseName": "command-monitoring-tests" + "commandName": "update" } } ] diff --git a/test/command_monitoring/updateOne.json b/test/command_monitoring/updateOne.json index f418dbe401..a0ae99e88d 100644 --- a/test/command_monitoring/updateOne.json +++ b/test/command_monitoring/updateOne.json @@ -108,8 +108,7 @@ "ok": 1, "n": 1 }, - "commandName": "update", - "databaseName": "command-monitoring-tests" + "commandName": "update" } } ] @@ -177,8 +176,7 @@ } ] }, - "commandName": "update", - "databaseName": "command-monitoring-tests" + "commandName": "update" } } ] @@ -251,8 +249,7 @@ "$$type": "array" } }, - "commandName": "update", - "databaseName": "command-monitoring-tests" + "commandName": "update" } } ] @@ -260,4 +257,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/test/command_monitoring/writeConcernError.json b/test/command_monitoring/writeConcernError.json new file mode 100644 index 0000000000..7bc16f2ab7 --- /dev/null +++ b/test/command_monitoring/writeConcernError.json @@ -0,0 +1,155 @@ +{ + "description": "writeConcernError", + "schemaVersion": "1.4", + "runOnRequirements": [ + { + "minServerVersion": "4.1.0", + "topologies": [ + "replicaset" + ], + "serverless": "forbid" + } + ], + "createEntities": [ + { + "client": { + "id": "client", + "observeEvents": [ + "commandStartedEvent", + "commandSucceededEvent", + "commandFailedEvent" + ] + } + }, + { + "database": { + "id": "database", + "client": "client", + "databaseName": "command-monitoring-tests" + } + }, + { + "collection": { + "id": "collection", + "database": "database", + "collectionName": "test" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "command-monitoring-tests", + "documents": [ + { + "_id": 1, + "x": 11 + } + ] + } + ], + "tests": [ + { + "description": "A retryable write with write concern errors publishes success event", + "operations": [ + { + "name": "failPoint", + "object": "testRunner", + "arguments": { + "client": "client", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "insert" + ], + "writeConcernError": { + "code": 91, + "errorLabels": [ + "RetryableWriteError" + ] + } + } + } + } + }, + { + "name": "insertOne", + "object": "collection", + "arguments": { + "document": { + "_id": 2, + "x": 22 + } + } + } + ], + "expectEvents": [ + { + "client": "client", + "events": [ + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2, + "x": 22 + } + ], + "ordered": true + }, + "commandName": "insert", + "databaseName": "command-monitoring-tests" + } + }, + { + "commandSucceededEvent": { + "reply": { + "ok": 1, + "n": 1, + "writeConcernError": { + "code": 91, + "errorLabels": [ + "RetryableWriteError" + ] + } + }, + "commandName": "insert" + } + }, + { + "commandStartedEvent": { + "command": { + "insert": "test", + "documents": [ + { + "_id": 2, + "x": 22 + } + ], + "ordered": true + }, + "commandName": "insert", + "databaseName": "command-monitoring-tests" + } + }, + { + "commandSucceededEvent": { + "reply": { + "ok": 1, + "n": 1 + }, + "commandName": "insert" + } + } + ] + } + ] + } + ] +} From 178e312688db276b1113ef1375e6b2b00cd6778e Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 12:46:36 -0400 Subject: [PATCH 08/15] made __slots__ a tuple once again --- pymongo/monitoring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 468e03decb..36b7bd8b94 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -629,7 +629,7 @@ class CommandStartedEvent(_CommandEvent): - `service_id`: The service_id this command was sent to, or ``None``. """ - __slots__ = "__cmd" + __slots__ = ("__cmd",) def __init__( self, From 4ec36750695c6c0c49f73ce4ee8a90b053f20d3d Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 14:10:22 -0400 Subject: [PATCH 09/15] version change bump --- test/unified_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unified_format.py b/test/unified_format.py index acd65d574d..aefa18d60d 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -874,7 +874,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest): a class attribute ``TEST_SPEC``. """ - SCHEMA_VERSION = Version.from_string("1.12") + SCHEMA_VERSION = Version.from_string("1.15") RUN_ON_LOAD_BALANCER = True RUN_ON_SERVERLESS = True TEST_SPEC: Any From b3ebd411b10a4a4138acde0913e33aececeea152 Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 1 Sep 2023 14:15:30 -0400 Subject: [PATCH 10/15] moved the operation.as_command call back --- pymongo/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymongo/server.py b/pymongo/server.py index a2bc68b87c..820240375e 100644 --- a/pymongo/server.py +++ b/pymongo/server.py @@ -130,7 +130,6 @@ def run_operation( publish = listeners.enabled_for_commands if publish: start = datetime.now() - cmd, dbn = operation.as_command(conn) use_cmd = operation.use_command(conn) more_to_come = operation.conn_mgr and operation.conn_mgr.more_to_come @@ -142,6 +141,7 @@ def run_operation( if publish: assert listeners is not None + cmd, dbn = operation.as_command(conn) listeners.publish_command_start( cmd, dbn, request_id, conn.address, service_id=conn.service_id ) From db3d211649500d3ef37303ee999298a18ad77f6b Mon Sep 17 00:00:00 2001 From: Jib Date: Fri, 15 Sep 2023 12:33:08 -0400 Subject: [PATCH 11/15] removed server-connection-id tests and changed str typing --- pymongo/monitoring.py | 29 ++--- .../pre-42-server-connection-id.json | 101 ------------------ .../server-connection-id.json | 101 ------------------ 3 files changed, 11 insertions(+), 220 deletions(-) delete mode 100644 test/command_monitoring/pre-42-server-connection-id.json delete mode 100644 test/command_monitoring/server-connection-id.json diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 36b7bd8b94..6d801320fb 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -570,7 +570,7 @@ def __init__( connection_id: _Address, operation_id: Optional[int], service_id: Optional[ObjectId] = None, - database_name: Optional[str] = None, + database_name: str = "", ) -> None: self.__cmd_name = command_name self.__rqst_id = request_id @@ -608,8 +608,8 @@ def operation_id(self) -> Optional[int]: return self.__op_id @property - def database_name(self) -> Optional[str]: - """The database_name this command was sent to, or ``None``. + def database_name(self) -> str: + """The database_name this command was sent to, or ``""``. .. versionadded:: 4.6 """ @@ -663,13 +663,6 @@ def command(self) -> _DocumentOut: """The command document.""" return self.__cmd - @property - def database_name(self) -> str: - """The name of the database this command was run against.""" - db = super().database_name - assert db is not None - return db - def __repr__(self) -> str: return ("<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}>").format( self.__class__.__name__, @@ -693,7 +686,7 @@ class CommandSucceededEvent(_CommandEvent): was sent to. - `operation_id`: An optional identifier for a series of related events. - `service_id`: The service_id this command was sent to, or ``None``. - - `database_name`: The database this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``""``. """ __slots__ = ("__duration_micros", "__reply") @@ -707,7 +700,7 @@ def __init__( connection_id: _Address, operation_id: Optional[int], service_id: Optional[ObjectId] = None, - database_name: Optional[str] = None, + database_name: str = "", ) -> None: super().__init__( command_name, @@ -760,7 +753,7 @@ class CommandFailedEvent(_CommandEvent): was sent to. - `operation_id`: An optional identifier for a series of related events. - `service_id`: The service_id this command was sent to, or ``None``. - - `database_name`: The database this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``""``. """ __slots__ = ("__duration_micros", "__failure") @@ -774,7 +767,7 @@ def __init__( connection_id: _Address, operation_id: Optional[int], service_id: Optional[ObjectId] = None, - database_name: Optional[str] = None, + database_name: str = "", ) -> None: super().__init__( command_name, @@ -1523,7 +1516,7 @@ def publish_command_success( op_id: Optional[int] = None, service_id: Optional[ObjectId] = None, speculative_hello: bool = False, - database_name: Optional[str] = None, + database_name: str = "", ) -> None: """Publish a CommandSucceededEvent to all command listeners. @@ -1537,7 +1530,7 @@ def publish_command_success( - `op_id`: The (optional) operation id for this operation. - `service_id`: The service_id this command was sent to, or ``None``. - `speculative_hello`: Was the command sent with speculative auth? - - `database_name`: The database this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``""``. """ if op_id is None: op_id = request_id @@ -1570,7 +1563,7 @@ def publish_command_failure( connection_id: _Address, op_id: Optional[int] = None, service_id: Optional[ObjectId] = None, - database_name: Optional[str] = None, + database_name: str = "", ) -> None: """Publish a CommandFailedEvent to all command listeners. @@ -1584,7 +1577,7 @@ def publish_command_failure( command was sent to. - `op_id`: The (optional) operation id for this operation. - `service_id`: The service_id this command was sent to, or ``None``. - - `database_name`: The database this command was sent to, or ``None``. + - `database_name`: The database this command was sent to, or ``""``. """ if op_id is None: op_id = request_id diff --git a/test/command_monitoring/pre-42-server-connection-id.json b/test/command_monitoring/pre-42-server-connection-id.json deleted file mode 100644 index 141fbe584f..0000000000 --- a/test/command_monitoring/pre-42-server-connection-id.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "description": "pre-42-server-connection-id", - "schemaVersion": "1.6", - "runOnRequirements": [ - { - "maxServerVersion": "4.0.99" - } - ], - "createEntities": [ - { - "client": { - "id": "client", - "observeEvents": [ - "commandStartedEvent", - "commandSucceededEvent", - "commandFailedEvent" - ] - } - }, - { - "database": { - "id": "database", - "client": "client", - "databaseName": "server-connection-id-tests" - } - }, - { - "collection": { - "id": "collection", - "database": "database", - "collectionName": "coll" - } - } - ], - "initialData": [ - { - "databaseName": "server-connection-id-tests", - "collectionName": "coll", - "documents": [] - } - ], - "tests": [ - { - "description": "command events do not include server connection id", - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "$or": true - } - }, - "expectError": { - "isError": true - } - } - ], - "expectEvents": [ - { - "client": "client", - "events": [ - { - "commandStartedEvent": { - "commandName": "insert", - "hasServerConnectionId": false - } - }, - { - "commandSucceededEvent": { - "commandName": "insert", - "hasServerConnectionId": false - } - }, - { - "commandStartedEvent": { - "commandName": "find", - "hasServerConnectionId": false - } - }, - { - "commandFailedEvent": { - "commandName": "find", - "hasServerConnectionId": false - } - } - ] - } - ] - } - ] -} diff --git a/test/command_monitoring/server-connection-id.json b/test/command_monitoring/server-connection-id.json deleted file mode 100644 index a8f27637fc..0000000000 --- a/test/command_monitoring/server-connection-id.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "description": "server-connection-id", - "schemaVersion": "1.6", - "runOnRequirements": [ - { - "minServerVersion": "4.2" - } - ], - "createEntities": [ - { - "client": { - "id": "client", - "observeEvents": [ - "commandStartedEvent", - "commandSucceededEvent", - "commandFailedEvent" - ] - } - }, - { - "database": { - "id": "database", - "client": "client", - "databaseName": "server-connection-id-tests" - } - }, - { - "collection": { - "id": "collection", - "database": "database", - "collectionName": "coll" - } - } - ], - "initialData": [ - { - "databaseName": "server-connection-id-tests", - "collectionName": "coll", - "documents": [] - } - ], - "tests": [ - { - "description": "command events include server connection id", - "operations": [ - { - "name": "insertOne", - "object": "collection", - "arguments": { - "document": { - "x": 1 - } - } - }, - { - "name": "find", - "object": "collection", - "arguments": { - "filter": { - "$or": true - } - }, - "expectError": { - "isError": true - } - } - ], - "expectEvents": [ - { - "client": "client", - "events": [ - { - "commandStartedEvent": { - "commandName": "insert", - "hasServerConnectionId": true - } - }, - { - "commandSucceededEvent": { - "commandName": "insert", - "hasServerConnectionId": true - } - }, - { - "commandStartedEvent": { - "commandName": "find", - "hasServerConnectionId": true - } - }, - { - "commandFailedEvent": { - "commandName": "find", - "hasServerConnectionId": true - } - } - ] - } - ] - } - ] -} From 96c2030dd66a0affed7ad463b9d2c7f648b49dda Mon Sep 17 00:00:00 2001 From: Jib Date: Mon, 2 Oct 2023 11:36:37 -0400 Subject: [PATCH 12/15] addressed pr comments --- pymongo/monitoring.py | 7 ++++++- pymongo/server.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 5b962c31ba..3d648df5f3 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -629,7 +629,7 @@ class CommandStartedEvent(_CommandEvent): - `service_id`: The service_id this command was sent to, or ``None``. """ - __slots__ = ("__cmd",) + __slots__ = ("__cmd", "__db") def __init__( self, @@ -663,6 +663,11 @@ def command(self) -> _DocumentOut: """The command document.""" return self.__cmd + @property + def database_name(self) -> str: + """The name of the database this command was run against.""" + return self.__db + def __repr__(self) -> str: return ("<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}>").format( self.__class__.__name__, diff --git a/pymongo/server.py b/pymongo/server.py index 5c0c408df9..985d45acb3 100644 --- a/pymongo/server.py +++ b/pymongo/server.py @@ -131,8 +131,8 @@ def run_operation( request_id, data, max_doc_size = self._split_message(message) if publish: - assert listeners is not None cmd, dbn = operation.as_command(conn) + assert listeners is not None listeners.publish_command_start( cmd, dbn, request_id, conn.address, service_id=conn.service_id ) From 3a0ccbadadb8dc09125ee9287d12e0a5ceafc52f Mon Sep 17 00:00:00 2001 From: Jib Date: Mon, 2 Oct 2023 12:06:25 -0400 Subject: [PATCH 13/15] removed redundant slotting --- pymongo/monitoring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 3d648df5f3..9b0aedc4a6 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -629,7 +629,7 @@ class CommandStartedEvent(_CommandEvent): - `service_id`: The service_id this command was sent to, or ``None``. """ - __slots__ = ("__cmd", "__db") + __slots__ = ("__cmd",) def __init__( self, From 9b0c08e319756fb386176d422a55162f7a618c6a Mon Sep 17 00:00:00 2001 From: Jib Date: Mon, 2 Oct 2023 13:53:12 -0400 Subject: [PATCH 14/15] call database_name property from inherited property call --- doc/changelog.rst | 6 ++++++ pymongo/monitoring.py | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 3571516bfd..fc0d2c5fe1 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,12 @@ Changelog ========= +Changes in Version 4.6 +---------------------- + +PyMongo 4.6 brings a number of improvements including: +- Added support for recording database name to command*Events (`PYTHON-3598`_) + Changes in Version 4.5 ---------------------- diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 9b0aedc4a6..942ddd9850 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -665,8 +665,12 @@ def command(self) -> _DocumentOut: @property def database_name(self) -> str: - """The name of the database this command was run against.""" - return self.__db + """The name of the database this command was run against. + + .. versionchanged:: 4.6 + Derived from base class's property. + """ + return super().database_name def __repr__(self) -> str: return ("<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}>").format( From d6424c01be9ded043e7ff6098a596b7141f0a41c Mon Sep 17 00:00:00 2001 From: Jib Date: Wed, 4 Oct 2023 10:06:01 -0400 Subject: [PATCH 15/15] readme and documentation changes --- doc/changelog.rst | 3 ++- pymongo/monitoring.py | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index fc0d2c5fe1..06fe5ec688 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -5,7 +5,8 @@ Changes in Version 4.6 ---------------------- PyMongo 4.6 brings a number of improvements including: -- Added support for recording database name to command*Events (`PYTHON-3598`_) +- Added the :attr:`pymongo.monitoring.CommandSucceededEvent.database_name` property. +- Added the :attr:`pymongo.monitoring.CommandFailedEvent.database_name` property. Changes in Version 4.5 ---------------------- diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 942ddd9850..5bc3fda497 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -665,11 +665,7 @@ def command(self) -> _DocumentOut: @property def database_name(self) -> str: - """The name of the database this command was run against. - - .. versionchanged:: 4.6 - Derived from base class's property. - """ + """The name of the database this command was run against.""" return super().database_name def __repr__(self) -> str: