summaryrefslogtreecommitdiff
path: root/jstests/replsets/shard_merge_invalid_options.js
blob: 93e5c2daf96e5a198a186e5cd7fa2878a9f41b82 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
 * Tests that the donorStartMigration and recipientSyncData commands throw when a node has options
 * set that are incompatible with protocol shard merge.
 *
 * @tags: [featureFlagShardMerge]
 * ]
 */

import {
    isShardMergeEnabled,
    kProtocolShardMerge,
    makeMigrationCertificatesForTest,
} from "jstests/replsets/libs/tenant_migration_util.js";

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

function runTest(nodeOptions) {
    const rst = new ReplSetTest({nodes: 1, nodeOptions: nodeOptions});
    rst.startSet();
    rst.initiate();

    // Note: including this explicit early return here due to the fact that multiversion
    // suites will execute this test without featureFlagShardMerge enabled (despite the
    // presence of the featureFlagShardMerge tag above), which means the test will attempt
    // to run a multi-tenant migration and fail.
    if (!isShardMergeEnabled(rst.getPrimary().getDB("admin"))) {
        rst.stopSet();
        jsTestLog("Skipping Shard Merge-specific test");
        return;
    }

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

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

    // Ensure the feature flag is enabled and FCV is latest
    assert(isShardMergeEnabled(adminDB));
    assert.eq(getFCVConstants().latest,
              adminDB.system.version.findOne({_id: 'featureCompatibilityVersion'}).version);

    // Assert that donorStartMigration fails with the expected code
    assert.commandFailedWithCode(
        adminDB.runCommand({
            donorStartMigration: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
            tenantIds: [ObjectId()]
        }),
        ErrorCodes.InvalidOptions,
        "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    // Assert that donorStartMigration fails with the expected code when tenantIds is missing.
    assert.commandFailedWithCode(
        adminDB.runCommand({
            donorStartMigration: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor
        }),
        ErrorCodes.InvalidOptions,
        "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    // Assert that donorStartMigration fails with the expected code when tenantId is provided.
    assert.commandFailedWithCode(
        adminDB.runCommand({
            donorStartMigration: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
            tenantIds: [ObjectId()],
            tenantId: ObjectId().str
        }),
        ErrorCodes.InvalidOptions,
        "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    // Assert that donorStartMigration fails with the expected code when tenantIds is not an
    // ObjectId.
    assert.commandFailedWithCode(
        adminDB.runCommand({
            donorStartMigration: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
            tenantIds: ["admin"]
        }),
        ErrorCodes.BadValue,
        "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    // Assert that donorStartMigration fails with the expected code when one of the tenantIds is
    // empty.
    assert.commandFailedWithCode(
        adminDB.runCommand({
            donorStartMigration: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
            tenantIds: [{}, ObjectId()]
        }),
        ErrorCodes.BadValue,
        "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    // Assert that donorStartMigration fails with the expected code when tenantIds is empty.
    assert.commandFailedWithCode(
        adminDB.runCommand({
            donorStartMigration: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            recipientConnectionString: kDummyConnStr,
            readPreference: readPreference,
            donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
            tenantIds: []
        }),
        ErrorCodes.InvalidOptions,
        "Expected donorStartMigration to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    // Assert that recipientSyncData fails with the expected code
    assert.commandFailedWithCode(
        adminDB.runCommand({
            recipientSyncData: 1,
            protocol: kProtocolShardMerge,
            migrationId: UUID(),
            tenantIds: [ObjectId()],
            donorConnectionString: kDummyConnStr,
            readPreference: readPreference,
            startMigrationDonorTimestamp: Timestamp(1, 1),
            recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor
        }),
        ErrorCodes.InvalidOptions,
        "Expected recipientSyncData to fail when protocol is 'shard merge' and node options " +
            tojson(nodeOptions) + " are set, but did not");

    rst.stopSet();
}

// Shard merge is not allowed when directoryperdb is enabled
runTest({directoryperdb: ""});

// Shard merge is not allowed when directoryForIndexes is enabled
runTest({"wiredTigerDirectoryForIndexes": ""});