diff --git a/source/change-streams/change-streams.rst b/source/change-streams/change-streams.rst index 2722008ad3..31b1570d9b 100644 --- a/source/change-streams/change-streams.rst +++ b/source/change-streams/change-streams.rst @@ -9,8 +9,8 @@ Change Streams :Status: Accepted :Type: Standards :Minimum Server Version: 3.6 -:Last Modified: 2022-03-25 -:Version: 1.13.1 +:Last Modified: 2022-04-13 +:Version: 1.14 .. contents:: @@ -175,20 +175,34 @@ If an aggregate command with a ``$changeStream`` stage completes successfully, t updateDescription: Optional; /** - * Always present for operations of type ‘insert’ and ‘replace’. Also - * present for operations of type ‘update’ if the user has specified ‘updateLookup’ - * in the ‘fullDocument’ arguments to the ‘$changeStream’ stage. + * Always present for operations of type 'insert' and 'replace'. Also + * present for operations of type 'update' if the user has specified + * 'updateLookup' for the 'fullDocument' option when creating the change + * stream. * - * For operations of type ‘insert’ and ‘replace’, this key will contain the - * document being inserted, or the new version of the document that is replacing - * the existing document, respectively. + * For operations of type 'insert' and 'replace', this key will contain the + * document being inserted or the new version of the document that is + * replacing the existing document, respectively. * - * For operations of type ‘update’, this key will contain a copy of the full + * For operations of type 'update', this key will contain a copy of the full * version of the document from some point after the update occurred. If the * document was deleted since the updated happened, it will be null. + * + * Contains the point-in-time post-image of the modified document if the + * post-image is available and either 'required' or 'whenAvailable' was + * specified for the 'fullDocument' option when creating the change stream. + * A post-image is always available for 'insert' and 'replace' events. */ fullDocument: Document | null; + /** + * Contains the pre-image of the modified or deleted document if the + * pre-image is available for the change event and either 'required' or + * 'whenAvailable' was specified for the 'fullDocumentBeforeChange' option + * when creating the change stream. If 'whenAvailable' was specified but the + * pre-image is unavailable, this will be explicitly set to null. + */ + fullDocumentBeforeChange: Document | null; } class UpdateDescription { @@ -347,16 +361,52 @@ Driver API class ChangeStreamOptions { /** - * Allowed values: ‘updateLookup’. When set to ‘updateLookup’, the change notification - * for partial updates will include both a delta describing the changes to the document, - * as well as a copy of the entire document that was changed from some time after the - * change occurred. The default is to not send a value. - * For forward compatibility, a driver MUST NOT raise an error when a user provides an - * unknown value. The driver relies on the server to validate this option. + * Allowed values: 'default', 'updateLookup', 'whenAvailable', 'required'. + * + * The default is to not send a value, which is equivalent to 'default'. By + * default, the change notification for partial updates will include a delta + * describing the changes to the document. + * + * When set to 'updateLookup', the change notification for partial updates + * will include both a delta describing the changes to the document as well + * as a copy of the entire document that was changed from some time after + * the change occurred. + * + * When set to 'whenAvailable', configures the change stream to return the + * post-image of the modified document for replace and update change events + * if the post-image for this event is available. + * + * When set to 'required', the same behavior as 'whenAvailable' except that + * an error is raised if the post-image is not available. + * + * For forward compatibility, a driver MUST NOT raise an error when a user + * provides an unknown value. The driver relies on the server to validate + * this option. + * * @note this is an option of the `$changeStream` pipeline stage. */ fullDocument: Optional; + /** + * Allowed values: 'whenAvailable', 'required', 'off'. + * + * The default is to not send a value, which is equivalent to 'off'. + * + * When set to 'whenAvailable', configures the change stream to return the + * pre-image of the modified document for replace, update, and delete change + * events if it is available. + * + * When set to 'required', the same behavior as 'whenAvailable' except that + * an error is raised if the pre-image is not available. + * + * For forward compatibility, a driver MUST NOT raise an error when a user + * provides an unknown value. The driver relies on the server to validate + * this option. + * + * @note this is an option of the `$changeStream` pipeline stage. + */ + fullDocumentBeforeChange: Optional; + /** * Specifies the logical starting point for the new change stream. * @@ -946,3 +996,6 @@ Changelog +------------+------------------------------------------------------------+ | 2022-03-25 | Do not error when parsing change stream event documents. | +------------+------------------------------------------------------------+ +| 2022-04-13 | Support returning point-in-time pre and post-images with | +| | ``fullDocumentBeforeChange`` and ``fullDocument``. | ++------------+------------------------------------------------------------+ diff --git a/source/change-streams/tests/unified/change-streams-pre_and_post_images.json b/source/change-streams/tests/unified/change-streams-pre_and_post_images.json new file mode 100644 index 0000000000..b6f0e2c3bd --- /dev/null +++ b/source/change-streams/tests/unified/change-streams-pre_and_post_images.json @@ -0,0 +1,826 @@ +{ + "description": "change-streams-pre_and_post_images", + "schemaVersion": "1.0", + "runOnRequirements": [ + { + "minServerVersion": "6.0.0", + "topologies": [ + "replicaset", + "sharded-replicaset", + "load-balanced" + ] + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ], + "ignoreCommandMonitoringEvents": [ + "collMod", + "insert", + "update", + "getMore", + "killCursors" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "change-stream-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + } + ], + "initialData": [ + { + "collectionName": "test", + "databaseName": "change-stream-tests", + "documents": [ + { + "_id": 1 + } + ] + } + ], + "tests": [ + { + "description": "fullDocument:whenAvailable with changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocument": "whenAvailable" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocument": { + "_id": 1, + "x": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocument": "whenAvailable" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocument:whenAvailable with changeStreamPreAndPostImages disabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocument": "whenAvailable" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocument": null + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocument": "whenAvailable" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocument:required with changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocument": "required" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocument": { + "_id": 1, + "x": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocument": "required" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocument:required with changeStreamPreAndPostImages disabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocument": "required" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectError": { + "isClientError": false + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocument": "required" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocumentBeforeChange:whenAvailable with changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocumentBeforeChange": "whenAvailable" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocumentBeforeChange": { + "_id": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocumentBeforeChange": "whenAvailable" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocumentBeforeChange:whenAvailable with changeStreamPreAndPostImages disabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocumentBeforeChange": "whenAvailable" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocumentBeforeChange": null + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocumentBeforeChange": "whenAvailable" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocumentBeforeChange:required with changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocumentBeforeChange": "required" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocumentBeforeChange": { + "_id": 1 + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocumentBeforeChange": "required" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocumentBeforeChange:required with changeStreamPreAndPostImages disabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocumentBeforeChange": "required" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectError": { + "isClientError": false + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocumentBeforeChange": "required" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocumentBeforeChange:off with changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocumentBeforeChange": "off" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocumentBeforeChange": { + "$$exists": false + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocumentBeforeChange": "off" + } + } + ] + } + } + } + ] + } + ] + }, + { + "description": "fullDocumentBeforeChange:off with changeStreamPreAndPostImages disabled", + "operations": [ + { + "name": "runCommand", + "object": "database0", + "arguments": { + "commandName": "collMod", + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + } + }, + { + "name": "createChangeStream", + "object": "collection0", + "arguments": { + "pipeline": [], + "fullDocumentBeforeChange": "off" + }, + "saveResultAsEntity": "changeStream0" + }, + { + "name": "updateOne", + "object": "collection0", + "arguments": { + "filter": { + "_id": 1 + }, + "update": { + "$set": { + "x": 1 + } + } + } + }, + { + "name": "iterateUntilDocumentOrError", + "object": "changeStream0", + "expectResult": { + "operationType": "update", + "ns": { + "db": "change-stream-tests", + "coll": "test" + }, + "updateDescription": { + "$$type": "object" + }, + "fullDocumentBeforeChange": { + "$$exists": false + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "aggregate": "test", + "pipeline": [ + { + "$changeStream": { + "fullDocumentBeforeChange": "off" + } + } + ] + } + } + } + ] + } + ] + } + ] +} diff --git a/source/change-streams/tests/unified/change-streams-pre_and_post_images.yml b/source/change-streams/tests/unified/change-streams-pre_and_post_images.yml new file mode 100644 index 0000000000..3dc6afab74 --- /dev/null +++ b/source/change-streams/tests/unified/change-streams-pre_and_post_images.yml @@ -0,0 +1,350 @@ +description: "change-streams-pre_and_post_images" + +schemaVersion: "1.3" + +runOnRequirements: + - minServerVersion: "6.0.0" + topologies: [ replicaset, sharded-replicaset, load-balanced ] + +createEntities: + - client: + id: &client0 client0 + observeEvents: [ commandStartedEvent ] + ignoreCommandMonitoringEvents: [ collMod, insert, update, getMore, killCursors ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name change-stream-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name test + +initialData: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - { _id: 1 } + +tests: + - description: "fullDocument:whenAvailable with changeStreamPreAndPostImages enabled" + operations: + - name: runCommand + object: *database0 + arguments: &enablePreAndPostImages + commandName: collMod + command: + collMod: *collection0Name + changeStreamPreAndPostImages: { enabled: true } + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocument: "whenAvailable" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocument: { _id: 1, x: 1 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocument: "whenAvailable" } + + - description: "fullDocument:whenAvailable with changeStreamPreAndPostImages disabled" + operations: + - name: runCommand + object: *database0 + arguments: &disablePreAndPostImages + commandName: collMod + command: + collMod: *collection0Name + changeStreamPreAndPostImages: { enabled: false } + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocument: "whenAvailable" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocument: null + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocument: "whenAvailable" } + + - description: "fullDocument:required with changeStreamPreAndPostImages enabled" + operations: + - name: runCommand + object: *database0 + arguments: *enablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocument: "required" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocument: { _id: 1, x: 1 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocument: "required" } + + - description: "fullDocument:required with changeStreamPreAndPostImages disabled" + operations: + - name: runCommand + object: *database0 + arguments: *disablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocument: "required" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectError: + isClientError: false + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocument: "required" } + + - description: "fullDocumentBeforeChange:whenAvailable with changeStreamPreAndPostImages enabled" + operations: + - name: runCommand + object: *database0 + arguments: *enablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocumentBeforeChange: "whenAvailable" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocumentBeforeChange: { _id: 1 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocumentBeforeChange: "whenAvailable" } + + - description: "fullDocumentBeforeChange:whenAvailable with changeStreamPreAndPostImages disabled" + operations: + - name: runCommand + object: *database0 + arguments: *disablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocumentBeforeChange: "whenAvailable" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocumentBeforeChange: null + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocumentBeforeChange: "whenAvailable" } + + - description: "fullDocumentBeforeChange:required with changeStreamPreAndPostImages enabled" + operations: + - name: runCommand + object: *database0 + arguments: *enablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocumentBeforeChange: "required" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocumentBeforeChange: { _id: 1 } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocumentBeforeChange: "required" } + + - description: "fullDocumentBeforeChange:required with changeStreamPreAndPostImages disabled" + operations: + - name: runCommand + object: *database0 + arguments: *disablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocumentBeforeChange: "required" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectError: + isClientError: false + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocumentBeforeChange: "required" } + + - description: "fullDocumentBeforeChange:off with changeStreamPreAndPostImages enabled" + operations: + - name: runCommand + object: *database0 + arguments: *enablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocumentBeforeChange: "off" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocumentBeforeChange: { $$exists: false } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocumentBeforeChange: "off" } + + - description: "fullDocumentBeforeChange:off with changeStreamPreAndPostImages disabled" + operations: + - name: runCommand + object: *database0 + arguments: *disablePreAndPostImages + - name: createChangeStream + object: *collection0 + arguments: + pipeline: [] + fullDocumentBeforeChange: "off" + saveResultAsEntity: &changeStream0 changeStream0 + - name: updateOne + object: *collection0 + arguments: + filter: { _id: 1 } + update: { $set: { x: 1 }} + - name: iterateUntilDocumentOrError + object: *changeStream0 + expectResult: + operationType: "update" + ns: { db: *database0Name, coll: *collection0Name } + updateDescription: { $$type: "object" } + fullDocumentBeforeChange: { $$exists: false } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + aggregate: *collection0Name + pipeline: + - $changeStream: { fullDocumentBeforeChange: "off" } diff --git a/source/unified-test-format/tests/Makefile b/source/unified-test-format/tests/Makefile index ab393d9934..9e8100402c 100644 --- a/source/unified-test-format/tests/Makefile +++ b/source/unified-test-format/tests/Makefile @@ -2,7 +2,7 @@ SCHEMA=../schema-1.7.json .PHONY: all invalid valid-fail valid-pass versioned-api load-balancers gridfs transactions crud collection-management sessions command-monitoring HAS_AJV -all: invalid valid-fail valid-pass versioned-api load-balancers gridfs transactions crud collection-management sessions command-monitoring +all: invalid valid-fail valid-pass versioned-api load-balancers gridfs transactions change-streams crud collection-management sessions command-monitoring invalid: HAS_AJV @# Redirect stdout to hide expected validation errors @@ -26,6 +26,9 @@ gridfs: HAS_AJV transactions: HAS_AJV @ajv test -s $(SCHEMA) -d "../../transactions/tests/unified/*.yml" --valid +change-streams: HAS_AJV + @ajv test -s $(SCHEMA) -d "../../change-streams/tests/unified/*.yml" --valid + crud: HAS_AJV @ajv test -s $(SCHEMA) -d "../../crud/tests/unified/*.yml" --valid