summaryrefslogtreecommitdiff
path: root/jstests/replsets/shard_merge_enabled.js
blob: 0235f79ea00272e8a281b47dedbd8846dc75d12f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
 * Tests that the "shard merge" protocol is enabled only in the proper FCV.
 * @tags: [requires_fcv_52, featureFlagShardMerge]
 */

(function() {
"use strict";

load("jstests/replsets/libs/tenant_migration_util.js");
load("jstests/libs/fail_point_util.js");

function runTest(downgradeFCV) {
    let rst = new ReplSetTest({nodes: 1});
    rst.startSet();
    rst.initiate();

    let primary = rst.getPrimary();
    let adminDB = primary.getDB("admin");
    const kDummyConnStr = "mongodb://localhost/?replicaSet=foo";
    const readPreference = {mode: 'primary'};
    const migrationCertificates = TenantMigrationUtil.makeMigrationCertificatesForTest();

    // A function, not a constant, to ensure unique UUIDs.
    function donorStartMigrationCmd() {
        return {
            donorStartMigration: 1,
            protocol: "shard merge",
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor
        };
    }

    function recipientSyncDataCmd() {
        return {
            recipientSyncData: 1,
            protocol: "shard merge",
            migrationId: UUID(),
            donorConnectionString: kDummyConnStr,
            readPreference: readPreference,
            startMigrationDonorTimestamp: Timestamp(1, 1),
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor
        };
    }

    function recipientForgetMigrationCmd() {
        return {
            recipientForgetMigration: 1,
            protocol: "shard merge",
            migrationId: UUID(),
            donorConnectionString: kDummyConnStr,
            readPreference: readPreference,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor
        };
    }

    function func(cmd) {
        return eval(cmd + "Cmd()");
    }

    function upgradeTest(cmd) {
        let msg = cmd + " shouldn't reject 'shard merge' protocol when it's enabled";
        assert.commandWorked(adminDB.runCommand(func(cmd)), msg);
    }

    function downgradeTest(cmd) {
        let msg = cmd + " should reject 'shard merge' protocol when it's disabled";
        let expectedErrorMsg = "'protocol' field is not supported for FCV below 5.2'";
        let response = assert.commandFailedWithCode(
            adminDB.runCommand(func(cmd)), ErrorCodes.InvalidOptions, msg);
        assert.neq(-1,
                   response.errmsg.indexOf(expectedErrorMsg),
                   "Error message did not contain '" + expectedErrorMsg + "', found:\n" +
                       tojson(response));
    }

    // Enable below fail points to prevent starting the donor/recipient POS instance.
    configureFailPoint(primary, "returnResponseCommittedForDonorStartMigrationCmd");
    configureFailPoint(primary, "returnResponseOkForRecipientSyncDataCmd");
    configureFailPoint(primary, "returnResponseOkForRecipientForgetMigrationCmd");

    // Preconditions: the shard merge feature is enabled and our fresh RS is on the latest FCV.
    assert(TenantMigrationUtil.isShardMergeEnabled(adminDB));
    assert.eq(getFCVConstants().latest,
              adminDB.system.version.findOne({_id: 'featureCompatibilityVersion'}).version);

    // Shard merge is enabled, so this call should work.
    let cmds = ["donorStartMigration", "recipientSyncData", "recipientForgetMigration"];
    cmds.forEach((cmd) => {
        upgradeTest(cmd);
    });

    assert.commandWorked(adminDB.adminCommand({setFeatureCompatibilityVersion: downgradeFCV}));

    // Now that FCV is downgraded, shard merge is automatically disabled.
    cmds.forEach((cmd) => {
        downgradeTest(cmd);
    });

    rst.stopSet();
}

runFeatureFlagMultiversionTest('featureFlagShardMerge', runTest);
})();