summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorMatt Broadstone <mbroadst@mongodb.com>2022-02-04 13:23:59 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-04 13:54:45 +0000
commit2e878f0d1f4234199fe0602878de0ac1ce7aa0cc (patch)
tree727c8804b0c6258af883f87a6a957eb37275da25 /jstests
parent08ca09bda76f5d1082b7d8fea5e874c1113a5542 (diff)
downloadmongo-2e878f0d1f4234199fe0602878de0ac1ce7aa0cc.tar.gz
SERVER-62482 Build recipient connection string from tag/set name
Diffstat (limited to 'jstests')
-rw-r--r--jstests/replsets/shard_split_enabled.js58
-rw-r--r--jstests/replsets/shard_split_test.js94
-rw-r--r--jstests/serverless/libs/basic_serverless_test.js55
3 files changed, 131 insertions, 76 deletions
diff --git a/jstests/replsets/shard_split_enabled.js b/jstests/replsets/shard_split_enabled.js
index ece5f4d2cb1..5047fd8e178 100644
--- a/jstests/replsets/shard_split_enabled.js
+++ b/jstests/replsets/shard_split_enabled.js
@@ -8,44 +8,45 @@
"use strict";
load("jstests/replsets/libs/tenant_migration_util.js");
+load("jstests/serverless/libs/basic_serverless_test.js");
+
+class ShardSplitEnabledTest extends BasicServerlessTest {
+ makeCommitShardSplitCmd() {
+ return {
+ commitShardSplit: 1,
+ tenantIds: ["foo"],
+ migrationId: UUID(),
+ recipientTagName: this.recipientTagName,
+ recipientSetName: this.recipientSetName
+ };
+ }
+
+ makeAbortShardSplitCmd() {
+ return {abortShardSplit: 1, migrationId: UUID()};
+ }
+}
-const kDummyConnStr = "mongodb://localhost/?replicaSet=foo";
function makeShardSplitTest() {
return function(downgradeFCV) {
- function commitShardSplitCmd(recipientConnectionString) {
- return {
- commitShardSplit: 1,
- tenantIds: ["foo"],
- migrationId: UUID(),
- recipientConnectionString
- };
- }
- function abortShardSplitCmd() {
- return {abortShardSplit: 1, migrationId: UUID()};
- }
+ const test = new ShardSplitEnabledTest(
+ {recipientTagName: "recipientNode", recipientSetName: "recipient"});
+ test.addRecipientNodes();
- // start up a replica set for the recipient
- const recipientRst = new ReplSetTest({name: "recipientRst", nodes: 1});
- recipientRst.startSet();
- recipientRst.initiate();
+ const donorPrimary = test.donor.getPrimary();
+ const adminDB = donorPrimary.getDB("admin");
- // start up a replica set
- // server-side setup
- const donorRst = new ReplSetTest({name: "donorRst", nodes: 1});
- donorRst.startSet();
- donorRst.initiate();
- const primary = donorRst.getPrimary();
- const adminDB = primary.getDB("admin");
+ // TODO(SERVER-63091): remove this when we actually split recipients
+ configureFailPoint(adminDB, "skipShardSplitWaitForSplitAcceptance");
assert(TenantMigrationUtil.isShardSplitEnabled(adminDB));
assert.eq(getFCVConstants().latest,
adminDB.system.version.findOne({_id: 'featureCompatibilityVersion'}).version);
- let res = adminDB.runCommand(commitShardSplitCmd(recipientRst.getURL()));
+ let res = adminDB.runCommand(test.makeCommitShardSplitCmd());
assert.neq(res.code,
6057900,
`commitShardSplitCmd shouldn't reject when featureFlagShardSplit is enabled`);
- res = adminDB.runCommand(abortShardSplitCmd());
+ res = adminDB.runCommand(test.makeAbortShardSplitCmd());
assert.neq(res.code,
6057902,
`abortShardSplitCmd shouldn't reject when featureFlagShardSplit is enabled`);
@@ -53,17 +54,16 @@ function makeShardSplitTest() {
assert.commandWorked(adminDB.adminCommand({setFeatureCompatibilityVersion: downgradeFCV}));
assert.commandFailedWithCode(
- adminDB.runCommand(commitShardSplitCmd(recipientRst.getURL())),
+ adminDB.runCommand(test.makeCommitShardSplitCmd()),
6057900,
`commitShardSplitCmd should reject when featureFlagShardSplit is disabled`);
assert.commandFailedWithCode(
- adminDB.runCommand(abortShardSplitCmd()),
+ adminDB.runCommand(test.makeAbortShardSplitCmd()),
6057902,
`abortShardSplitCmd should reject when featureFlagShardSplit is disabled`);
// shut down replica sets
- donorRst.stopSet();
- recipientRst.stopSet();
+ test.stop();
};
}
diff --git a/jstests/replsets/shard_split_test.js b/jstests/replsets/shard_split_test.js
index 902d66a7918..22302965367 100644
--- a/jstests/replsets/shard_split_test.js
+++ b/jstests/replsets/shard_split_test.js
@@ -5,6 +5,7 @@
load("jstests/libs/fail_point_util.js");
load('jstests/libs/parallel_shell_helpers.js');
+load("jstests/serverless/libs/basic_serverless_test.js");
const kMaxTimeMS = 1 * 1000;
@@ -19,16 +20,6 @@ function assertDocumentState(primary, uuid, state) {
assert.eq(migrationDoc.state, state);
}
-function startReplica(name, numNodes) {
- const replTest = new ReplSetTest({name, nodes: numNodes});
-
- jsTestLog("Starting replica set for test");
- const donorNodes = replTest.startSet();
- replTest.initiate();
-
- return replTest;
-}
-
function runAbort() {
"use strict";
@@ -37,21 +28,24 @@ function runAbort() {
// Skip db hash check because secondary is left with a different config.
TestData.skipCheckDBHashes = true;
- const donorSet = startReplica("donorSet", 3);
- const primary = donorSet.getPrimary();
- const adminDb = primary.getDB("admin");
+ const test =
+ new BasicServerlessTest({recipientTagName: "recipientNode", recipientSetName: "recipient"});
+ test.addRecipientNodes();
+
+ const donorPrimary = test.donor.getPrimary();
+ const adminDb = donorPrimary.getDB("admin");
const migrationId = UUID();
jsTestLog("Asserting no state document exist before command");
- assert.isnull(findMigration(primary, migrationId));
+ assert.isnull(findMigration(donorPrimary, migrationId));
jsTestLog("Running abortShardSplit command");
- assert.commandWorked(adminDb.runCommand({abortShardSplit: 1, migrationId: migrationId}));
+ assert.commandWorked(adminDb.runCommand({abortShardSplit: 1, migrationId}));
jsTestLog("Asserting state document exist after command");
- assertDocumentState(primary, migrationId, "aborted");
+ assertDocumentState(donorPrimary, migrationId, "aborted");
- donorSet.stopSet();
+ test.stop();
}
function runBlocking() {
@@ -62,65 +56,71 @@ function runBlocking() {
// Skip db hash check because secondary is left with a different config.
TestData.skipCheckDBHashes = true;
- const donorSet = startReplica("donorSet", 3);
- const recipientSet = startReplica("recipientSet", 3);
- const primary = donorSet.getPrimary();
- const adminDb = primary.getDB("admin");
- const migrationId = UUID();
+ const test =
+ new BasicServerlessTest({recipientTagName: "recipientNode", recipientSetName: "recipient"});
+ test.addRecipientNodes();
- const tenantId1 = "test_tenant_1";
- const tenantId2 = "test_tenant_2";
- const tenants = [tenantId1, tenantId2];
+ const donorPrimary = test.donor.getPrimary();
+ const migrationId = UUID();
+ const tenantIds = ["test_tenant_1", "test_tenant_2"];
jsTestLog("Asserting no state document exist before command");
- assert.isnull(findMigration(primary, migrationId));
+ assert.isnull(findMigration(donorPrimary, migrationId));
jsTestLog("Asserting we can write before the migration");
- tenants.forEach(id => {
- const tenantDB = primary.getDB(id + "_data");
+ tenantIds.forEach(id => {
+ const tenantDB = donorPrimary.getDB(id + "_data");
let insertedObj = {name: id + "1", payload: "testing_data"};
assert.commandWorked(tenantDB.runCommand(
{insert: "testing_collection", documents: [insertedObj], maxTimeMS: kMaxTimeMS}));
});
- jsTestLog("Inserting failpoint after blocking");
- let blockingFailPoint = configureFailPoint(adminDb, "pauseShardSplitAfterBlocking");
+ // configure failpoints
+ const adminDb = donorPrimary.getDB("admin");
+ const blockingFailPoint = configureFailPoint(adminDb, "pauseShardSplitAfterBlocking");
+
+ // TODO(SERVER-63091): remove this when we actually split recipients
+ configureFailPoint(adminDb, "skipShardSplitWaitForSplitAcceptance");
jsTestLog("Running commitShardSplit command");
const awaitCommand = startParallelShell(
- funWithArgs(function(migrationId, url, tenants) {
- assert.commandWorked(db.adminCommand({
- commitShardSplit: 1,
- migrationId: migrationId,
- recipientConnectionString: url,
- "tenantIds": tenants
- }));
- }, migrationId, recipientSet.getURL(), [tenantId1, tenantId2]), donorSet.getPrimary().port);
+ funWithArgs(
+ function(migrationId, recipientTagName, recipientSetName, tenantIds) {
+ assert.commandWorked(db.adminCommand({
+ commitShardSplit: 1,
+ migrationId,
+ recipientTagName,
+ recipientSetName,
+ tenantIds
+ }));
+ },
+ migrationId,
+ test.recipientTagName,
+ test.recipientSetName,
+ tenantIds),
+ donorPrimary.port);
blockingFailPoint.wait();
jsTestLog("Asserting state document is in blocking state");
- assertDocumentState(primary, migrationId, "blocking");
+ assertDocumentState(donorPrimary, migrationId, "blocking");
jsTestLog("Asserting we cannot write in blocking state");
- tenants.forEach(id => {
- const tenantDB = primary.getDB(id + "_data");
+ tenantIds.forEach(id => {
+ const tenantDB = donorPrimary.getDB(id + "_data");
let insertedObj = {name: id + "2", payload: "testing_data2"};
let res = tenantDB.runCommand(
{insert: "testing_collection", documents: [insertedObj], maxTimeMS: kMaxTimeMS});
assert.commandFailedWithCode(res, ErrorCodes.MaxTimeMSExpired);
});
+ jsTestLog("Disabling failpoints and waiting for command to complete");
blockingFailPoint.off();
awaitCommand();
jsTestLog("Asserting state document exist after command");
- assertDocumentState(primary, migrationId, "committed");
-
- // If we validate, it will try to list all collections and the migrated collections will return
- // a TenantMigrationCommitted error.
- donorSet.stopSet(undefined /* signal */, false /* forRestart */, {skipValidation: 1});
- recipientSet.stopSet();
+ assertDocumentState(donorPrimary, migrationId, "committed");
+ test.stop();
}
runAbort();
diff --git a/jstests/serverless/libs/basic_serverless_test.js b/jstests/serverless/libs/basic_serverless_test.js
new file mode 100644
index 00000000000..b19c95ec0cb
--- /dev/null
+++ b/jstests/serverless/libs/basic_serverless_test.js
@@ -0,0 +1,55 @@
+class BasicServerlessTest {
+ constructor({recipientTagName, recipientSetName}) {
+ this.donor = new ReplSetTest({name: "donor", nodes: 3});
+ this.donor.startSet();
+ this.donor.initiate();
+
+ this.recipientTagName = recipientTagName;
+ this.recipientSetName = recipientSetName;
+ this.recipientNodes = [];
+ }
+
+ stop() {
+ // If we validate, it will try to list all collections and the migrated collections will
+ // return a TenantMigrationCommitted error.
+ this.donor.stopSet(undefined /* signal */, false /* forRestart */, {skipValidation: 1});
+ }
+
+ addRecipientNodes(numNodes) {
+ numNodes = numNodes || 3; // default to three nodes
+
+ if (this.recipientNodes.lengh > 0) {
+ throw new Error("Recipient nodes may only be added once");
+ }
+
+ jsTestLog(`Adding ${numNodes} non-voting recipient nodes to donor`);
+ const donor = this.donor;
+ for (let i = 0; i < numNodes; ++i) {
+ this.recipientNodes.push(donor.add());
+ }
+
+ const primary = donor.getPrimary();
+ const admin = primary.getDB('admin');
+ const config = donor.getReplSetConfigFromNode();
+ config.version++;
+
+ // ensure recipient nodes are added as non-voting members
+ this.recipientNodes.forEach(node => {
+ config.members.push({
+ host: node.host,
+ votes: 0,
+ priority: 0,
+ tags: {[this.recipientTagName]: ObjectId().valueOf()}
+ });
+ });
+
+ // reindex all members from 0
+ config.members = config.members.map((member, idx) => {
+ member._id = idx;
+ return member;
+ });
+
+ assert.commandWorked(admin.runCommand({replSetReconfig: config}));
+ this.recipientNodes.forEach(node => donor.waitForState(node, ReplSetTest.State.SECONDARY));
+ }
+}