diff options
Diffstat (limited to 'jstests/replsets/initial_sync_drop_collection.js')
-rw-r--r-- | jstests/replsets/initial_sync_drop_collection.js | 105 |
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(); })(); |