From 01e34cebdb9aac96c72ddb649e9b0040a0dfd3a0 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Thu, 15 Jul 2021 14:12:11 -0700 Subject: [PATCH] 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. --- pymongo/message.py | 3 +- pymongo/monitoring.py | 8 +- pymongo/network.py | 6 +- test/command_monitoring/legacy/bulkWrite.json | 4 +- .../command_monitoring/legacy/insertMany.json | 12 +- .../command_monitoring/legacy/updateMany.json | 6 +- test/command_monitoring/legacy/updateOne.json | 9 +- .../unified/redacted-commands.json | 295 ++++++++++++++---- test/test_command_monitoring_legacy.py | 9 + .../example-insertOne.json | 100 ------ ...-client-observeSensitiveCommands-type.json | 18 ++ ...ectionCheckOutFailedEvent-reason-type.json | 23 ++ ...kOutStartedEvent-additionalProperties.json | 23 ++ ...onCheckedInEvent-additionalProperties.json | 23 ++ ...nCheckedOutEvent-additionalProperties.json | 23 ++ ...ent-connectionClosedEvent-reason-type.json | 23 ++ ...tionCreatedEvent-additionalProperties.json | 23 ++ ...ectionReadyEvent-additionalProperties.json | 23 ++ ...nt-poolClearedEvent-hasServiceId-type.json | 23 ++ ...-poolClosedEvent-additionalProperties.json | 23 ++ ...poolCreatedEvent-additionalProperties.json | 23 ++ ...t-poolReadyEvent-additionalProperties.json | 23 ++ ...-commandFailedEvent-hasServiceId-type.json | 29 ++ ...commandStartedEvent-hasServiceId-type.json | 29 ++ ...mmandSucceededEvent-hasServiceId-type.json | 29 ++ .../expectedEvent-additionalProperties.json | 32 -- ...t-commandFailedEvent-commandName-type.json | 34 -- ...mandStartedEvent-additionalProperties.json | 34 -- ...vent-commandStartedEvent-command-type.json | 34 -- ...-commandStartedEvent-commandName-type.json | 34 -- ...commandStartedEvent-databaseName-type.json | 34 -- ...ommandSucceededEvent-commandName-type.json | 34 -- ...vent-commandSucceededEvent-reply-type.json | 34 -- .../invalid/expectedEvent-maxProperties.json | 33 -- .../invalid/expectedEvent-minProperties.json | 30 -- ...xpectedEventsForClient-eventType-enum.json | 24 ++ ...xpectedEventsForClient-eventType-type.json | 24 ++ ...-events_conflicts_with_cmap_eventType.json | 28 ++ ...ents_conflicts_with_command_eventType.json | 28 ++ ...ents_conflicts_with_default_eventType.json | 27 ++ ...ltAndError-conflicts_with_expectError.json | 19 ++ ...tAndError-conflicts_with_expectResult.json | 17 + ...ror-conflicts_with_saveResultAsEntity.json | 17 + .../invalid/runOnRequirement-auth-type.json | 15 + .../runOnRequirement-serverless-enum.json | 15 + .../runOnRequirement-serverless-type.json | 15 + ...reEventsAsEntity-additionalProperties.json | 26 ++ .../storeEventsAsEntity-events-enum.json | 25 ++ .../storeEventsAsEntity-events-minItems.json | 23 ++ .../storeEventsAsEntity-events-required.json | 22 ++ .../storeEventsAsEntity-events-type.json | 23 ++ .../storeEventsAsEntity-id-required.json | 24 ++ .../invalid/storeEventsAsEntity-id-type.json | 25 ++ .../assertNumberConnectionsCheckedOut.json | 63 ++++ .../valid-fail/entity-find-cursor.json | 62 ++++ .../valid-fail/ignoreResultAndError.json | 72 +++++ .../assertNumberConnectionsCheckedOut.json | 27 ++ .../valid-pass/entity-client-cmap-events.json | 71 +++++ .../valid-pass/entity-find-cursor.json | 182 +++++++++++ .../expectedEventsForClient-eventType.json | 126 ++++++++ .../valid-pass/ignoreResultAndError.json | 59 ++++ .../valid-pass/poc-crud.json | 3 +- test/unified_format.py | 12 +- 63 files changed, 1689 insertions(+), 528 deletions(-) delete mode 100644 test/unified-test-format/example-insertOne.json create mode 100644 test/unified-test-format/invalid/entity-client-observeSensitiveCommands-type.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutFailedEvent-reason-type.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedInEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedOutEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionClosedEvent-reason-type.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionCreatedEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-connectionReadyEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-poolClearedEvent-hasServiceId-type.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-poolClosedEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-poolCreatedEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCmapEvent-poolReadyEvent-additionalProperties.json create mode 100644 test/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServiceId-type.json create mode 100644 test/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServiceId-type.json create mode 100644 test/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServiceId-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-additionalProperties.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandFailedEvent-commandName-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandStartedEvent-additionalProperties.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandStartedEvent-command-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandStartedEvent-commandName-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandStartedEvent-databaseName-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-commandName-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-reply-type.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-maxProperties.json delete mode 100644 test/unified-test-format/invalid/expectedEvent-minProperties.json create mode 100644 test/unified-test-format/invalid/expectedEventsForClient-eventType-enum.json create mode 100644 test/unified-test-format/invalid/expectedEventsForClient-eventType-type.json create mode 100644 test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_cmap_eventType.json create mode 100644 test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_command_eventType.json create mode 100644 test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_default_eventType.json create mode 100644 test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectError.json create mode 100644 test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectResult.json create mode 100644 test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_saveResultAsEntity.json create mode 100644 test/unified-test-format/invalid/runOnRequirement-auth-type.json create mode 100644 test/unified-test-format/invalid/runOnRequirement-serverless-enum.json create mode 100644 test/unified-test-format/invalid/runOnRequirement-serverless-type.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-additionalProperties.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-events-enum.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-events-minItems.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-events-required.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-events-type.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-id-required.json create mode 100644 test/unified-test-format/invalid/storeEventsAsEntity-id-type.json create mode 100644 test/unified-test-format/valid-fail/assertNumberConnectionsCheckedOut.json create mode 100644 test/unified-test-format/valid-fail/entity-find-cursor.json create mode 100644 test/unified-test-format/valid-fail/ignoreResultAndError.json create mode 100644 test/unified-test-format/valid-pass/assertNumberConnectionsCheckedOut.json create mode 100644 test/unified-test-format/valid-pass/entity-client-cmap-events.json create mode 100644 test/unified-test-format/valid-pass/entity-find-cursor.json create mode 100644 test/unified-test-format/valid-pass/expectedEventsForClient-eventType.json create mode 100644 test/unified-test-format/valid-pass/ignoreResultAndError.json diff --git a/pymongo/message.py b/pymongo/message.py index 79b56ec1a..0ca4ca71f 100644 --- a/pymongo/message.py +++ b/pymongo/message.py @@ -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 diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 0643a26d1..c72e83680 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -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) diff --git a/pymongo/network.py b/pymongo/network.py index 5d6439cdc..e575f0eb3 100644 --- a/pymongo/network.py +++ b/pymongo/network.py @@ -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()) diff --git a/test/command_monitoring/legacy/bulkWrite.json b/test/command_monitoring/legacy/bulkWrite.json index c5cd5a239..ca5a9a105 100644 --- a/test/command_monitoring/legacy/bulkWrite.json +++ b/test/command_monitoring/legacy/bulkWrite.json @@ -86,9 +86,7 @@ "$set": { "x": 333 } - }, - "upsert": false, - "multi": false + } } ], "ordered": true diff --git a/test/command_monitoring/legacy/insertMany.json b/test/command_monitoring/legacy/insertMany.json index 327da61b7..0becf928e 100644 --- a/test/command_monitoring/legacy/insertMany.json +++ b/test/command_monitoring/legacy/insertMany.json @@ -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" diff --git a/test/command_monitoring/legacy/updateMany.json b/test/command_monitoring/legacy/updateMany.json index 8e98fc92f..d82792fc4 100644 --- a/test/command_monitoring/legacy/updateMany.json +++ b/test/command_monitoring/legacy/updateMany.json @@ -51,8 +51,7 @@ "x": 1 } }, - "multi": true, - "upsert": false + "multi": true } ] }, @@ -106,8 +105,7 @@ "x": 1 } }, - "multi": true, - "upsert": false + "multi": true } ] }, diff --git a/test/command_monitoring/legacy/updateOne.json b/test/command_monitoring/legacy/updateOne.json index 565b74970..ba41dbb0c 100644 --- a/test/command_monitoring/legacy/updateOne.json +++ b/test/command_monitoring/legacy/updateOne.json @@ -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 + } } ] }, diff --git a/test/command_monitoring/unified/redacted-commands.json b/test/command_monitoring/unified/redacted-commands.json index c53f018d3..0f85dc3e9 100644 --- a/test/command_monitoring/unified/redacted-commands.json +++ b/test/command_monitoring/unified/redacted-commands.json @@ -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 + } } } } diff --git a/test/test_command_monitoring_legacy.py b/test/test_command_monitoring_legacy.py index 16bdf1c68..acebe3a23 100644 --- a/test/test_command_monitoring_legacy.py +++ b/test/test_command_monitoring_legacy.py @@ -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) diff --git a/test/unified-test-format/example-insertOne.json b/test/unified-test-format/example-insertOne.json deleted file mode 100644 index be41f9eac..000000000 --- a/test/unified-test-format/example-insertOne.json +++ /dev/null @@ -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 - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/entity-client-observeSensitiveCommands-type.json b/test/unified-test-format/invalid/entity-client-observeSensitiveCommands-type.json new file mode 100644 index 000000000..c5572f1fb --- /dev/null +++ b/test/unified-test-format/invalid/entity-client-observeSensitiveCommands-type.json @@ -0,0 +1,18 @@ +{ + "description": "entity-client-observeSensitiveCommands-type", + "schemaVersion": "1.5", + "createEntities": [ + { + "client": { + "id": "client0", + "observeSensitiveCommands": 0 + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutFailedEvent-reason-type.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutFailedEvent-reason-type.json new file mode 100644 index 000000000..110ce7869 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutFailedEvent-reason-type.json @@ -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 + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties.json new file mode 100644 index 000000000..f84e208d6 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-connectionCheckOutStartedEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckOutStartedEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedInEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedInEvent-additionalProperties.json new file mode 100644 index 000000000..56ffcdee7 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedInEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-connectionCheckedInEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckedInEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedOutEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedOutEvent-additionalProperties.json new file mode 100644 index 000000000..9b804aad0 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionCheckedOutEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-connectionCheckedOutEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCheckedOutEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionClosedEvent-reason-type.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionClosedEvent-reason-type.json new file mode 100644 index 000000000..053cd0b41 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionClosedEvent-reason-type.json @@ -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 + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionCreatedEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionCreatedEvent-additionalProperties.json new file mode 100644 index 000000000..c2edc3f6a --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionCreatedEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-connectionCreatedEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionCreatedEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-connectionReadyEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-connectionReadyEvent-additionalProperties.json new file mode 100644 index 000000000..994fb6331 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-connectionReadyEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-connectionReadyEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "connectionReadyEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-poolClearedEvent-hasServiceId-type.json b/test/unified-test-format/invalid/expectedCmapEvent-poolClearedEvent-hasServiceId-type.json new file mode 100644 index 000000000..5a1a25d46 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-poolClearedEvent-hasServiceId-type.json @@ -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" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-poolClosedEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-poolClosedEvent-additionalProperties.json new file mode 100644 index 000000000..c181707f4 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-poolClosedEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-poolClosedEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "poolClosedEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-poolCreatedEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-poolCreatedEvent-additionalProperties.json new file mode 100644 index 000000000..6aaa59a60 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-poolCreatedEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-poolCreatedEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "poolCreatedEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCmapEvent-poolReadyEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedCmapEvent-poolReadyEvent-additionalProperties.json new file mode 100644 index 000000000..66c803a5d --- /dev/null +++ b/test/unified-test-format/invalid/expectedCmapEvent-poolReadyEvent-additionalProperties.json @@ -0,0 +1,23 @@ +{ + "description": "expectedCmapEvent-poolReadyEvent-additionalProperties", + "schemaVersion": "1.3", + "tests": [ + { + "description": "foo", + "operations": [], + "expectEvents": [ + { + "client": "client0", + "eventType": "cmap", + "events": [ + { + "poolReadyEvent": { + "foo": "bar" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServiceId-type.json b/test/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServiceId-type.json new file mode 100644 index 000000000..5314dc9f8 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCommandEvent-commandFailedEvent-hasServiceId-type.json @@ -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" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServiceId-type.json b/test/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServiceId-type.json new file mode 100644 index 000000000..39ab925ef --- /dev/null +++ b/test/unified-test-format/invalid/expectedCommandEvent-commandStartedEvent-hasServiceId-type.json @@ -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" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServiceId-type.json b/test/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServiceId-type.json new file mode 100644 index 000000000..edc9d3cd7 --- /dev/null +++ b/test/unified-test-format/invalid/expectedCommandEvent-commandSucceededEvent-hasServiceId-type.json @@ -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" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedEvent-additionalProperties.json deleted file mode 100644 index 2c4f7d27e..000000000 --- a/test/unified-test-format/invalid/expectedEvent-additionalProperties.json +++ /dev/null @@ -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 - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandFailedEvent-commandName-type.json b/test/unified-test-format/invalid/expectedEvent-commandFailedEvent-commandName-type.json deleted file mode 100644 index ea6078faa..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandFailedEvent-commandName-type.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-additionalProperties.json b/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-additionalProperties.json deleted file mode 100644 index ee6eb5065..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-additionalProperties.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-command-type.json b/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-command-type.json deleted file mode 100644 index 4c9483caf..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-command-type.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-commandName-type.json b/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-commandName-type.json deleted file mode 100644 index a5a66096a..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-commandName-type.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-databaseName-type.json b/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-databaseName-type.json deleted file mode 100644 index dc040ec10..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandStartedEvent-databaseName-type.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-commandName-type.json b/test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-commandName-type.json deleted file mode 100644 index 4a20e906b..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-commandName-type.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-reply-type.json b/test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-reply-type.json deleted file mode 100644 index 546454275..000000000 --- a/test/unified-test-format/invalid/expectedEvent-commandSucceededEvent-reply-type.json +++ /dev/null @@ -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 - } - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-maxProperties.json b/test/unified-test-format/invalid/expectedEvent-maxProperties.json deleted file mode 100644 index f01441946..000000000 --- a/test/unified-test-format/invalid/expectedEvent-maxProperties.json +++ /dev/null @@ -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": {} - } - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEvent-minProperties.json b/test/unified-test-format/invalid/expectedEvent-minProperties.json deleted file mode 100644 index ebcc49489..000000000 --- a/test/unified-test-format/invalid/expectedEvent-minProperties.json +++ /dev/null @@ -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": [ - {} - ] - } - ] - } - ] - } - ] -} diff --git a/test/unified-test-format/invalid/expectedEventsForClient-eventType-enum.json b/test/unified-test-format/invalid/expectedEventsForClient-eventType-enum.json new file mode 100644 index 000000000..6e26cfaa7 --- /dev/null +++ b/test/unified-test-format/invalid/expectedEventsForClient-eventType-enum.json @@ -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": [] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedEventsForClient-eventType-type.json b/test/unified-test-format/invalid/expectedEventsForClient-eventType-type.json new file mode 100644 index 000000000..105bb001e --- /dev/null +++ b/test/unified-test-format/invalid/expectedEventsForClient-eventType-type.json @@ -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": [] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_cmap_eventType.json b/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_cmap_eventType.json new file mode 100644 index 000000000..b38021991 --- /dev/null +++ b/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_cmap_eventType.json @@ -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": {} + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_command_eventType.json b/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_command_eventType.json new file mode 100644 index 000000000..08446fe18 --- /dev/null +++ b/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_command_eventType.json @@ -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": {} + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_default_eventType.json b/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_default_eventType.json new file mode 100644 index 000000000..c31efbb8b --- /dev/null +++ b/test/unified-test-format/invalid/expectedEventsForClient-events_conflicts_with_default_eventType.json @@ -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": {} + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectError.json b/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectError.json new file mode 100644 index 000000000..b47e6be2a --- /dev/null +++ b/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectError.json @@ -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 + } + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectResult.json b/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectResult.json new file mode 100644 index 000000000..03c5a1dbb --- /dev/null +++ b/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_expectResult.json @@ -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 + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_saveResultAsEntity.json b/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_saveResultAsEntity.json new file mode 100644 index 000000000..6745dff2e --- /dev/null +++ b/test/unified-test-format/invalid/operation-ignoreResultAndError-conflicts_with_saveResultAsEntity.json @@ -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" + } + ] + } + ] +} diff --git a/test/unified-test-format/invalid/runOnRequirement-auth-type.json b/test/unified-test-format/invalid/runOnRequirement-auth-type.json new file mode 100644 index 000000000..e5475d079 --- /dev/null +++ b/test/unified-test-format/invalid/runOnRequirement-auth-type.json @@ -0,0 +1,15 @@ +{ + "description": "runOnRequirement-auth-type", + "schemaVersion": "1.3", + "runOnRequirements": [ + { + "auth": "foo" + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/runOnRequirement-serverless-enum.json b/test/unified-test-format/invalid/runOnRequirement-serverless-enum.json new file mode 100644 index 000000000..031fa539d --- /dev/null +++ b/test/unified-test-format/invalid/runOnRequirement-serverless-enum.json @@ -0,0 +1,15 @@ +{ + "description": "runOnRequirement-serverless-enum", + "schemaVersion": "1.4", + "runOnRequirements": [ + { + "serverless": "foo" + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/runOnRequirement-serverless-type.json b/test/unified-test-format/invalid/runOnRequirement-serverless-type.json new file mode 100644 index 000000000..1aa41712f --- /dev/null +++ b/test/unified-test-format/invalid/runOnRequirement-serverless-type.json @@ -0,0 +1,15 @@ +{ + "description": "runOnRequirement-serverless-type", + "schemaVersion": "1.4", + "runOnRequirements": [ + { + "serverless": 1234 + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-additionalProperties.json b/test/unified-test-format/invalid/storeEventsAsEntity-additionalProperties.json new file mode 100644 index 000000000..5357da8d8 --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-additionalProperties.json @@ -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": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-events-enum.json b/test/unified-test-format/invalid/storeEventsAsEntity-events-enum.json new file mode 100644 index 000000000..ee99a5538 --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-events-enum.json @@ -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": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-events-minItems.json b/test/unified-test-format/invalid/storeEventsAsEntity-events-minItems.json new file mode 100644 index 000000000..ddab042b1 --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-events-minItems.json @@ -0,0 +1,23 @@ +{ + "description": "storeEventsAsEntity-events-minItems", + "schemaVersion": "1.2", + "createEntities": [ + { + "client": { + "id": "client0", + "storeEventsAsEntities": [ + { + "id": "client0_events", + "events": [] + } + ] + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-events-required.json b/test/unified-test-format/invalid/storeEventsAsEntity-events-required.json new file mode 100644 index 000000000..90b45918c --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-events-required.json @@ -0,0 +1,22 @@ +{ + "description": "storeEventsAsEntity-events-required", + "schemaVersion": "1.2", + "createEntities": [ + { + "client": { + "id": "client0", + "storeEventsAsEntities": [ + { + "id": "client0_events" + } + ] + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-events-type.json b/test/unified-test-format/invalid/storeEventsAsEntity-events-type.json new file mode 100644 index 000000000..1b920ebd5 --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-events-type.json @@ -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": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-id-required.json b/test/unified-test-format/invalid/storeEventsAsEntity-id-required.json new file mode 100644 index 000000000..71387c531 --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-id-required.json @@ -0,0 +1,24 @@ +{ + "description": "storeEventsAsEntity-id-required", + "schemaVersion": "1.2", + "createEntities": [ + { + "client": { + "id": "client0", + "storeEventsAsEntities": [ + { + "events": [ + "CommandStartedEvent" + ] + } + ] + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/invalid/storeEventsAsEntity-id-type.json b/test/unified-test-format/invalid/storeEventsAsEntity-id-type.json new file mode 100644 index 000000000..4f52dc253 --- /dev/null +++ b/test/unified-test-format/invalid/storeEventsAsEntity-id-type.json @@ -0,0 +1,25 @@ +{ + "description": "storeEventsAsEntity-id-type", + "schemaVersion": "1.2", + "createEntities": [ + { + "client": { + "id": "client0", + "storeEventsAsEntities": [ + { + "id": 0, + "events": [ + "CommandStartedEvent" + ] + } + ] + } + } + ], + "tests": [ + { + "description": "foo", + "operations": [] + } + ] +} diff --git a/test/unified-test-format/valid-fail/assertNumberConnectionsCheckedOut.json b/test/unified-test-format/valid-fail/assertNumberConnectionsCheckedOut.json new file mode 100644 index 000000000..9799bb2f6 --- /dev/null +++ b/test/unified-test-format/valid-fail/assertNumberConnectionsCheckedOut.json @@ -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 + } + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-fail/entity-find-cursor.json b/test/unified-test-format/valid-fail/entity-find-cursor.json new file mode 100644 index 000000000..f4c5bcdf4 --- /dev/null +++ b/test/unified-test-format/valid-fail/entity-find-cursor.json @@ -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" + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-fail/ignoreResultAndError.json b/test/unified-test-format/valid-fail/ignoreResultAndError.json new file mode 100644 index 000000000..4457040b4 --- /dev/null +++ b/test/unified-test-format/valid-fail/ignoreResultAndError.json @@ -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 + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-pass/assertNumberConnectionsCheckedOut.json b/test/unified-test-format/valid-pass/assertNumberConnectionsCheckedOut.json new file mode 100644 index 000000000..a9fc063f3 --- /dev/null +++ b/test/unified-test-format/valid-pass/assertNumberConnectionsCheckedOut.json @@ -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 + } + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-pass/entity-client-cmap-events.json b/test/unified-test-format/valid-pass/entity-client-cmap-events.json new file mode 100644 index 000000000..3209033de --- /dev/null +++ b/test/unified-test-format/valid-pass/entity-client-cmap-events.json @@ -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": {} + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-pass/entity-find-cursor.json b/test/unified-test-format/valid-pass/entity-find-cursor.json new file mode 100644 index 000000000..85b8f69d7 --- /dev/null +++ b/test/unified-test-format/valid-pass/entity-find-cursor.json @@ -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" + } + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-pass/expectedEventsForClient-eventType.json b/test/unified-test-format/valid-pass/expectedEventsForClient-eventType.json new file mode 100644 index 000000000..fe308df96 --- /dev/null +++ b/test/unified-test-format/valid-pass/expectedEventsForClient-eventType.json @@ -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": {} + } + ] + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-pass/ignoreResultAndError.json b/test/unified-test-format/valid-pass/ignoreResultAndError.json new file mode 100644 index 000000000..2e9b1c58a --- /dev/null +++ b/test/unified-test-format/valid-pass/ignoreResultAndError.json @@ -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 + } + ] + } + ] +} diff --git a/test/unified-test-format/valid-pass/poc-crud.json b/test/unified-test-format/valid-pass/poc-crud.json index 7bb072de8..0790d9b78 100644 --- a/test/unified-test-format/valid-pass/poc-crud.json +++ b/test/unified-test-format/valid-pass/poc-crud.json @@ -323,7 +323,8 @@ "topologies": [ "replicaset", "sharded-replicaset" - ] + ], + "serverless": "forbid" } ], "operations": [ diff --git a/test/unified_format.py b/test/unified_format.py index e402e20ae..48a1e4940 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -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)