From 3d43d9420c12c2f47d614fc6f2546cf80742817e Mon Sep 17 00:00:00 2001 From: Ian Boros Date: Wed, 18 Apr 2018 12:21:09 -0400 Subject: SERVER-34032 add tests for resuming using an "invalidate" resumeToken --- ...nge_streams_sharded_collections_passthrough.yml | 3 ++ ...ole_cluster_sharded_collections_passthrough.yml | 3 ++ ...ms_whole_db_sharded_collections_passthrough.yml | 3 ++ .../change_stream_rename_resumability.js | 44 ++++++++++++++++++++++ .../change_streams/change_stream_rename_target.js | 40 ++++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 jstests/change_streams/change_stream_rename_resumability.js create mode 100644 jstests/change_streams/change_stream_rename_target.js diff --git a/buildscripts/resmokeconfig/suites/change_streams_sharded_collections_passthrough.yml b/buildscripts/resmokeconfig/suites/change_streams_sharded_collections_passthrough.yml index 4c7c48dbaf1..17992685444 100644 --- a/buildscripts/resmokeconfig/suites/change_streams_sharded_collections_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/change_streams_sharded_collections_passthrough.yml @@ -6,6 +6,9 @@ selector: exclude_files: # Exercises an internal detail of mongos<->mongod communication. Not expected to work on mongos. - jstests/change_streams/report_latest_observed_oplog_timestamp.js + # Renames a collection, which is not allowed for sharded collections. + - jstests/change_streams/change_stream_rename_target.js + - jstests/change_streams/change_stream_rename_resumability.js exclude_with_any_tags: ## # The next three tags correspond to the special errors thrown by the diff --git a/buildscripts/resmokeconfig/suites/change_streams_whole_cluster_sharded_collections_passthrough.yml b/buildscripts/resmokeconfig/suites/change_streams_whole_cluster_sharded_collections_passthrough.yml index 6f659d668c9..c6c10ecb937 100644 --- a/buildscripts/resmokeconfig/suites/change_streams_whole_cluster_sharded_collections_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/change_streams_whole_cluster_sharded_collections_passthrough.yml @@ -6,6 +6,9 @@ selector: exclude_files: # Exercises an internal detail of mongos<->mongod communication. Not expected to work on mongos. - jstests/change_streams/report_latest_observed_oplog_timestamp.js + # These tests rename a collection, which is not allowed for sharded collections. + - jstests/change_streams/change_stream_rename_target.js + - jstests/change_streams/change_stream_rename_resumability.js exclude_with_any_tags: ## # The next three tags correspond to the special errors thrown by the diff --git a/buildscripts/resmokeconfig/suites/change_streams_whole_db_sharded_collections_passthrough.yml b/buildscripts/resmokeconfig/suites/change_streams_whole_db_sharded_collections_passthrough.yml index e63ee3cd2a9..d5b1d538c71 100644 --- a/buildscripts/resmokeconfig/suites/change_streams_whole_db_sharded_collections_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/change_streams_whole_db_sharded_collections_passthrough.yml @@ -6,6 +6,9 @@ selector: exclude_files: # Exercises an internal detail of mongos<->mongod communication. Not expected to work on mongos. - jstests/change_streams/report_latest_observed_oplog_timestamp.js + # These tests rename a collection, which is not allowed for sharded collections. + - jstests/change_streams/change_stream_rename_target.js + - jstests/change_streams/change_stream_rename_resumability.js exclude_with_any_tags: ## # The next three tags correspond to the special errors thrown by the diff --git a/jstests/change_streams/change_stream_rename_resumability.js b/jstests/change_streams/change_stream_rename_resumability.js new file mode 100644 index 00000000000..e3d7f5191c5 --- /dev/null +++ b/jstests/change_streams/change_stream_rename_resumability.js @@ -0,0 +1,44 @@ +// Tests resuming on a change stream that was invalidated due to rename. + +(function() { + "use strict"; + + load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection. + + const coll = assertDropAndRecreateCollection(db, "change_stream_invalidate_resumability"); + + // Drop the collection we'll rename to _before_ starting the changeStream, so that we don't + // get accidentally an invalidate when running on the whole DB or cluster. + assertDropCollection(db, coll.getName() + "_renamed"); + + const cursor = coll.watch(); + assert(!cursor.hasNext()); + + // Create an 'insert' oplog entry. + assert.writeOK(coll.insert({_id: 1})); + + assert.commandWorked(coll.renameCollection(coll.getName() + "_renamed")); + + // Insert another document after the rename. + assert.commandWorked(coll.insert({_id: 2})); + + // We should get 2 oplog entries of type insert and invalidate. + assert.soon(() => cursor.hasNext()); + let change = cursor.next(); + assert.eq(change.operationType, "insert", tojson(change)); + assert.docEq(change.fullDocument, {_id: 1}); + + assert.soon(() => cursor.hasNext()); + change = cursor.next(); + assert.eq(change.operationType, "invalidate", tojson(change)); + assert(cursor.isExhausted()); + + // Try resuming from the invalidate. + const resumeCursor = coll.watch([], {resumeAfter: change._id}); + + // Be sure we can see the change after the rename. + assert.soon(() => resumeCursor.hasNext()); + change = resumeCursor.next(); + assert.eq(change.operationType, "insert", tojson(change)); + assert.docEq(change.fullDocument, {_id: 2}); +}()); diff --git a/jstests/change_streams/change_stream_rename_target.js b/jstests/change_streams/change_stream_rename_target.js new file mode 100644 index 00000000000..3ff1b4289f0 --- /dev/null +++ b/jstests/change_streams/change_stream_rename_target.js @@ -0,0 +1,40 @@ +// Tests that watching a collection which another collection is renamed _to_ causes an invalidate. +(function() { + "use strict"; + + load("jstests/libs/collection_drop_recreate.js"); // For assert[Drop|Create]Collection. + + const testDB = db.getSiblingDB(jsTestName()); + + // Write a document to the collection and test that the change stream returns it + // and getMore command closes the cursor afterwards. + const collName1 = "change_stream_rename_1"; + const collName2 = "change_stream_rename_2"; + let coll = assertDropAndRecreateCollection(testDB, collName1); + assertDropCollection(testDB, collName2); + assertDropCollection(testDB, collName2); + + // Watch the collection which doesn't exist yet. + let aggCursor = testDB[collName2].watch(); + + // Insert something to the collection we're _not_ watching. + assert.writeOK(coll.insert({_id: 1})); + + assert.eq(aggCursor.hasNext(), false); + + // Now rename the collection TO the collection that's being watched. This should invalidate the + // change stream. + assert.commandWorked(coll.renameCollection(collName2)); + assert.soon(() => aggCursor.hasNext()); + let invalidate = aggCursor.next(); + assert.eq(invalidate.operationType, "invalidate"); + assert(aggCursor.isExhausted()); + + // Do another insert. + assert.writeOK(testDB[collName2].insert({_id: 2})); + + let cursor = testDB[collName2].watch([], {resumeAfter: invalidate._id}); + assert.soon(() => cursor.hasNext()); + let change = cursor.next(); + assert.docEq(change.fullDocument, {_id: 2}); +}()); -- cgit v1.2.1