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
|
/**
* Tests that a tenant migration recipient instance shows up as active in serverStatus metrics until
* it has directly deleted its state doc (even if the state doc has actually already been deleted by
* the TTL monitor).
*
* @tags: [
* incompatible_with_macos,
* incompatible_with_windows_tls,
* # Uses pauseTenantMigrationRecipientBeforeDeletingStateDoc failpoint, which was added in 6.2
* requires_fcv_62,
* requires_majority_read_concern,
* requires_persistence,
* serverless,
* ]
*/
import {TenantMigrationTest} from "jstests/replsets/libs/tenant_migration_test.js";
load("jstests/libs/fail_point_util.js");
load("jstests/libs/uuid_util.js");
(() => {
jsTest.log("Test case where the TTL monitor deletes the state doc first");
const tmt = new TenantMigrationTest({name: jsTestName(), quickGarbageCollection: true});
const recipientPrimary = tmt.getRecipientPrimary();
const fp =
configureFailPoint(recipientPrimary, "pauseTenantMigrationRecipientBeforeDeletingStateDoc");
jsTest.log("Confirm serverStatus does not show any active or completed tenant migrations.");
let recipientStats = tmt.getTenantMigrationStats(recipientPrimary);
jsTest.log("recipientStats: " + tojson(recipientStats));
assert.eq(0, recipientStats.currentMigrationsReceiving);
jsTest.log("Start a tenant migration.");
const tenantId = ObjectId().str;
const migrationId = extractUUIDFromObject(UUID());
const migrationOpts = {
migrationIdString: migrationId,
tenantId: tenantId,
recipientConnString: tmt.getRecipientConnString(),
};
TenantMigrationTest.assertCommitted(tmt.runMigration(migrationOpts));
jsTest.log("Wait for the migration to reach the failpoint before deleting the state doc.");
fp.wait();
jsTest.log("Confirm the state doc has been deleted by the TTL monitor");
assert.soon(() => {
return 0 ==
recipientPrimary.getDB("config").getCollection("tenantMigrationRecipients").count();
});
jsTest.log("Confirm the instance still shows up as active in serverStatus.");
recipientStats = tmt.getTenantMigrationStats(recipientPrimary);
jsTest.log("recipientStats: " + tojson(recipientStats));
assert.eq(1, recipientStats.currentMigrationsReceiving);
// TODO (SERVER-61717): Confirm the instance still shows up in the POS map. Currently, the
// instance is removed from the map as soon as its' state doc is deleted by the TTL monitor.
jsTest.log("Turn off the failpoint.");
fp.off();
jsTest.log("Confirm the instance eventually stops showing up as active in serverStatus");
assert.soon(() => {
recipientStats = tmt.getTenantMigrationStats(recipientPrimary);
return 0 == recipientStats.currentMigrationsReceiving;
});
// TODO (SERVER-61717): Confirm the instance eventually stops showing up in the POS map.
tmt.stop();
})();
(() => {
jsTest.log("Test case where the instance deletes the state doc first");
const tmt = new TenantMigrationTest({name: jsTestName(), quickGarbageCollection: true});
const recipientPrimary = tmt.getRecipientPrimary();
jsTest.log("Confirm the TTL index exists");
const listIndexesRes1 = assert.commandWorked(
recipientPrimary.getDB("config").runCommand({listIndexes: "tenantMigrationRecipients"}));
assert(listIndexesRes1.cursor.firstBatch.some(
elem => elem.name === "TenantMigrationRecipientTTLIndex" && elem.key.expireAt === 1));
jsTest.log("Drop the TTL index");
assert.commandWorked(recipientPrimary.getDB("config").runCommand(
{dropIndexes: "tenantMigrationRecipients", index: "TenantMigrationRecipientTTLIndex"}));
jsTest.log("Confirm the TTL index no longer exists");
const listIndexesRes2 = assert.commandWorked(
recipientPrimary.getDB("config").runCommand({listIndexes: "tenantMigrationRecipients"}));
assert(listIndexesRes2.cursor.firstBatch.every(elem => elem.key.expireAt == null));
jsTest.log("Confirm serverStatus does not show any active or completed tenant migrations.");
let recipientStats = tmt.getTenantMigrationStats(recipientPrimary);
jsTest.log("recipientStats: " + tojson(recipientStats));
assert.eq(0, recipientStats.currentMigrationsReceiving);
jsTest.log("Start a tenant migration.");
const tenantId = ObjectId().str;
const migrationId = extractUUIDFromObject(UUID());
const migrationOpts = {
migrationIdString: migrationId,
tenantId: tenantId,
recipientConnString: tmt.getRecipientConnString(),
};
TenantMigrationTest.assertCommitted(tmt.runMigration(migrationOpts));
jsTest.log("Wait for the instance to delete the state doc");
assert.soon(() => {
return 0 ==
recipientPrimary.getDB("config").getCollection("tenantMigrationRecipients").count();
});
jsTest.log("Confirm the instance eventually stops showing up as active in serverStatus");
assert.soon(() => {
recipientStats = tmt.getTenantMigrationStats(recipientPrimary);
return 0 == recipientStats.currentMigrationsReceiving;
});
// TODO (SERVER-61717): Confirm the instance eventually stops showing up in the POS map.
tmt.stop();
})();
|