summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Fuschetto <antonio.fuschetto@mongodb.com>2022-05-12 10:52:56 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-05-12 11:19:46 +0000
commit5b9077c974c7e1ca78c7d1795761817cc60e6bdb (patch)
treee63190ed8aef5ff2156197bdbec52fd2c0d84ec3
parent8c9ceb09f28bdecbfc896994f45f9a69f1011eca (diff)
downloadmongo-5b9077c974c7e1ca78c7d1795761817cc60e6bdb.tar.gz
SERVER-66312 Tests on batched operations do not involve orphaned documents
-rw-r--r--jstests/sharding/change_stream_no_orphans.js306
1 files changed, 128 insertions, 178 deletions
diff --git a/jstests/sharding/change_stream_no_orphans.js b/jstests/sharding/change_stream_no_orphans.js
index 98d5fd1bcd6..ce4d35c847c 100644
--- a/jstests/sharding/change_stream_no_orphans.js
+++ b/jstests/sharding/change_stream_no_orphans.js
@@ -1,13 +1,12 @@
/**
* Verify that write operations on orphaned documents (1) do not show up unexpected events in change
- * streams and (2) have no effect on the persisted data.
+ * streams and (2) have a certain behavior on the persisted data.
*
* The behavior is tested in the following scenarios:
- * - Direct operations to shard on orphaned documents
- * - Broadcasted operations (from router) on orphaned documents
- * - Transaction from router updating both orphaned and non-orphaned documents
- * - Transaction to shard updating both orphaned and non-orphaned documents
- * - Batched deletes from router and to shard
+ * - Test case 1: Direct operations to shard on orphaned documents
+ * - Test case 2: Broadcasted operations (from router) on orphaned documents
+ * - Test case 3: Transaction from router updating both orphaned and owned documents
+ * - Test case 4: Transaction to shard updating both orphaned and owned documents
*
* @tags: [
* requires_fcv_53,
@@ -19,6 +18,19 @@
load('jstests/libs/fail_point_util.js'); // For configureFailPoint
+// Asserts that there is no event.
+function assertNoChanges(csCursor) {
+ function advanceAndGetToken() {
+ assert(!csCursor.hasNext(), () => csCursor.next());
+ return csCursor.getResumeToken();
+ }
+ const startToken = advanceAndGetToken();
+ assert.soon(() => {
+ const currentToken = advanceAndGetToken();
+ return bsonWoCompare(currentToken, startToken) > 0;
+ });
+}
+
const dbName = 'test';
const collName = 'foo';
const collNS = dbName + '.' + collName;
@@ -29,7 +41,7 @@ const st = new ShardingTest({
mongos: 1,
config: 1,
shards: 2,
- rs: {nodes: 1, setParameter: {writePeriodicNoops: true}},
+ rs: {nodes: 1, setParameter: {writePeriodicNoops: true, periodicNoopIntervalSecs: 1}},
other: {enableBalancer: false}
});
@@ -42,14 +54,15 @@ assert.commandWorked(
st.s.adminCommand({enableSharding: dbName, primaryShard: st.shard0.shardName}));
assert.commandWorked(st.s.adminCommand({shardCollection: collNS, key: {_id: 1}}));
const coll = st.s.getCollection(collNS);
-assert.commandWorked(coll.insert({_id: -2, name: 'emma', age: 20}));
-assert.commandWorked(coll.insert({_id: -1, name: 'olivia', age: 25}));
-assert.commandWorked(coll.insert({_id: 0, name: 'matt', age: 30}));
-assert.commandWorked(coll.insert({_id: 1, name: 'john', age: 35}));
-assert.commandWorked(coll.insert({_id: 2, name: 'robert', age: 40}));
-assert.commandWorked(coll.insert({_id: 3, name: 'robert', age: 45}));
-assert.commandWorked(coll.insert({_id: 4, name: 'james', age: 50}));
-assert.commandWorked(coll.insert({_id: 5, name: 'liam', age: 55}));
+assert.commandWorked(coll.insert({_id: -2, name: 'emma', age: 20})); // Test case 4
+assert.commandWorked(coll.insert({_id: -1, name: 'olivia', age: 25})); // Test case 3
+assert.commandWorked(coll.insert({_id: 0, name: 'matt', age: 30})); // Test case 1
+assert.commandWorked(coll.insert({_id: 1, name: 'matt', age: 35})); // Test case 1
+assert.commandWorked(coll.insert({_id: 2, name: 'john', age: 40})); // Test case 2
+assert.commandWorked(coll.insert({_id: 3, name: 'robert', age: 45})); // Test case 2
+assert.commandWorked(coll.insert({_id: 4, name: 'robert', age: 50})); // Test case 2
+assert.commandWorked(coll.insert({_id: 5, name: 'james', age: 55})); // Test case 3
+assert.commandWorked(coll.insert({_id: 6, name: 'liam', age: 60})); // Test case 4
// Move the chunk to the second shard leaving orphaned documents on the first shard.
assert.commandWorked(st.s.adminCommand({split: collNS, middle: {_id: 0}}));
@@ -60,64 +73,91 @@ assert.commandWorked(
const changeStream = coll.watch([]);
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Direct operations to shard on orphaned documents
+// Test case 1: Direct operations to shard on orphaned documents
////////////////////////////////////////////////////////////////////////////////////////////////////
jsTest.log('A direct insert to a shard of an orphaned document does not generate an insert event');
{
// Direct insert to first shard of an orphaned document.
- assert.commandWorked(st.shard0.getCollection(collNS).insert({_id: 6, name: 'ken', age: 60}));
+ assert.commandWorked(st.shard0.getCollection(collNS).insert({_id: 7, name: 'ken', age: 65}));
// No event is notified.
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
// The orphaned document on first shard has been inserted.
- assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 6}));
+ assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 7}));
}
jsTest.log('A direct update to a shard of an orphaned document does not generate an update event');
{
// Send a direct update to first shard on an orphaned document.
- assert.commandWorked(st.shard0.getCollection(collNS).update({name: 'matt'}, {$set: {age: 31}}));
+ assert.commandWorked(st.shard0.getCollection(collNS).update({name: 'ken'}, {$set: {age: 66}}));
// No change stream event is generated.
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
// The orphaned document on first shard has been updated.
- assert.eq(31, st.shard0.getCollection(collNS).findOne({_id: 0}).age);
+ assert.eq(66, st.shard0.getCollection(collNS).findOne({_id: 7}).age);
}
jsTest.log('A direct delete to a shard of an orphaned document does generate an update event');
{
// Send a direct delete to first shard on an orphaned document.
- assert.commandWorked(st.shard0.getCollection(collNS).remove({name: 'matt'}));
+ assert.commandWorked(st.shard0.getCollection(collNS).remove({name: 'ken'}));
// No change stream event is generated.
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
// The orphaned document on first shard has been removed.
+ assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: 7}));
+}
+
+jsTest.log('A direct update to a shard of multi-documents does not generate update events');
+{
+ // Send a direct update to first shard on two orphaned documents.
+ assert.commandWorked(
+ st.shard0.getCollection(collNS).update({name: 'matt'}, {$set: {age: 31}}, {multi: true}));
+
+ // No change stream event is generated.
+ assertNoChanges(changeStream);
+
+ // The orphaned documents on first shard have been updated
+ assert.eq(31, st.shard0.getCollection(collNS).findOne({_id: 0}).age);
+ assert.eq(31, st.shard0.getCollection(collNS).findOne({_id: 1}).age);
+}
+
+jsTest.log('A direct delete to a shard of multi-documents does not generate delete events');
+{
+ // Send a direct delete to first shard on an orphaned document.
+ assert.commandWorked(st.shard0.getCollection(collNS).remove({name: 'matt'}));
+
+ // No change stream event is generated.
+ assertNoChanges(changeStream);
+
+ // The orphaned documents on first shard have been removed.
assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: 0}));
+ assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: 1}));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Broadcasted operations (from router) on orphaned documents
+// Test case 2: Broadcasted operations (from router) on orphaned documents
////////////////////////////////////////////////////////////////////////////////////////////////////
jsTest.log('A broadcasted update of a single document generates an update event');
{
// Send a broadcasted update (query on non-key field) on a single document to all the shards.
- assert.commandWorked(coll.update({name: 'john'}, {$set: {age: 36}}, {multi: true}));
+ assert.commandWorked(coll.update({name: 'john'}, {$set: {age: 41}}, {multi: true}));
// The document is hosted by the second shard and the update event is notified. The first shard
// still hosts the orphaned document so no additional event must be notified.
assert.soon(() => changeStream.hasNext(), 'An update event is expected');
assert.eq(changeStream.next().operationType, 'update');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // The orphaned document on first shard has not been updated, unlike the non-orphaned one on the
- // second shard.
- assert.eq(35, st.shard0.getCollection(collNS).findOne({_id: 1}).age);
- assert.eq(36, st.shard1.getCollection(collNS).findOne({_id: 1}).age);
+ // The orphaned document on first shard has not been updated, unlike the owned one on the second
+ // shard.
+ assert.eq(40, st.shard0.getCollection(collNS).findOne({_id: 2}).age);
+ assert.eq(41, st.shard1.getCollection(collNS).findOne({_id: 2}).age);
}
jsTest.log('A broadcasted delete of a single document generates a delete event');
@@ -129,18 +169,18 @@ jsTest.log('A broadcasted delete of a single document generates a delete event')
// still hosts the orphaned document so no additional event must be notified.
assert.soon(() => changeStream.hasNext(), 'A delete event is expected');
assert.eq(changeStream.next().operationType, 'delete');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // The orphaned document on first shard has not been removed, unlike the non-orphaned one on the
- // second shard.
- assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 1}));
- assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 1}));
+ // The orphaned document on first shard has not been removed, unlike the owned one on the second
+ // shard.
+ assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 2}));
+ assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 2}));
}
jsTest.log('A broadcasted update of multi-documents generates more update events');
{
// Send a broadcasted update (query on non-key field) on two documents to all the shards.
- assert.commandWorked(coll.update({name: 'robert'}, {$set: {age: 41}}, {multi: true}));
+ assert.commandWorked(coll.update({name: 'robert'}, {$set: {age: 46}}, {multi: true}));
// The documents are hosted by the second shard and two delete events are notified. The first
// shard still hosts the orphaned documents so no additional event must be notified.
@@ -148,14 +188,14 @@ jsTest.log('A broadcasted update of multi-documents generates more update events
assert.eq(changeStream.next().operationType, 'update');
assert.soon(() => changeStream.hasNext(), 'A second update event is expected');
assert.eq(changeStream.next().operationType, 'update');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // The orphaned documents on first shard have not been updated, unlike the non-orphaned ones on
- // the second shard.
- assert.eq(40, st.shard0.getCollection(collNS).findOne({_id: 2}).age);
+ // The orphaned documents on first shard have not been updated, unlike the owned ones on the
+ // second shard.
assert.eq(45, st.shard0.getCollection(collNS).findOne({_id: 3}).age);
- assert.eq(41, st.shard1.getCollection(collNS).findOne({_id: 2}).age);
- assert.eq(41, st.shard1.getCollection(collNS).findOne({_id: 3}).age);
+ assert.eq(50, st.shard0.getCollection(collNS).findOne({_id: 4}).age);
+ assert.eq(46, st.shard1.getCollection(collNS).findOne({_id: 3}).age);
+ assert.eq(46, st.shard1.getCollection(collNS).findOne({_id: 4}).age);
}
jsTest.log('A broadcasted delete of multi-documents generates more delete events');
@@ -169,55 +209,52 @@ jsTest.log('A broadcasted delete of multi-documents generates more delete events
assert.eq(changeStream.next().operationType, 'delete');
assert.soon(() => changeStream.hasNext(), 'A second delete event is expected');
assert.eq(changeStream.next().operationType, 'delete');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // The orphaned documents on first shard have not been removed, unlike the non-orphaned ones on
- // the second shard.
- assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 2}));
+ // The orphaned documents on first shard have not been removed, unlike the owned ones on the
+ // second shard.
assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 3}));
- assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 2}));
+ assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 4}));
assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 3}));
+ assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 4}));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Transaction from router updating both orphaned and non-orphaned documents
+// Test case 3: Transaction from router updating both orphaned and owned documents
////////////////////////////////////////////////////////////////////////////////////////////////////
-jsTest.log('Broadcasted updates (via a transaction through the router) of both orphaned and ' +
- 'non-orphaned documents generate events only for operations on non-orphaned documents');
+jsTest.log('Broadcasted updates (via a transaction through the router) of both orphaned and owned' +
+ 'documents generate events only for operations on owned documents');
{
- // Send a broadcasted transaction to the router updating both orphaned and non-orphaned
- // documents.
+ // Send a broadcasted transaction to the router updating both orphaned and owned documents.
const session = st.s.startSession();
const sessionDB = session.getDatabase(dbName);
const sessionColl = sessionDB.getCollection(collName);
session.startTransaction();
assert.commandWorked(sessionColl.update({name: 'olivia'}, {$set: {age: 26}}, {multi: true}));
- assert.commandWorked(sessionColl.update({name: 'james'}, {$set: {age: 51}}, {multi: true}));
+ assert.commandWorked(sessionColl.update({name: 'james'}, {$set: {age: 56}}, {multi: true}));
assert.commandWorked(session.commitTransaction_forTesting());
session.endSession();
- // The primary shard hosts orphaned (james) and non-orphaned (olivia) documents, whereas the
- // second shard hosts a non-orphaned document (james). Consequently, two update events are
- // notified.
+ // The primary shard hosts orphaned (james) and owned (olivia) documents, whereas the second
+ // shard hosts an owned document (james). Consequently, two update events are notified.
assert.soon(() => changeStream.hasNext(), 'A first update event is expected');
assert.eq(changeStream.next().operationType, 'update');
assert.soon(() => changeStream.hasNext(), 'A second update event is expected');
assert.eq(changeStream.next().operationType, 'update');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // The orphaned document on first shard (james) has not been updated, unlike the non-orphaned
- // ones on both primary and second shards (olivia and james).
+ // The orphaned document on first shard (james) has not been updated, unlike the owned ones on
+ // both primary and second shards (olivia and james).
assert.eq(26, st.shard0.getCollection(collNS).findOne({_id: -1}).age);
- assert.eq(50, st.shard0.getCollection(collNS).findOne({_id: 4}).age);
- assert.eq(51, st.shard1.getCollection(collNS).findOne({_id: 4}).age);
+ assert.eq(55, st.shard0.getCollection(collNS).findOne({_id: 5}).age);
+ assert.eq(56, st.shard1.getCollection(collNS).findOne({_id: 5}).age);
}
-jsTest.log('Broadcasted deletes (via a transaction through the router) of both orphaned and ' +
- 'non-orphaned documents generate events only for operations on non-orphaned documents');
+jsTest.log('Broadcasted deletes (via a transaction through the router) of both orphaned and owned' +
+ 'documents generate events only for operations on owned documents');
{
- // Send a broadcasted transaction to the router deleting both orphaned and non-orphaned
- // documents.
+ // Send a broadcasted transaction to the router deleting both orphaned and owned documents.
const session = st.s.startSession();
const sessionDB = session.getDatabase(dbName);
const sessionColl = sessionDB.getCollection(collName);
@@ -227,58 +264,57 @@ jsTest.log('Broadcasted deletes (via a transaction through the router) of both o
assert.commandWorked(session.commitTransaction_forTesting());
session.endSession();
- // The primary shard hosts orphaned (james) and non-orphaned (olivia) documents, whereas the
- // second shard hosts a non-orphaned document (james). Consequently, two delete events are
- // notified.
+ // The primary shard hosts orphaned (james) and owned (olivia) documents, whereas the second
+ // shard hosts an owned document (james). Consequently, two delete events are notified.
assert.soon(() => changeStream.hasNext(), 'A first delete event is expected');
assert.eq(changeStream.next().operationType, 'delete');
assert.soon(() => changeStream.hasNext(), 'A second delete event is expected');
assert.eq(changeStream.next().operationType, 'delete');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // The orphaned document on first shard (james) has not been removed, unlike the non-orphaned
- // ones on both primary and second shards (olivia and james).
+ // The orphaned document on first shard (james) has not been removed, unlike the owned ones on
+ // both primary and second shards (olivia and james).
assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: -1}));
- assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 4}));
- assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 4}));
+ assert.neq(null, st.shard0.getCollection(collNS).findOne({_id: 5}));
+ assert.eq(null, st.shard1.getCollection(collNS).findOne({_id: 5}));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Transaction to shard updating both orphaned and non-orphaned documents
+// Test case 4: Transaction to shard updating both orphaned and owned documents
////////////////////////////////////////////////////////////////////////////////////////////////////
-jsTest.log('Direct updates (via a transaction to a shard) of both orphaned and non-orphaned' +
- 'documents generate events only for operations on non-orphaned documents');
+jsTest.log('Direct updates (via a transaction to a shard) of both orphaned and owned documents' +
+ 'generate events only for operations on owned documents');
{
- // Send a direct transaction to a shard updating both orphaned and non-orphaned documents.
+ // Send a direct transaction to a shard updating both orphaned and owned documents.
const session = st.rs0.getPrimary().getDB(dbName).getMongo().startSession();
const sessionDB = session.getDatabase(dbName);
const sessionColl = sessionDB.getCollection(collName);
session.startTransaction();
assert.commandWorked(sessionColl.update({name: 'emma'}, {$set: {age: 21}}, {multi: true}));
- assert.commandWorked(sessionColl.update({name: 'liam'}, {$set: {age: 56}}, {multi: true}));
+ assert.commandWorked(sessionColl.update({name: 'liam'}, {$set: {age: 61}}, {multi: true}));
assert.commandWorked(session.commitTransaction_forTesting());
session.endSession();
- // The shard hosts both orphaned (liam) and non-orphaned (emma) documents. Consequently, only
- // one update event is notified.
+ // The shard hosts both orphaned (liam) and owned (emma) documents. Consequently, only one
+ // update event is notified.
// TODO (SERVER-65859): The second update event will be filtered out when the ticket is
// completed.
assert.soon(() => changeStream.hasNext(), 'A first update event is expected');
assert.eq(changeStream.next().operationType, 'update');
assert.soon(() => changeStream.hasNext(), 'A second update event is expected');
assert.eq(changeStream.next().operationType, 'update');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // Both orphaned (liam) and non-orphaned (emma) documents on the shard have been updated.
+ // Both orphaned (liam) and owned (emma) documents on the shard have been updated.
assert.eq(21, st.shard0.getCollection(collNS).findOne({_id: -2}).age);
- assert.eq(56, st.shard0.getCollection(collNS).findOne({_id: 5}).age);
+ assert.eq(61, st.shard0.getCollection(collNS).findOne({_id: 6}).age);
}
-jsTest.log('Direct deletes (via a transaction to a shard) of both orphaned and non-orphaned' +
- 'documents generate events only for operations on non-orphaned documents');
+jsTest.log('Direct deletes (via a transaction to a shard) of both orphaned and owned documents' +
+ 'generate events only for operations on owned documents');
{
- // Send a direct transaction to a shard deleting both orphaned and non-orphaned documents.
+ // Send a direct transaction to a shard deleting both orphaned and owned documents.
const session = st.rs0.getPrimary().getDB(dbName).getMongo().startSession();
const sessionDB = session.getDatabase(dbName);
const sessionColl = sessionDB.getCollection(collName);
@@ -288,19 +324,19 @@ jsTest.log('Direct deletes (via a transaction to a shard) of both orphaned and n
assert.commandWorked(session.commitTransaction_forTesting());
session.endSession();
- // The shard hosts both orphaned (liam) and non-orphaned (emma) documents. Consequently, only
- // one update event is notified.
+ // The shard hosts both orphaned (liam) and owned (emma) documents. Consequently, only one
+ // update event is notified.
// TODO (SERVER-65859): The second delete event will be filtered out when the ticket is
// completed.
assert.soon(() => changeStream.hasNext(), 'A first delete event is expected');
assert.eq(changeStream.next().operationType, 'delete');
assert.soon(() => changeStream.hasNext(), 'A second delete event is expected');
assert.eq(changeStream.next().operationType, 'delete');
- assert(!changeStream.hasNext());
+ assertNoChanges(changeStream);
- // Both orphaned (liam) and non-orphaned (emma) documents on the shard have been removed.
+ // Both orphaned (liam) and owned (emma) documents on the shard have been removed.
assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: -2}));
- assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: 5}));
+ assert.eq(null, st.shard0.getCollection(collNS).findOne({_id: 6}));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -315,92 +351,6 @@ jsTest.log('The collection drop generates a drop event');
assert.eq(changeStream.next().operationType, 'drop');
}
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Batched deletes from router and to shard
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// Set the database to use batched deletes.
-const db2 = st.rs0.getPrimary().getDB(dbName);
-assert.commandWorked(db2.adminCommand({setParameter: 1, batchedDeletesTargetStagedDocBytes: 0}));
-assert.commandWorked(db2.adminCommand({setParameter: 1, batchedDeletesTargetBatchTimeMS: 0}));
-assert.commandWorked(db2.adminCommand({setParameter: 1, batchedDeletesTargetBatchDocs: 2}));
-
-// Create a non-sharded collection.
-const coll2 = db2.getCollection(collName);
-
-// Setup a change stream on the collection to receive real-time events on any data changes.
-const changeStream2 = coll2.watch([]);
-
-jsTest.log('A batched delete from router generates only one delete event');
-{
- // Insert two documents in the collection (see 'batchedDeletesTargetBatchDocs') and skip the
- // generated events.
- assert.commandWorked(coll2.insert({_id: 0, name: 'volkswagen'}));
- assert.commandWorked(coll2.insert({_id: 1, name: 'renault'}));
- assert.soon(() => changeStream2.hasNext(), 'A first insert event is expected');
- assert.eq(changeStream2.next().operationType, 'insert');
- assert.soon(() => changeStream2.hasNext(), 'A second insert event is expected');
- assert.eq(changeStream2.next().operationType, 'insert');
- assert(!changeStream2.hasNext());
-
- // Delete all documents in batch from the collection.
- assert.commandWorked(coll2.deleteMany({_id: {$gte: 0}}));
-
- // Actually only one delete operation is performed. Consequently, only one delete event is
- // notified.
- // TODO (SERVER-65859): The second delete event will be filtered out when the ticket is
- // completed.
- assert.soon(() => changeStream2.hasNext(), 'A first delete event is expected');
- assert.eq(changeStream2.next().operationType, 'delete');
- assert.soon(() => changeStream2.hasNext(), 'A second delete event is expected for now');
- assert.eq(changeStream2.next().operationType, 'delete');
- assert(!changeStream2.hasNext());
-
- // All documents have been removed from the collection.
- assert.eq(0, coll2.find().itcount());
-}
-
-jsTest.log('A batched delete to shard generates only one delete event');
-{
- // Insert two documents in the collection (see 'batchedDeletesTargetBatchDocs') and skip the
- // generated events.
- assert.commandWorked(coll2.insert({_id: 0, name: 'volkswagen'}));
- assert.commandWorked(coll2.insert({_id: 1, name: 'renault'}));
- assert.soon(() => changeStream2.hasNext(), 'A first insert event is expected');
- assert.eq(changeStream2.next().operationType, 'insert');
- assert.soon(() => changeStream2.hasNext(), 'A second insert event is expected');
- assert.eq(changeStream2.next().operationType, 'insert');
- assert(!changeStream2.hasNext());
-
- // Delete all documents in batch from the collection.
- assert.commandWorked(st.shard0.getCollection(collNS).deleteMany({_id: {$gte: 0}}));
-
- // Actually only one delete operation is performed. Consequently, only one delete event is
- // notified.
- // TODO (SERVER-65859): The second delete event will be filtered out when the ticket is
- // completed.
- assert.soon(() => changeStream2.hasNext(), 'A first delete event is expected');
- assert.eq(changeStream2.next().operationType, 'delete');
- assert.soon(() => changeStream2.hasNext(), 'A second delete event is expected for now');
- assert.eq(changeStream2.next().operationType, 'delete');
- assert(!changeStream2.hasNext());
-
- // All documents have been removed from the collection.
- assert.eq(0, coll2.find().itcount());
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-jsTest.log('The collection drop generates a drop event');
-{
- coll2.drop();
-
- // Essentially, this verifies that the operation before dropping the collection did not notify
- // additional and unexpected events.
- assert.soon(() => changeStream2.hasNext(), 'A drop event is expected');
- assert.eq(changeStream2.next().operationType, 'drop');
-}
-
suspendRangeDeletionShard0.off();
st.stop();