From 426640eb5e1960ba8c3c8085921cf08e9e2cb62a Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 13:04:25 -0400 Subject: [PATCH 1/9] sync change stream pre/post images spec tests - spec tests synced from https://github.com/mongodb/specifications/pull/1176 --- .../change-streams-pre_and_post_images.json | 826 ++++++++++++++++++ .../change-streams-pre_and_post_images.yml | 350 ++++++++ 2 files changed, 1176 insertions(+) create mode 100644 test/spec/change-streams/unified/change-streams-pre_and_post_images.json create mode 100644 test/spec/change-streams/unified/change-streams-pre_and_post_images.yml diff --git a/test/spec/change-streams/unified/change-streams-pre_and_post_images.json b/test/spec/change-streams/unified/change-streams-pre_and_post_images.json new file mode 100644 index 0000000000..b6f0e2c3bd --- /dev/null +++ b/test/spec/change-streams/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/test/spec/change-streams/unified/change-streams-pre_and_post_images.yml b/test/spec/change-streams/unified/change-streams-pre_and_post_images.yml new file mode 100644 index 0000000000..3dc6afab74 --- /dev/null +++ b/test/spec/change-streams/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" } From 60b36f8ff71f4d2820148cf1ce5e0c3afc7fe4aa Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 13:07:23 -0400 Subject: [PATCH 2/9] sync spec tests for collMod and create collection pre/post images - changes included in this PR - https://github.com/mongodb/specifications/pull/1206 - also skips the modifyCollection helper test because node doesn't implement a modify collection helper --- .../collection_management.spec.test.js | 7 +- .../createCollection-pre_and_post_images.json | 91 +++++++++++++++ .../createCollection-pre_and_post_images.yml | 49 ++++++++ .../modifyCollection-pre_and_post_images.json | 110 ++++++++++++++++++ .../modifyCollection-pre_and_post_images.yml | 57 +++++++++ 5 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 test/spec/collection-management/createCollection-pre_and_post_images.json create mode 100644 test/spec/collection-management/createCollection-pre_and_post_images.yml create mode 100644 test/spec/collection-management/modifyCollection-pre_and_post_images.json create mode 100644 test/spec/collection-management/modifyCollection-pre_and_post_images.yml diff --git a/test/integration/collection-management/collection_management.spec.test.js b/test/integration/collection-management/collection_management.spec.test.js index 5906110a7b..90168087c9 100644 --- a/test/integration/collection-management/collection_management.spec.test.js +++ b/test/integration/collection-management/collection_management.spec.test.js @@ -3,6 +3,9 @@ const { loadSpecTests } = require('../../spec/index'); const { runUnifiedSuite } = require('../../tools/unified-spec-runner/runner'); -describe('Collection management unified spec tests', function () { - runUnifiedSuite(loadSpecTests('collection-management')); +// The Node driver does not have a Collection.modifyCollection helper. +const SKIPPED_TESTS = ['modifyCollection to changeStreamPreAndPostImages enabled']; + +describe.only('Collection management unified spec tests', function () { + runUnifiedSuite(loadSpecTests('collection-management'), SKIPPED_TESTS); }); diff --git a/test/spec/collection-management/createCollection-pre_and_post_images.json b/test/spec/collection-management/createCollection-pre_and_post_images.json new file mode 100644 index 0000000000..fb4319d27d --- /dev/null +++ b/test/spec/collection-management/createCollection-pre_and_post_images.json @@ -0,0 +1,91 @@ +{ + "description": "createCollection-pre_and_post_images", + "schemaVersion": "1.0", + "runOnRequirements": [ + { + "minServerVersion": "6.0" + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "papi-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + } + ], + "tests": [ + { + "description": "createCollection with changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "dropCollection", + "object": "database0", + "arguments": { + "collection": "test" + } + }, + { + "name": "createCollection", + "object": "database0", + "arguments": { + "collection": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "databaseName": "papi-tests", + "collectionName": "test" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "drop": "test" + }, + "databaseName": "papi-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "create": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + }, + "databaseName": "papi-tests" + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/collection-management/createCollection-pre_and_post_images.yml b/test/spec/collection-management/createCollection-pre_and_post_images.yml new file mode 100644 index 0000000000..f8aa69ec4d --- /dev/null +++ b/test/spec/collection-management/createCollection-pre_and_post_images.yml @@ -0,0 +1,49 @@ +description: "createCollection-pre_and_post_images" + +schemaVersion: "1.0" + +runOnRequirements: + - minServerVersion: "6.0" + +createEntities: + - client: + id: &client0 client0 + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name papi-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name test + +tests: + - description: "createCollection with changeStreamPreAndPostImages enabled" + operations: + - name: dropCollection + object: *database0 + arguments: + collection: *collection0Name + - name: createCollection + object: *database0 + arguments: + collection: *collection0Name + changeStreamPreAndPostImages: { enabled: true } + - name: assertCollectionExists + object: testRunner + arguments: + databaseName: *database0Name + collectionName: *collection0Name + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + drop: *collection0Name + databaseName: *database0Name + - commandStartedEvent: + command: + create: *collection0Name + changeStreamPreAndPostImages: { enabled: true } + databaseName: *database0Name diff --git a/test/spec/collection-management/modifyCollection-pre_and_post_images.json b/test/spec/collection-management/modifyCollection-pre_and_post_images.json new file mode 100644 index 0000000000..2dab219c43 --- /dev/null +++ b/test/spec/collection-management/modifyCollection-pre_and_post_images.json @@ -0,0 +1,110 @@ +{ + "description": "modifyCollection-pre_and_post_images", + "schemaVersion": "1.0", + "runOnRequirements": [ + { + "minServerVersion": "6.0" + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "papi-tests" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "test" + } + } + ], + "tests": [ + { + "description": "modifyCollection to changeStreamPreAndPostImages enabled", + "operations": [ + { + "name": "dropCollection", + "object": "database0", + "arguments": { + "collection": "test" + } + }, + { + "name": "createCollection", + "object": "database0", + "arguments": { + "collection": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "databaseName": "papi-tests", + "collectionName": "test" + } + }, + { + "name": "modifyCollection", + "object": "database0", + "arguments": { + "collection": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "command": { + "drop": "test" + }, + "databaseName": "papi-tests" + } + }, + { + "commandStartedEvent": { + "command": { + "create": "test", + "changeStreamPreAndPostImages": { + "enabled": false + } + } + } + }, + { + "commandStartedEvent": { + "command": { + "collMod": "test", + "changeStreamPreAndPostImages": { + "enabled": true + } + } + } + } + ] + } + ] + } + ] +} diff --git a/test/spec/collection-management/modifyCollection-pre_and_post_images.yml b/test/spec/collection-management/modifyCollection-pre_and_post_images.yml new file mode 100644 index 0000000000..1c26d5b6af --- /dev/null +++ b/test/spec/collection-management/modifyCollection-pre_and_post_images.yml @@ -0,0 +1,57 @@ +description: "modifyCollection-pre_and_post_images" + +schemaVersion: "1.0" + +runOnRequirements: + - minServerVersion: "6.0" + +createEntities: + - client: + id: &client0 client0 + observeEvents: [ commandStartedEvent ] + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name papi-tests + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name test + +tests: + - description: "modifyCollection to changeStreamPreAndPostImages enabled" + operations: + - name: dropCollection + object: *database0 + arguments: + collection: *collection0Name + - name: createCollection + object: *database0 + arguments: + collection: *collection0Name + changeStreamPreAndPostImages: { enabled: false } + - name: assertCollectionExists + object: testRunner + arguments: + databaseName: *database0Name + collectionName: *collection0Name + - name: modifyCollection + object: *database0 + arguments: + collection: *collection0Name + changeStreamPreAndPostImages: { enabled: true } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + command: + drop: *collection0Name + databaseName: *database0Name + - commandStartedEvent: + command: + create: *collection0Name + changeStreamPreAndPostImages: { enabled: false } + - commandStartedEvent: + command: + collMod: *collection0Name + changeStreamPreAndPostImages: { enabled: true } From eff7494ce80aa480c477cf6dad2503f6ca1b9669 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 13:09:52 -0400 Subject: [PATCH 3/9] remove .only --- .../collection-management/collection_management.spec.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/collection-management/collection_management.spec.test.js b/test/integration/collection-management/collection_management.spec.test.js index 90168087c9..88db4d6a0a 100644 --- a/test/integration/collection-management/collection_management.spec.test.js +++ b/test/integration/collection-management/collection_management.spec.test.js @@ -6,6 +6,6 @@ const { runUnifiedSuite } = require('../../tools/unified-spec-runner/runner'); // The Node driver does not have a Collection.modifyCollection helper. const SKIPPED_TESTS = ['modifyCollection to changeStreamPreAndPostImages enabled']; -describe.only('Collection management unified spec tests', function () { +describe('Collection management unified spec tests', function () { runUnifiedSuite(loadSpecTests('collection-management'), SKIPPED_TESTS); }); From fb949bc0c157c7c00929c8af4a803f06083f3896 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 13:32:50 -0400 Subject: [PATCH 4/9] add pre/post image functionality to change streams --- src/change_stream.ts | 39 +++++++++++++++++++++++------ src/operations/create_collection.ts | 5 ++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/change_stream.ts b/src/change_stream.ts index 86aafa6373..968383121f 100644 --- a/src/change_stream.ts +++ b/src/change_stream.ts @@ -50,7 +50,8 @@ const CHANGE_STREAM_OPTIONS = [ 'resumeAfter', 'startAfter', 'startAtOperationTime', - 'fullDocument' + 'fullDocument', + 'fullDocumentBeforeChange' ] as const; const CURSOR_OPTIONS = [ @@ -131,11 +132,35 @@ export type ChangeStreamAggregateRawResult = { */ export interface ChangeStreamOptions extends AggregateOptions { /** - * Allowed values: 'updateLookup'. When set to 'updateLookup', - * the change stream 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. + * Allowed values: 'updateLookup', 'whenAvailable', 'required'. + * + * 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. */ fullDocument?: string; + + /** + * 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. + */ + fullDocumentBeforeChange?: string; /** The maximum amount of time for the server to wait on new documents to satisfy a change stream query. */ maxAwaitTimeMS?: number; /** @@ -230,9 +255,9 @@ export interface ChangeStreamUpdateDocument operationType: 'update'; /** * This is only set if `fullDocument` is set to `'updateLookup'` - * The fullDocument document represents the most current majority-committed version of the updated document. - * The fullDocument document may vary from the document at the time of the update operation depending on the - * number of interleaving majority-committed operations that occur between the update operation and the document lookup. + * 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. */ fullDocument?: TSchema; /** Contains a description of updated and removed fields in this operation */ diff --git a/src/operations/create_collection.ts b/src/operations/create_collection.ts index 8a9e02add7..1d1abdde18 100644 --- a/src/operations/create_collection.ts +++ b/src/operations/create_collection.ts @@ -91,6 +91,11 @@ export interface CreateCollectionOptions extends CommandOperationOptions { expireAfterSeconds?: number; /** @experimental */ encryptedFields?: Document; + /** + * If set, enables pre-update and post-update document events to be included for any + * change streams that listen on this collection. + */ + changeStreamPreAndPostImages?: { enabled: true }; } /** @internal */ From fcc096aac2999cda9e0d539c2fb9a1e4100d44ee Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 14:05:45 -0400 Subject: [PATCH 5/9] add fullDocumentBeforeChange to relevant changestream events --- src/change_stream.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/change_stream.ts b/src/change_stream.ts index 968383121f..8529f5d77d 100644 --- a/src/change_stream.ts +++ b/src/change_stream.ts @@ -264,6 +264,14 @@ export interface ChangeStreamUpdateDocument updateDescription: UpdateDescription; /** Namespace the update event occured on */ ns: ChangeStreamNameSpace; + /** + * 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; } /** @@ -279,6 +287,14 @@ export interface ChangeStreamReplaceDocument operationType: 'delete'; /** Namespace the delete event occured on */ ns: ChangeStreamNameSpace; + /** + * 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; } /** From 6ea29eab2a3de8d4e7e7c510879d9a346d2eb466 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 14:11:23 -0400 Subject: [PATCH 6/9] sync clustered index test changes --- test/spec/collection-management/clustered-indexes.json | 7 ++++--- test/spec/collection-management/clustered-indexes.yml | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/spec/collection-management/clustered-indexes.json b/test/spec/collection-management/clustered-indexes.json index 3910f4d4f8..739d0fd8b6 100644 --- a/test/spec/collection-management/clustered-indexes.json +++ b/test/spec/collection-management/clustered-indexes.json @@ -1,9 +1,10 @@ { "description": "clustered-indexes", - "schemaVersion": "1.0", + "schemaVersion": "1.4", "runOnRequirements": [ { - "minServerVersion": "5.3" + "minServerVersion": "5.3", + "serverless": "forbid" } ], "createEntities": [ @@ -173,4 +174,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/test/spec/collection-management/clustered-indexes.yml b/test/spec/collection-management/clustered-indexes.yml index 6e3163305d..d4a69eab51 100644 --- a/test/spec/collection-management/clustered-indexes.yml +++ b/test/spec/collection-management/clustered-indexes.yml @@ -1,9 +1,10 @@ description: "clustered-indexes" -schemaVersion: "1.0" +schemaVersion: "1.4" runOnRequirements: - minServerVersion: "5.3" + serverless: forbid createEntities: - client: @@ -91,4 +92,4 @@ tests: name: *index0Name clustered: true unique: true - v: { $$type: [ int, long ] } \ No newline at end of file + v: { $$type: [ int, long ] } From 71c89bff933a281304ec7723d8421040adc5b4b7 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Tue, 17 May 2022 14:20:22 -0400 Subject: [PATCH 7/9] skip serverless tests for pre/post images tests --- .../createCollection-pre_and_post_images.json | 5 +++-- .../createCollection-pre_and_post_images.yml | 3 ++- .../modifyCollection-pre_and_post_images.json | 5 +++-- .../modifyCollection-pre_and_post_images.yml | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/spec/collection-management/createCollection-pre_and_post_images.json b/test/spec/collection-management/createCollection-pre_and_post_images.json index fb4319d27d..f488deacd8 100644 --- a/test/spec/collection-management/createCollection-pre_and_post_images.json +++ b/test/spec/collection-management/createCollection-pre_and_post_images.json @@ -1,9 +1,10 @@ { "description": "createCollection-pre_and_post_images", - "schemaVersion": "1.0", + "schemaVersion": "1.4", "runOnRequirements": [ { - "minServerVersion": "6.0" + "minServerVersion": "6.0", + "serverless": "forbid" } ], "createEntities": [ diff --git a/test/spec/collection-management/createCollection-pre_and_post_images.yml b/test/spec/collection-management/createCollection-pre_and_post_images.yml index f8aa69ec4d..100e9a1d7c 100644 --- a/test/spec/collection-management/createCollection-pre_and_post_images.yml +++ b/test/spec/collection-management/createCollection-pre_and_post_images.yml @@ -1,9 +1,10 @@ description: "createCollection-pre_and_post_images" -schemaVersion: "1.0" +schemaVersion: "1.4" runOnRequirements: - minServerVersion: "6.0" + serverless: forbid createEntities: - client: diff --git a/test/spec/collection-management/modifyCollection-pre_and_post_images.json b/test/spec/collection-management/modifyCollection-pre_and_post_images.json index 2dab219c43..8026faeb17 100644 --- a/test/spec/collection-management/modifyCollection-pre_and_post_images.json +++ b/test/spec/collection-management/modifyCollection-pre_and_post_images.json @@ -1,9 +1,10 @@ { "description": "modifyCollection-pre_and_post_images", - "schemaVersion": "1.0", + "schemaVersion": "1.4", "runOnRequirements": [ { - "minServerVersion": "6.0" + "minServerVersion": "6.0", + "serverless": "forbid" } ], "createEntities": [ diff --git a/test/spec/collection-management/modifyCollection-pre_and_post_images.yml b/test/spec/collection-management/modifyCollection-pre_and_post_images.yml index 1c26d5b6af..75675bf2c7 100644 --- a/test/spec/collection-management/modifyCollection-pre_and_post_images.yml +++ b/test/spec/collection-management/modifyCollection-pre_and_post_images.yml @@ -1,9 +1,10 @@ description: "modifyCollection-pre_and_post_images" -schemaVersion: "1.0" +schemaVersion: "1.4" runOnRequirements: - minServerVersion: "6.0" + serverless: forbid createEntities: - client: From 0c0fe4947f4aded3ee23a87ad37da7d5c7b35a7d Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 18 May 2022 14:02:49 -0400 Subject: [PATCH 8/9] adjust Document in schema to TSchema --- src/change_stream.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/change_stream.ts b/src/change_stream.ts index 8529f5d77d..4997206df0 100644 --- a/src/change_stream.ts +++ b/src/change_stream.ts @@ -271,7 +271,7 @@ export interface ChangeStreamUpdateDocument * when creating the change stream. If 'whenAvailable' was specified but the * pre-image is unavailable, this will be explicitly set to null. */ - fullDocumentBeforeChange?: Document; + fullDocumentBeforeChange?: TSchema; } /** @@ -294,7 +294,7 @@ export interface ChangeStreamReplaceDocument * when creating the change stream. If 'whenAvailable' was specified but the * pre-image is unavailable, this will be explicitly set to null. */ - fullDocumentBeforeChange?: Document; + fullDocumentBeforeChange?: TSchema; } /** From 8a1aa41fa9e6c384f54950b80b90bfd93e95d0a6 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 18 May 2022 14:05:40 -0400 Subject: [PATCH 9/9] remove type restriction on create collection options --- src/operations/create_collection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/create_collection.ts b/src/operations/create_collection.ts index 1d1abdde18..6da9bf0a6a 100644 --- a/src/operations/create_collection.ts +++ b/src/operations/create_collection.ts @@ -95,7 +95,7 @@ export interface CreateCollectionOptions extends CommandOperationOptions { * If set, enables pre-update and post-update document events to be included for any * change streams that listen on this collection. */ - changeStreamPreAndPostImages?: { enabled: true }; + changeStreamPreAndPostImages?: { enabled: boolean }; } /** @internal */