diff options
author | A. Jesse Jiryu Davis <jesse@mongodb.com> | 2021-11-15 19:29:59 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-16 03:19:02 +0000 |
commit | 5f3c1897af8571355124a1c58774eda5d580c9f5 (patch) | |
tree | 0dde4482a35cc774985aa676226c409315d0b1a2 | |
parent | 71e85a2029d7e93f2915191ea28be10e2d869859 (diff) | |
download | mongo-5f3c1897af8571355124a1c58774eda5d580c9f5.tar.gz |
SERVER-61440 Race in tenant_migration_recipient_current_op.js
(cherry picked from commit f0095b9c20c472d9ba53d4c1f147d18b35bd27f4)
-rw-r--r-- | jstests/replsets/tenant_migration_recipient_current_op.js | 122 |
1 files changed, 49 insertions, 73 deletions
diff --git a/jstests/replsets/tenant_migration_recipient_current_op.js b/jstests/replsets/tenant_migration_recipient_current_op.js index 68b85c0510e..65ad7354b83 100644 --- a/jstests/replsets/tenant_migration_recipient_current_op.js +++ b/jstests/replsets/tenant_migration_recipient_current_op.js @@ -69,6 +69,35 @@ function checkStandardFieldsOK(res) { assert.eq(res.inprog[0].numRestartsDueToRecipientFailure, 0, res); } +// Check currentOp fields' expected value once the recipient is in state "consistent" or later. +function checkPostConsistentFieldsOK(res) { + const currOp = res.inprog[0]; + assert(currOp.hasOwnProperty("startFetchingDonorOpTime") && + checkOptime(currOp.startFetchingDonorOpTime), + res); + assert(currOp.hasOwnProperty("startApplyingDonorOpTime") && + checkOptime(currOp.startApplyingDonorOpTime), + res); + assert(currOp.hasOwnProperty("dataConsistentStopDonorOpTime") && + checkOptime(currOp.dataConsistentStopDonorOpTime), + res); + assert(currOp.hasOwnProperty("cloneFinishedRecipientOpTime") && + checkOptime(currOp.cloneFinishedRecipientOpTime), + res); + assert(currOp.hasOwnProperty("approxTotalDataSize") && + currOp.approxTotalDataSize instanceof NumberLong, + res); + assert(currOp.hasOwnProperty("approxTotalBytesCopied") && + currOp.approxTotalBytesCopied instanceof NumberLong, + res); + assert(currOp.hasOwnProperty("totalReceiveElapsedMillis") && + currOp.totalReceiveElapsedMillis instanceof NumberLong, + res); + assert(currOp.hasOwnProperty("remainingReceiveEstimatedMillis") && + currOp.remainingReceiveEstimatedMillis instanceof NumberLong, + res); +} + // Validates the fields of an optime object. function checkOptime(optime) { assert(optime.ts instanceof Timestamp); @@ -191,42 +220,35 @@ fpAfterCollectionCloner.off(); // Wait for the "kConsistent" state to be reached. jsTestLog("Waiting for the kConsistent state to be reached."); fpAfterDataConsistent.wait(); +const fpBeforePersistingRejectReadsBeforeTimestamp = configureFailPoint( + recipientPrimary, "fpBeforePersistingRejectReadsBeforeTimestamp", {action: "hang"}); res = recipientPrimary.adminCommand({currentOp: true, desc: "tenant recipient migration"}); checkStandardFieldsOK(res); +checkPostConsistentFieldsOK(res); +currOp = res.inprog[0]; +// State should have changed. +assert.eq(currOp.state, migrationStates.kConsistent, res); +assert.eq(currOp.migrationCompleted, false, res); +assert.eq(currOp.dataSyncCompleted, false, res); +assert(!currOp.hasOwnProperty("expireAt"), res); + +// Wait to receive recipientSyncData with returnAfterReachingDonorTimestamp. +fpAfterDataConsistent.off(); +fpBeforePersistingRejectReadsBeforeTimestamp.wait(); + +res = recipientPrimary.adminCommand({currentOp: true, desc: "tenant recipient migration"}); +checkStandardFieldsOK(res); +checkPostConsistentFieldsOK(res); currOp = res.inprog[0]; // State should have changed. assert.eq(currOp.state, migrationStates.kConsistent, res); assert.eq(currOp.migrationCompleted, false, res); assert.eq(currOp.dataSyncCompleted, false, res); -assert(currOp.hasOwnProperty("startFetchingDonorOpTime") && - checkOptime(currOp.startFetchingDonorOpTime), - res); -assert(currOp.hasOwnProperty("startApplyingDonorOpTime") && - checkOptime(currOp.startApplyingDonorOpTime), - res); -assert(currOp.hasOwnProperty("dataConsistentStopDonorOpTime") && - checkOptime(currOp.dataConsistentStopDonorOpTime), - res); -assert(currOp.hasOwnProperty("cloneFinishedRecipientOpTime") && - checkOptime(currOp.cloneFinishedRecipientOpTime), - res); -assert(currOp.hasOwnProperty("approxTotalDataSize") && - currOp.approxTotalDataSize instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("approxTotalBytesCopied") && - currOp.approxTotalBytesCopied instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("totalReceiveElapsedMillis") && - currOp.totalReceiveElapsedMillis instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("remainingReceiveEstimatedMillis") && - currOp.remainingReceiveEstimatedMillis instanceof NumberLong, - res); assert(!currOp.hasOwnProperty("expireAt"), res); // The oplog applier should have applied at least the noop resume token. assert.gte(currOp.numOpsApplied, 1, tojson(res)); -fpAfterDataConsistent.off(); +fpBeforePersistingRejectReadsBeforeTimestamp.off(); jsTestLog("Waiting for migration to complete."); TenantMigrationTest.assertCommitted(tenantMigrationTest.waitForMigrationToComplete(migrationOpts)); @@ -244,35 +266,12 @@ fpAfterForgetMigration.wait(); res = recipientPrimary.adminCommand({currentOp: true, desc: "tenant recipient migration"}); checkStandardFieldsOK(res); +checkPostConsistentFieldsOK(res); currOp = res.inprog[0]; assert.eq(currOp.state, migrationStates.kConsistent, res); assert.eq(currOp.migrationCompleted, false, res); // dataSyncCompleted should have changed. assert.eq(currOp.dataSyncCompleted, true, res); -assert(currOp.hasOwnProperty("startFetchingDonorOpTime") && - checkOptime(currOp.startFetchingDonorOpTime), - res); -assert(currOp.hasOwnProperty("startApplyingDonorOpTime") && - checkOptime(currOp.startApplyingDonorOpTime), - res); -assert(currOp.hasOwnProperty("dataConsistentStopDonorOpTime") && - checkOptime(currOp.dataConsistentStopDonorOpTime), - res); -assert(currOp.hasOwnProperty("cloneFinishedRecipientOpTime") && - checkOptime(currOp.cloneFinishedRecipientOpTime), - res); -assert(currOp.hasOwnProperty("approxTotalDataSize") && - currOp.approxTotalDataSize instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("approxTotalBytesCopied") && - currOp.approxTotalBytesCopied instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("totalReceiveElapsedMillis") && - currOp.totalReceiveElapsedMillis instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("remainingReceiveEstimatedMillis") && - currOp.remainingReceiveEstimatedMillis instanceof NumberLong, - res); assert(!currOp.hasOwnProperty("expireAt"), res); jsTestLog("Allow the forgetMigration to complete."); @@ -281,32 +280,9 @@ assert.commandWorked(forgetMigrationThread.returnData()); res = recipientPrimary.adminCommand({currentOp: true, desc: "tenant recipient migration"}); checkStandardFieldsOK(res); +checkPostConsistentFieldsOK(res); currOp = res.inprog[0]; assert.eq(currOp.dataSyncCompleted, true, res); -assert(currOp.hasOwnProperty("startFetchingDonorOpTime") && - checkOptime(currOp.startFetchingDonorOpTime), - res); -assert(currOp.hasOwnProperty("startApplyingDonorOpTime") && - checkOptime(currOp.startApplyingDonorOpTime), - res); -assert(currOp.hasOwnProperty("dataConsistentStopDonorOpTime") && - checkOptime(currOp.dataConsistentStopDonorOpTime), - res); -assert(currOp.hasOwnProperty("cloneFinishedRecipientOpTime") && - checkOptime(currOp.cloneFinishedRecipientOpTime), - res); -assert(currOp.hasOwnProperty("approxTotalDataSize") && - currOp.approxTotalDataSize instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("approxTotalBytesCopied") && - currOp.approxTotalBytesCopied instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("totalReceiveElapsedMillis") && - currOp.totalReceiveElapsedMillis instanceof NumberLong, - res); -assert(currOp.hasOwnProperty("remainingReceiveEstimatedMillis") && - currOp.remainingReceiveEstimatedMillis instanceof NumberLong, - res); // State, completion status and expireAt should have changed. assert.eq(currOp.state, migrationStates.kDone, res); assert.eq(currOp.migrationCompleted, true, res); |