PYTHON-2769 Test redaction of replies to security-sensitive commands (#676)

Resync command monitoring and unified test format tests.
Redact entire hello response when the command started contained speculativeAuthenticate.
Make OP_REPLY cursor.cursor_id always be an Int64.
This commit is contained in:
Shane Harvey 2021-07-15 14:12:11 -07:00 committed by GitHub
parent 9a4c64f325
commit 01e34cebdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 1689 additions and 528 deletions

View File

@ -33,6 +33,7 @@ from bson import (CodecOptions,
_dict_to_bson,
_make_c_string)
from bson.codec_options import DEFAULT_CODEC_OPTIONS
from bson.int64 import Int64
from bson.raw_bson import (_inflate_bson, DEFAULT_RAW_BSON_OPTIONS,
RawBSONDocument)
from bson.son import SON
@ -1503,7 +1504,7 @@ class _OpReply(object):
def __init__(self, flags, cursor_id, number_returned, documents):
self.flags = flags
self.cursor_id = cursor_id
self.cursor_id = Int64(cursor_id)
self.number_returned = number_returned
self.documents = documents

View File

@ -1350,7 +1350,8 @@ class _EventListeners(object):
def publish_command_success(self, duration, reply, command_name,
request_id, connection_id, op_id=None,
service_id=None):
service_id=None,
speculative_hello=False):
"""Publish a CommandSucceededEvent to all command listeners.
:Parameters:
@ -1362,9 +1363,14 @@ class _EventListeners(object):
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``.
- `speculative_hello`: Was the command sent with speculative auth?
"""
if op_id is None:
op_id = request_id
if speculative_hello:
# Redact entire response when the command started contained
# speculativeAuthenticate.
reply = {}
event = CommandSucceededEvent(
duration, reply, command_name, request_id, connection_id, op_id,
service_id)

View File

@ -31,6 +31,7 @@ from pymongo.errors import (NotPrimaryError,
ProtocolError,
_OperationCancelled)
from pymongo.message import _UNPACK_REPLY, _OpMsg
from pymongo.monitoring import _is_speculative_authenticate
from pymongo.socket_checker import _errno_from_exception
@ -82,6 +83,7 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
name = next(iter(spec))
ns = dbname + '.$cmd'
flags = 4 if slave_ok else 0
speculative_hello = False
# Publish the original command document, perhaps with lsid and $clusterTime.
orig = spec
@ -98,6 +100,7 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
publish = listeners is not None and listeners.enabled_for_commands
if publish:
start = datetime.datetime.now()
speculative_hello = _is_speculative_authenticate(name, spec)
if compression_ctx and name.lower() in _NO_COMPRESSION:
compression_ctx = None
@ -170,7 +173,8 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
duration = (datetime.datetime.now() - start) + encoding_duration
listeners.publish_command_success(
duration, response_doc, name, request_id, address,
service_id=sock_info.service_id)
service_id=sock_info.service_id,
speculative_hello=speculative_hello)
if client and client._encrypter and reply:
decrypted = client._encrypter.decrypt(reply.raw_command_response())

View File

@ -86,9 +86,7 @@
"$set": {
"x": 333
}
},
"upsert": false,
"multi": false
}
}
],
"ordered": true

View File

@ -32,9 +32,7 @@
"x": 22
}
],
"options": {
"ordered": true
}
"ordered": true
},
"command_name": "insert",
"database_name": "command-monitoring-tests"
@ -75,9 +73,7 @@
"x": 11
}
],
"options": {
"ordered": true
}
"ordered": true
},
"command_name": "insert",
"database_name": "command-monitoring-tests"
@ -128,9 +124,7 @@
"x": 22
}
],
"options": {
"ordered": false
}
"ordered": false
},
"command_name": "insert",
"database_name": "command-monitoring-tests"

View File

@ -51,8 +51,7 @@
"x": 1
}
},
"multi": true,
"upsert": false
"multi": true
}
]
},
@ -106,8 +105,7 @@
"x": 1
}
},
"multi": true,
"upsert": false
"multi": true
}
]
},

View File

@ -50,9 +50,7 @@
"$inc": {
"x": 1
}
},
"multi": false,
"upsert": false
}
}
]
},
@ -103,7 +101,6 @@
"x": 1
}
},
"multi": false,
"upsert": true
}
]
@ -163,9 +160,7 @@
"$nothing": {
"x": 1
}
},
"multi": false,
"upsert": false
}
}
]
},

View File

@ -12,7 +12,8 @@
"client": {
"id": "client",
"observeEvents": [
"commandStartedEvent"
"commandStartedEvent",
"commandSucceededEvent"
],
"observeSensitiveCommands": true
}
@ -35,7 +36,10 @@
"arguments": {
"commandName": "authenticate",
"command": {
"authenticate": "private"
"authenticate": 1,
"mechanism": "MONGODB-X509",
"user": "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry",
"db": "$external"
}
},
"expectError": {
@ -53,6 +57,15 @@
"command": {
"authenticate": {
"$$exists": false
},
"mechanism": {
"$$exists": false
},
"user": {
"$$exists": false
},
"db": {
"$$exists": false
}
}
}
@ -70,7 +83,9 @@
"arguments": {
"commandName": "saslStart",
"command": {
"saslStart": "private"
"saslStart": 1,
"payload": "definitely-invalid-payload",
"db": "admin"
}
},
"expectError": {
@ -88,6 +103,12 @@
"command": {
"saslStart": {
"$$exists": false
},
"payload": {
"$$exists": false
},
"db": {
"$$exists": false
}
}
}
@ -105,7 +126,9 @@
"arguments": {
"commandName": "saslContinue",
"command": {
"saslContinue": "private"
"saslContinue": 1,
"conversationId": 0,
"payload": "definitely-invalid-payload"
}
},
"expectError": {
@ -123,6 +146,12 @@
"command": {
"saslContinue": {
"$$exists": false
},
"conversationId": {
"$$exists": false
},
"payload": {
"$$exists": false
}
}
}
@ -140,7 +169,7 @@
"arguments": {
"commandName": "getnonce",
"command": {
"getnonce": "private"
"getnonce": 1
}
}
}
@ -158,6 +187,19 @@
}
}
}
},
{
"commandSucceededEvent": {
"commandName": "getnonce",
"reply": {
"ok": {
"$$exists": false
},
"nonce": {
"$$exists": false
}
}
}
}
]
}
@ -172,7 +214,9 @@
"arguments": {
"commandName": "createUser",
"command": {
"createUser": "private"
"createUser": "private",
"pwd": {},
"roles": []
}
},
"expectError": {
@ -190,6 +234,12 @@
"command": {
"createUser": {
"$$exists": false
},
"pwd": {
"$$exists": false
},
"roles": {
"$$exists": false
}
}
}
@ -207,7 +257,9 @@
"arguments": {
"commandName": "updateUser",
"command": {
"updateUser": "private"
"updateUser": "private",
"pwd": {},
"roles": []
}
},
"expectError": {
@ -225,6 +277,12 @@
"command": {
"updateUser": {
"$$exists": false
},
"pwd": {
"$$exists": false
},
"roles": {
"$$exists": false
}
}
}
@ -340,6 +398,11 @@
},
{
"description": "hello with speculative authenticate",
"runOnRequirements": [
{
"minServerVersion": "4.9"
}
],
"operations": [
{
"name": "runCommand",
@ -347,40 +410,11 @@
"arguments": {
"commandName": "hello",
"command": {
"hello": "private",
"speculativeAuthenticate": "foo"
"hello": 1,
"speculativeAuthenticate": {
"saslStart": 1
}
}
},
"expectError": {
"isError": true
}
},
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "ismaster",
"command": {
"ismaster": "private",
"speculativeAuthenticate": "foo"
}
},
"expectError": {
"isError": true
}
},
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "isMaster",
"command": {
"isMaster": "private",
"speculativeAuthenticate": "foo"
}
},
"expectError": {
"isError": true
}
}
],
@ -394,16 +428,86 @@
"command": {
"hello": {
"$$exists": false
},
"speculativeAuthenticate": {
"$$exists": false
}
}
}
},
{
"commandSucceededEvent": {
"commandName": "hello",
"reply": {
"isWritablePrimary": {
"$$exists": false
},
"speculativeAuthenticate": {
"$$exists": false
}
}
}
}
]
}
]
},
{
"description": "legacy hello with speculative authenticate",
"operations": [
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "ismaster",
"command": {
"ismaster": 1,
"speculativeAuthenticate": {
"saslStart": 1
}
}
}
},
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "isMaster",
"command": {
"isMaster": 1,
"speculativeAuthenticate": {
"saslStart": 1
}
}
}
}
],
"expectEvents": [
{
"client": "client",
"events": [
{
"commandStartedEvent": {
"commandName": "ismaster",
"command": {
"ismaster": {
"$$exists": false
},
"speculativeAuthenticate": {
"$$exists": false
}
}
}
},
{
"commandSucceededEvent": {
"commandName": "ismaster",
"reply": {
"ismaster": {
"$$exists": false
},
"speculativeAuthenticate": {
"$$exists": false
}
}
}
@ -414,6 +518,22 @@
"command": {
"isMaster": {
"$$exists": false
},
"speculativeAuthenticate": {
"$$exists": false
}
}
}
},
{
"commandSucceededEvent": {
"commandName": "isMaster",
"reply": {
"ismaster": {
"$$exists": false
},
"speculativeAuthenticate": {
"$$exists": false
}
}
}
@ -424,6 +544,11 @@
},
{
"description": "hello without speculative authenticate is not redacted",
"runOnRequirements": [
{
"minServerVersion": "4.9"
}
],
"operations": [
{
"name": "runCommand",
@ -431,27 +556,7 @@
"arguments": {
"commandName": "hello",
"command": {
"hello": "public"
}
}
},
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "ismaster",
"command": {
"ismaster": "public"
}
}
},
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "isMaster",
"command": {
"isMaster": "public"
"hello": 1
}
}
}
@ -464,15 +569,67 @@
"commandStartedEvent": {
"commandName": "hello",
"command": {
"hello": "public"
"hello": 1
}
}
},
{
"commandSucceededEvent": {
"commandName": "hello",
"reply": {
"isWritablePrimary": {
"$$exists": true
}
}
}
}
]
}
]
},
{
"description": "legacy hello without speculative authenticate is not redacted",
"operations": [
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "ismaster",
"command": {
"ismaster": 1
}
}
},
{
"name": "runCommand",
"object": "database",
"arguments": {
"commandName": "isMaster",
"command": {
"isMaster": 1
}
}
}
],
"expectEvents": [
{
"client": "client",
"events": [
{
"commandStartedEvent": {
"commandName": "ismaster",
"command": {
"ismaster": "public"
"ismaster": 1
}
}
},
{
"commandSucceededEvent": {
"commandName": "ismaster",
"reply": {
"ismaster": {
"$$exists": true
}
}
}
},
@ -480,7 +637,17 @@
"commandStartedEvent": {
"commandName": "isMaster",
"command": {
"isMaster": "public"
"isMaster": 1
}
}
},
{
"commandSucceededEvent": {
"commandName": "isMaster",
"reply": {
"ismaster": {
"$$exists": true
}
}
}
}

View File

@ -146,6 +146,15 @@ def create_test(scenario_def, test):
event.command['getMore'] = 42
elif event.command_name == 'killCursors':
event.command['cursors'] = [42]
elif event.command_name == 'update':
# TODO: remove this once PYTHON-1744 is done.
# Add upsert and multi fields back into
# expectations.
updates = expectation[event_type]['command'][
'updates']
for update in updates:
update.setdefault('upsert', False)
update.setdefault('multi', False)
elif event_type == "command_succeeded_event":
event = (
res['succeeded'].pop(0) if len(res['succeeded']) else None)

View File

@ -1,100 +0,0 @@
{
"description": "example-insertOne",
"schemaVersion": "1.0",
"runOnRequirements": [
{
"minServerVersion": "2.6"
}
],
"createEntities": [
{
"client": {
"id": "client0",
"observeEvents": [
"commandStartedEvent"
]
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "test"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll"
}
}
],
"initialData": [
{
"collectionName": "coll",
"databaseName": "test",
"documents": [
{
"_id": 1
}
]
}
],
"tests": [
{
"description": "insertOne",
"operations": [
{
"object": "collection0",
"name": "insertOne",
"arguments": {
"document": {
"_id": 2
}
},
"expectResult": {
"insertedId": {
"$$unsetOrMatches": 2
}
}
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"commandName": "insert",
"databaseName": "test",
"command": {
"insert": "coll",
"documents": [
{
"_id": 2
}
]
}
}
}
]
}
],
"outcome": [
{
"collectionName": "coll",
"databaseName": "test",
"documents": [
{
"_id": 1
},
{
"_id": 2
}
]
}
]
}
]
}

View File

@ -0,0 +1,18 @@
{
"description": "entity-client-observeSensitiveCommands-type",
"schemaVersion": "1.5",
"createEntities": [
{
"client": {
"id": "client0",
"observeSensitiveCommands": 0
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionCheckOutFailedEvent-reason-type",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionCheckOutFailedEvent": {
"reason": 10
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionCheckOutStartedEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionCheckedInEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionCheckedInEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionCheckedOutEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionCheckedOutEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionClosedEvent-reason-type",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionClosedEvent": {
"reason": 10
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionCreatedEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionCreatedEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-connectionReadyEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionReadyEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-poolClearedEvent-hasServiceId-type",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"poolClearedEvent": {
"hasServiceId": "foo"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-poolClosedEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"poolClosedEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-poolCreatedEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"poolCreatedEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "expectedCmapEvent-poolReadyEvent-additionalProperties",
"schemaVersion": "1.3",
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"poolReadyEvent": {
"foo": "bar"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,29 @@
{
"description": "expectedCommandEvent-commandFailedEvent-hasServiceId-type",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandFailedEvent": {
"hasServiceId": "foo"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,29 @@
{
"description": "expectedCommandEvent-commandStartedEvent-hasServiceId-type",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"hasServiceId": "foo"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,29 @@
{
"description": "expectedCommandEvent-commandSucceededEvent-hasServiceId-type",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandSucceededEvent": {
"hasServiceId": "foo"
}
}
]
}
]
}
]
}

View File

@ -1,32 +0,0 @@
{
"description": "expectedEvent-additionalProperties",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"foo": 0
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandFailedEvent-commandName-type",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandFailedEvent": {
"commandName": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandStartedEvent-additionalProperties",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"foo": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandStartedEvent-command-type",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandStartedEvent-commandName-type",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"commandName": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandStartedEvent-databaseName-type",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"databaseName": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandSucceededEvent-commandName-type",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandSucceededEvent": {
"commandName": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,34 +0,0 @@
{
"description": "expectedEvent-commandSucceededEvent-reply-type",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandSucceededEvent": {
"reply": 0
}
}
]
}
]
}
]
}
]
}

View File

@ -1,33 +0,0 @@
{
"description": "expectedEvent-maxProperties",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {},
"commandSucceededEvent": {}
}
]
}
]
}
]
}
]
}

View File

@ -1,30 +0,0 @@
{
"description": "expectedEvent-minProperties",
"schemaVersion": "1.0",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "foo",
"operations": [
{
"name": "foo",
"object": "client0",
"expectEvents": [
{
"client": "client0",
"events": [
{}
]
}
]
}
]
}
]
}

View File

@ -0,0 +1,24 @@
{
"description": "expectedEventsForClient-eventType-enum",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "invalid eventType value",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "foo",
"events": []
}
]
}
]
}

View File

@ -0,0 +1,24 @@
{
"description": "expectedEventsForClient-eventType-type",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "invalid eventType type",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": 10,
"events": []
}
]
}
]
}

View File

@ -0,0 +1,28 @@
{
"description": "expectedEventsForClient-events_conflicts_with_cmap_eventType",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "invalid event when eventType is cmap",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"commandStartedEvent": {}
}
]
}
]
}
]
}

View File

@ -0,0 +1,28 @@
{
"description": "expectedEventsForClient-events_conflicts_with_command_eventType",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "invalid event when eventType is command",
"operations": [],
"expectEvents": [
{
"client": "client0",
"eventType": "command",
"events": [
{
"poolCreatedEvent": {}
}
]
}
]
}
]
}

View File

@ -0,0 +1,27 @@
{
"description": "expectedEventsForClient-events_conflicts_with_default_eventType",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
}
],
"tests": [
{
"description": "invalid event when eventType is unset",
"operations": [],
"expectEvents": [
{
"client": "client0",
"events": [
{
"poolCreatedEvent": {}
}
]
}
]
}
]
}

View File

@ -0,0 +1,19 @@
{
"description": "operation-ignoreResultAndError-conflicts_with_expectError",
"schemaVersion": "1.3",
"tests": [
{
"description": "ignoreResultAndError used with expectError",
"operations": [
{
"name": "foo",
"object": "bar",
"ignoreResultAndError": true,
"expectError": {
"isError": true
}
}
]
}
]
}

View File

@ -0,0 +1,17 @@
{
"description": "operation-ignoreResultAndError-conflicts_with_expectResult",
"schemaVersion": "1.3",
"tests": [
{
"description": "ignoreResultAndError used with expectResult",
"operations": [
{
"name": "foo",
"object": "bar",
"ignoreResultAndError": true,
"expectResult": 1
}
]
}
]
}

View File

@ -0,0 +1,17 @@
{
"description": "operation-ignoreResultAndError-conflicts_with_saveResultAsEntity",
"schemaVersion": "1.3",
"tests": [
{
"description": "ignoreResultAndError used with saveResultAsEntity",
"operations": [
{
"name": "foo",
"object": "bar",
"ignoreResultAndError": true,
"saveResultAsEntity": "entity0"
}
]
}
]
}

View File

@ -0,0 +1,15 @@
{
"description": "runOnRequirement-auth-type",
"schemaVersion": "1.3",
"runOnRequirements": [
{
"auth": "foo"
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,15 @@
{
"description": "runOnRequirement-serverless-enum",
"schemaVersion": "1.4",
"runOnRequirements": [
{
"serverless": "foo"
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,15 @@
{
"description": "runOnRequirement-serverless-type",
"schemaVersion": "1.4",
"runOnRequirements": [
{
"serverless": 1234
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,26 @@
{
"description": "storeEventsAsEntity-additionalProperties",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"id": "client0_events",
"events": [
"CommandStartedEvent"
],
"foo": 0
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,25 @@
{
"description": "storeEventsAsEntity-events-enum",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"id": "client0_events",
"events": [
"foo"
]
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "storeEventsAsEntity-events-minItems",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"id": "client0_events",
"events": []
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,22 @@
{
"description": "storeEventsAsEntity-events-required",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"id": "client0_events"
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,23 @@
{
"description": "storeEventsAsEntity-events-type",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"id": "client0_events",
"events": 0
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,24 @@
{
"description": "storeEventsAsEntity-id-required",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"events": [
"CommandStartedEvent"
]
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,25 @@
{
"description": "storeEventsAsEntity-id-type",
"schemaVersion": "1.2",
"createEntities": [
{
"client": {
"id": "client0",
"storeEventsAsEntities": [
{
"id": 0,
"events": [
"CommandStartedEvent"
]
}
]
}
}
],
"tests": [
{
"description": "foo",
"operations": []
}
]
}

View File

@ -0,0 +1,63 @@
{
"description": "assertNumberConnectionsCheckedOut",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": true
}
}
],
"tests": [
{
"description": "operation fails if client field is not specified",
"operations": [
{
"name": "assertNumberConnectionsCheckedOut",
"object": "testRunner",
"arguments": {
"connections": 1
}
}
]
},
{
"description": "operation fails if connections field is not specified",
"operations": [
{
"name": "assertNumberConnectionsCheckedOut",
"object": "testRunner",
"arguments": {
"client": "client0"
}
}
]
},
{
"description": "operation fails if client entity does not exist",
"operations": [
{
"name": "assertNumberConnectionsCheckedOut",
"object": "testRunner",
"arguments": {
"client": "client1"
}
}
]
},
{
"description": "operation fails if number of connections is incorrect",
"operations": [
{
"name": "assertNumberConnectionsCheckedOut",
"object": "testRunner",
"arguments": {
"client": "client0",
"connections": 1
}
}
]
}
]
}

View File

@ -0,0 +1,62 @@
{
"description": "entity-find-cursor",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0"
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0Name"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"databaseName": "database0Name",
"collectionName": "coll0",
"documents": []
}
],
"tests": [
{
"description": "createFindCursor fails if filter is not specified",
"operations": [
{
"name": "createFindCursor",
"object": "collection0",
"saveResultAsEntity": "cursor0"
}
]
},
{
"description": "iterateUntilDocumentOrError fails if it references a nonexistent entity",
"operations": [
{
"name": "iterateUntilDocumentOrError",
"object": "cursor0"
}
]
},
{
"description": "close fails if it references a nonexistent entity",
"operations": [
{
"name": "close",
"object": "cursor0"
}
]
}
]
}

View File

@ -0,0 +1,72 @@
{
"description": "ignoreResultAndError",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": true
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0Name"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"collectionName": "coll0",
"databaseName": "database0Name",
"documents": []
}
],
"tests": [
{
"description": "operation errors are not ignored if ignoreResultAndError is false",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1
}
}
},
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1
}
},
"ignoreResultAndError": false
}
]
},
{
"description": "malformed operation fails if ignoreResultAndError is true",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"foo": "bar"
},
"ignoreResultAndError": true
}
]
}
]
}

View File

@ -0,0 +1,27 @@
{
"description": "assertNumberConnectionsCheckedOut",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": true
}
}
],
"tests": [
{
"description": "basic assertion succeeds",
"operations": [
{
"name": "assertNumberConnectionsCheckedOut",
"object": "testRunner",
"arguments": {
"client": "client0",
"connections": 0
}
}
]
}
]
}

View File

@ -0,0 +1,71 @@
{
"description": "entity-client-cmap-events",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": true,
"observeEvents": [
"connectionReadyEvent",
"connectionCheckedOutEvent",
"connectionCheckedInEvent"
]
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0Name"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"collectionName": "coll0",
"databaseName": "database0Name",
"documents": []
}
],
"tests": [
{
"description": "events are captured during an operation",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"x": 1
}
}
}
],
"expectEvents": [
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionReadyEvent": {}
},
{
"connectionCheckedOutEvent": {}
},
{
"connectionCheckedInEvent": {}
}
]
}
]
}
]
}

View File

@ -0,0 +1,182 @@
{
"description": "entity-find-cursor",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"observeEvents": [
"commandStartedEvent",
"commandSucceededEvent",
"commandFailedEvent"
]
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0Name"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"databaseName": "database0Name",
"collectionName": "coll0",
"documents": [
{
"_id": 1
},
{
"_id": 2
},
{
"_id": 3
},
{
"_id": 4
},
{
"_id": 5
}
]
}
],
"tests": [
{
"description": "cursors can be created, iterated, and closed",
"operations": [
{
"name": "createFindCursor",
"object": "collection0",
"arguments": {
"filter": {},
"batchSize": 2
},
"saveResultAsEntity": "cursor0"
},
{
"name": "iterateUntilDocumentOrError",
"object": "cursor0",
"expectResult": {
"_id": 1
}
},
{
"name": "iterateUntilDocumentOrError",
"object": "cursor0",
"expectResult": {
"_id": 2
}
},
{
"name": "iterateUntilDocumentOrError",
"object": "cursor0",
"expectResult": {
"_id": 3
}
},
{
"name": "close",
"object": "cursor0"
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": {
"find": "coll0",
"filter": {},
"batchSize": 2
},
"commandName": "find",
"databaseName": "database0Name"
}
},
{
"commandSucceededEvent": {
"reply": {
"cursor": {
"id": {
"$$type": "long"
},
"ns": {
"$$type": "string"
},
"firstBatch": {
"$$type": "array"
}
}
},
"commandName": "find"
}
},
{
"commandStartedEvent": {
"command": {
"getMore": {
"$$type": "long"
},
"collection": "coll0"
},
"commandName": "getMore"
}
},
{
"commandSucceededEvent": {
"reply": {
"cursor": {
"id": {
"$$type": "long"
},
"ns": {
"$$type": "string"
},
"nextBatch": {
"$$type": "array"
}
}
},
"commandName": "getMore"
}
},
{
"commandStartedEvent": {
"command": {
"killCursors": "coll0",
"cursors": {
"$$type": "array"
}
},
"commandName": "killCursors"
}
},
{
"commandSucceededEvent": {
"reply": {
"cursorsKilled": {
"$$unsetOrMatches": {
"$$type": "array"
}
}
},
"commandName": "killCursors"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,126 @@
{
"description": "expectedEventsForClient-eventType",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": true,
"observeEvents": [
"commandStartedEvent",
"connectionReadyEvent"
]
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0Name"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"collectionName": "coll0",
"databaseName": "database0Name",
"documents": []
}
],
"tests": [
{
"description": "eventType can be set to command and cmap",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1
}
}
}
],
"expectEvents": [
{
"client": "client0",
"eventType": "command",
"events": [
{
"commandStartedEvent": {
"command": {
"insert": "coll0",
"documents": [
{
"_id": 1
}
]
},
"commandName": "insert"
}
}
]
},
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionReadyEvent": {}
}
]
}
]
},
{
"description": "eventType defaults to command if unset",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1
}
}
}
],
"expectEvents": [
{
"client": "client0",
"events": [
{
"commandStartedEvent": {
"command": {
"insert": "coll0",
"documents": [
{
"_id": 1
}
]
},
"commandName": "insert"
}
}
]
},
{
"client": "client0",
"eventType": "cmap",
"events": [
{
"connectionReadyEvent": {}
}
]
}
]
}
]
}

View File

@ -0,0 +1,59 @@
{
"description": "ignoreResultAndError",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": true
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0Name"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "coll0"
}
}
],
"initialData": [
{
"collectionName": "coll0",
"databaseName": "database0Name",
"documents": []
}
],
"tests": [
{
"description": "operation errors are ignored if ignoreResultAndError is true",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1
}
}
},
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1
}
},
"ignoreResultAndError": true
}
]
}
]
}

View File

@ -323,7 +323,8 @@
"topologies": [
"replicaset",
"sharded-replicaset"
]
],
"serverless": "forbid"
}
],
"operations": [

View File

@ -250,7 +250,7 @@ class EntityMapUtil(object):
ignore_commands = spec.get('ignoreCommandMonitoringEvents', [])
observe_sensitive_commands = spec.get(
'observeSensitiveCommands', False)
# TODO: SUPPORT storeEventsAsEntities
# TODO: PYTHON-2511 support storeEventsAsEntities
if len(observe_events) or len(ignore_commands):
ignore_commands = [cmd.lower() for cmd in ignore_commands]
listener = EventListenerUtil(
@ -409,8 +409,8 @@ class MatchEvaluatorUtil(object):
t for alias in spec for t in self.__type_alias_to_type(alias)])
else:
permissible_types = self.__type_alias_to_type(spec)
self.test.assertIsInstance(
actual[key_to_compare], permissible_types)
value = actual[key_to_compare] if key_to_compare else actual
self.test.assertIsInstance(value, permissible_types)
def _operation_matchesEntity(self, spec, actual, key_to_compare):
expected_entity = self.test.entity_map[spec]
@ -822,6 +822,8 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
def _collectionOperation_createFindCursor(self, target, *args, **kwargs):
self.__raise_if_unsupported('find', target, Collection)
if 'filter' not in kwargs:
self.fail('createFindCursor requires a "filter" argument')
cursor = NonLazyCursor(target.find(*args, **kwargs))
self.addCleanup(cursor.close)
return cursor
@ -909,7 +911,9 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
try:
result = cmd(**dict(arguments))
except Exception as exc:
if ignore:
# Ignore all operation errors but to avoid masking bugs don't
# ignore things like TypeError and ValueError.
if ignore and isinstance(exc, (PyMongoError,)):
return
if expect_error:
return self.process_error(exc, expect_error)