summaryrefslogtreecommitdiff
path: root/jstests/replsets/drop_collections_two_phase_rename_drop_target.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/replsets/drop_collections_two_phase_rename_drop_target.js')
-rw-r--r--jstests/replsets/drop_collections_two_phase_rename_drop_target.js52
1 files changed, 50 insertions, 2 deletions
diff --git a/jstests/replsets/drop_collections_two_phase_rename_drop_target.js b/jstests/replsets/drop_collections_two_phase_rename_drop_target.js
index e0c2aabadb6..5a646036fc8 100644
--- a/jstests/replsets/drop_collections_two_phase_rename_drop_target.js
+++ b/jstests/replsets/drop_collections_two_phase_rename_drop_target.js
@@ -9,6 +9,17 @@
load('jstests/replsets/libs/two_phase_drops.js'); // For TwoPhaseDropCollectionTest.
load('jstests/libs/check_log.js'); // For checkLog.contains().
+ // Return a list of all indexes for a given collection. Use 'args' as the
+ // 'listIndexes' command arguments.
+ // Assumes all indexes in the collection fit in the first batch of results.
+ function listIndexes(database, coll, args) {
+ args = args || {};
+ let failMsg = "'listIndexes' command failed";
+ let listIndexesCmd = {listIndexes: coll};
+ let res = assert.commandWorked(database.runCommand(listIndexesCmd, args), failMsg);
+ return res.cursor.firstBatch;
+ }
+
// Set up a two phase drop test.
let testName = 'drop_collection_two_phase_rename_drop_target';
let dbName = testName;
@@ -23,11 +34,23 @@
twoPhaseDropTest.createCollection(fromCollName);
twoPhaseDropTest.createCollection(toCollName);
- // Insert documents into both collections so that we can tell them apart.
+ // Collection renames with dropTarget set to true should handle long index names in the target
+ // collection gracefully. MMAPv1 imposes a hard limit on index namespaces so we have to drop
+ // indexes that are too long to store on disk after renaming the collection.
const primary = replTest.getPrimary();
const testDb = primary.getDB(dbName);
const fromColl = testDb.getCollection(fromCollName);
const toColl = testDb.getCollection(toCollName);
+ let maxNsLength = 127;
+ let longIndexName = ''.pad(maxNsLength - (toColl.getFullName() + '.$').length, true, 'a');
+ let shortIndexName = "short_name";
+
+ // In the target collection, which will be dropped, create one index with a "too long" name, and
+ // one with a name of acceptable size.
+ assert.commandWorked(toColl.ensureIndex({a: 1}, {name: longIndexName}));
+ assert.commandWorked(toColl.ensureIndex({b: 1}, {name: shortIndexName}));
+
+ // Insert documents into both collections so that we can tell them apart.
assert.writeOK(fromColl.insert({_id: 'from'}));
assert.writeOK(toColl.insert({_id: 'to'}));
replTest.awaitReplication();
@@ -61,7 +84,32 @@
assert.eq({_id: 'from'}, toColl.findOne());
// Confirm that original target collection is now a drop-pending collection.
- assert(twoPhaseDropTest.collectionIsPendingDrop(toCollName));
+ const isPendingDropResult = twoPhaseDropTest.collectionIsPendingDrop(toCollName);
+ assert(isPendingDropResult);
+ const droppedCollName = isPendingDropResult.name;
+ jsTestLog('Original target collection is now in a drop-pending state: ' + droppedCollName);
+
+ // Check that indexes that would violate the namespace length constraints after rename were
+ // dropped.
+ const indexes = listIndexes(testDb, droppedCollName);
+ jsTestLog('Indexes in ' + droppedCollName + ': ' + tojson(indexes));
+ assert(indexes.find(idx => idx.name === shortIndexName));
+ assert.eq(undefined, indexes.find(idx => idx.name === longIndexName));
+
+ // Check that index drop appears before collection rename in the oplog.
+ const oplogColl = primary.getCollection('local.oplog.rs');
+ const cmdNs = testDb.getCollection('$cmd').getFullName();
+ const renameOplogEntry =
+ oplogColl.findOne({ns: cmdNs, 'o.renameCollection': fromColl.getFullName()});
+ const dropIndexOplogEntry =
+ oplogColl.findOne({ns: cmdNs, o: {dropIndexes: toCollName, index: longIndexName}});
+ const renameTimestamp = renameOplogEntry.ts;
+ const dropIndexTimestamp = dropIndexOplogEntry.ts;
+ assert.lt(dropIndexTimestamp,
+ renameTimestamp,
+ 'index was not dropped before collection. index drop: ' +
+ tojson(dropIndexOplogEntry) + ' . collection rename: ' +
+ tojson(renameOplogEntry));
// COMMIT collection drop.
twoPhaseDropTest.resumeOplogApplication(secondary);