summaryrefslogtreecommitdiff
path: root/jstests/replsets/initial_sync_drop_collection.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/replsets/initial_sync_drop_collection.js')
-rw-r--r--jstests/replsets/initial_sync_drop_collection.js105
1 files changed, 57 insertions, 48 deletions
diff --git a/jstests/replsets/initial_sync_drop_collection.js b/jstests/replsets/initial_sync_drop_collection.js
index cd6b6aaee08..de375ffc73c 100644
--- a/jstests/replsets/initial_sync_drop_collection.js
+++ b/jstests/replsets/initial_sync_drop_collection.js
@@ -1,16 +1,11 @@
-// Test that CollectionCloner completes without error when a collection is dropped during cloning.
+/**
+ * Test that CollectionCloner completes without error when a collection is dropped during cloning.
+ * @tags: [requires_fcv_44]
+ */
(function() {
"use strict";
-// TODO(SERVER-43277): This test is disabled while we work on the Resumable Initial Sync
-// project
-/* eslint-disable no-unreachable */
-return;
-
-// Skip db hash check because secondary cannot complete initial sync.
-TestData.skipCheckDBHashes = true;
-
load("jstests/libs/fail_point_util.js");
load('jstests/replsets/libs/two_phase_drops.js');
load("jstests/libs/uuid_util.js");
@@ -30,7 +25,6 @@ var secondaryDB = secondary.getDB(dbName);
const collName = "testcoll";
var primaryColl = primaryDB[collName];
var secondaryColl = secondaryDB[collName];
-var pRenameColl = primaryDB["r_" + collName];
var nss = primaryColl.getFullName();
// This function adds data to the collection, restarts the secondary node with the given
@@ -38,13 +32,14 @@ var nss = primaryColl.getFullName();
// drops the collection, then disables the failpoint. It then optionally waits for the
// expectedLog message and waits for the secondary to complete initial sync, then ensures
// the collection on the secondary is empty.
-function setupTest({failPoint, secondaryStartupParams}) {
+function setupTest({failPoint, extraFailPointData, secondaryStartupParams}) {
jsTestLog("Writing data to collection.");
assert.commandWorked(primaryColl.insert([{_id: 1}, {_id: 2}]));
+ const data = Object.merge(extraFailPointData || {}, {nss: nss});
jsTestLog("Restarting secondary with failPoint " + failPoint + " set for " + nss);
secondaryStartupParams = secondaryStartupParams || {};
- secondaryStartupParams['failpoint.' + failPoint] = tojson({mode: 'alwaysOn', data: {nss: nss}});
+ secondaryStartupParams['failpoint.' + failPoint] = tojson({mode: 'alwaysOn', data: data});
// Skip clearing initial sync progress after a successful initial sync attempt so that we
// can check initialSyncStatus fields after initial sync is complete.
secondaryStartupParams['failpoint.skipClearInitialSyncState'] = tojson({mode: 'alwaysOn'});
@@ -67,9 +62,9 @@ function setupTest({failPoint, secondaryStartupParams}) {
replTest.waitForState(secondary, ReplSetTest.State.STARTUP_2);
}
-function finishTest({failPoint, secondaryStartupParams, expectedLog, waitForDrop, createNew}) {
+function finishTest({failPoint, expectedLog, waitForDrop, createNew}) {
// Get the uuid for use in checking the log line.
- let uuid = getUUIDFromListCollections(primaryDB, collName);
+ const uuid = extractUUIDFromObject(getUUIDFromListCollections(primaryDB, collName));
jsTestLog("Dropping collection on primary: " + primaryColl.getFullName());
assert(primaryColl.drop());
@@ -79,6 +74,16 @@ function finishTest({failPoint, secondaryStartupParams, expectedLog, waitForDrop
TwoPhaseDropCollectionTest.waitForDropToComplete(primaryDB, collName);
}
+ // Only set for test cases that use 'system.drop' namespaces when dropping collections.
+ // In those tests the variable 'rnss' represents such a namespace. Used for expectedLog.
+ // See test cases 3 and 4 below.
+ let rnss;
+ const dropPendingColl =
+ TwoPhaseDropCollectionTest.collectionIsPendingDropInDatabase(primaryDB, collName);
+ if (dropPendingColl) {
+ rnss = dbName + "." + dropPendingColl["name"];
+ }
+
if (createNew) {
jsTestLog("Creating a new collection with the same name: " + primaryColl.getFullName());
assert.commandWorked(primaryColl.insert({_id: "not the same collection"}));
@@ -112,68 +117,72 @@ function runDropTest(params) {
finishTest(params);
}
-jsTestLog("Testing dropping between listIndexes and find.");
-runDropTest({failPoint: "initialSyncHangCollectionClonerBeforeEstablishingCursor"});
+jsTestLog("[1] Testing dropping between listIndexes and find.");
+runDropTest({
+ failPoint: "hangBeforeClonerStage",
+ extraFailPointData: {cloner: "CollectionCloner", stage: "query"}
+});
+
+jsTestLog(
+ "[2] Testing dropping between listIndexes and find, with new same-name collection created.");
+runDropTest({
+ failPoint: "hangBeforeClonerStage",
+ extraFailPointData: {cloner: "CollectionCloner", stage: "query"},
+ createNew: true
+});
+
+let expectedLogFor3and4 =
+ "`CollectionCloner ns: '${nss}' uuid: UUID(\"${uuid}\") stopped because collection was dropped on source.`";
-jsTestLog("Testing dropping between listIndexes and find, with new same-name collection created.");
-runDropTest(
- {failPoint: "initialSyncHangCollectionClonerBeforeEstablishingCursor", createNew: true});
+// We don't support 4.2 style two-phase drops with EMRC=false - in that configuration, the
+// collection will instead be renamed to a <db>.system.drop.* namespace before being dropped. Since
+// the cloner queries collection by UUID, it will observe the first drop phase as a rename.
+// We still want to check that initial sync succeeds in such a case.
+if (TwoPhaseDropCollectionTest.supportsDropPendingNamespaces(replTest)) {
+ expectedLogFor3and4 =
+ "`Initial Sync retrying CollectionCloner stage query due to QueryPlanKilled: collection renamed from '${nss}' to '${rnss}'. UUID ${uuid}`";
+}
-jsTestLog("Testing drop-pending between getMore calls.");
+jsTestLog("[3] Testing drop-pending between getMore calls.");
runDropTest({
failPoint: "initialSyncHangCollectionClonerAfterHandlingBatchResponse",
secondaryStartupParams: {collectionClonerBatchSize: 1},
- expectedLog:
- "`CollectionCloner ns: '${nss}' uuid: ${uuid} stopped because collection was dropped.`"
+ expectedLog: expectedLogFor3and4
});
-jsTestLog("Testing drop-pending with new same-name collection created, between getMore calls.");
+jsTestLog("[4] Testing drop-pending with new same-name collection created, between getMore calls.");
runDropTest({
failPoint: "initialSyncHangCollectionClonerAfterHandlingBatchResponse",
secondaryStartupParams: {collectionClonerBatchSize: 1},
- expectedLog:
- "`CollectionCloner ns: '${nss}' uuid: ${uuid} stopped because collection was dropped.`",
+ expectedLog: expectedLogFor3and4,
createNew: true
});
-jsTestLog("Testing committed drop between getMore calls.");
-
// Add another node to the set, so when we drop the collection it can commit. This other
// secondary will be finished with initial sync when the drop happens.
var secondary2 = replTest.add({rsConfig: {priority: 0}});
replTest.reInitiate();
replTest.waitForState(secondary2, ReplSetTest.State.SECONDARY);
+jsTestLog("[5] Testing committed drop between getMore calls.");
runDropTest({
failPoint: "initialSyncHangCollectionClonerAfterHandlingBatchResponse",
secondaryStartupParams: {collectionClonerBatchSize: 1},
waitForDrop: true,
expectedLog:
- "`CollectionCloner ns: '${nss}' uuid: ${uuid} stopped because collection was dropped.`"
+ "`CollectionCloner ns: '${nss}' uuid: UUID(\"${uuid}\") stopped because collection was dropped on source.`"
});
-jsTestLog("Testing rename between getMores.");
-setupTest({
+jsTestLog(
+ "[6] Testing committed drop with new same-name collection created, between getMore calls.");
+runDropTest({
failPoint: "initialSyncHangCollectionClonerAfterHandlingBatchResponse",
secondaryStartupParams: {collectionClonerBatchSize: 1},
+ waitForDrop: true,
+ expectedLog:
+ "`CollectionCloner ns: '${nss}' uuid: UUID(\"${uuid}\") stopped because collection was dropped on source.`",
+ createNew: true
});
-jsTestLog("Renaming collection on primary");
-assert.commandWorked(primary.adminCommand({
- renameCollection: primaryColl.getFullName(),
- to: pRenameColl.getFullName(),
- dropTarget: false
-}));
-
-jsTestLog("Allowing secondary to continue.");
-// Make sure we don't reach the fassert() indicating initial sync failure.
-assert.commandWorked(
- secondary.adminCommand({configureFailPoint: "initialSyncHangBeforeFinish", mode: 'alwaysOn'}));
-
-assert.commandWorked(secondary.adminCommand({
- configureFailPoint: "initialSyncHangCollectionClonerAfterHandlingBatchResponse",
- mode: 'off'
-}));
-jsTestLog("Waiting for initial sync to complete.");
-checkLog.contains(secondary, "The maximum number of retries have been exhausted for initial sync.");
+
replTest.stopSet();
})();