summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/initial_sync_same_index_spec.js
blob: 5746a6091b3ad2eecec5113a5a946407ed295c5c (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
/**
 * Test that initial sync does not fail if an identical index spec is created, dropped and
 * recreated.
 */

(function() {
"use strict";

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

const testName = "initial_sync_same_index_spec";
const dbName = testName;
const collName = "testcoll";

// Set up a stable two node replica set.
let replTest = new ReplSetTest({
    name: testName,
    nodes: [{}, {rsConfig: {priority: 0, votes: 0}}],
});
replTest.startSet();
replTest.initiateWithHighElectionTimeout();

let primary = replTest.getPrimary();
let secondary = replTest.getSecondary();

let primaryDB = primary.getDB(dbName);
let secondaryDB = secondary.getDB(dbName);

let primaryColl = primaryDB[collName];
let secondaryColl = secondaryDB[collName];

// Insert data into the collection for initial sync to copy.
assert.commandWorked(primaryColl.insert([{_id: 1, a: 1}, {_id: 2, a: 2}]));

// Set WC to 1. The default WC is majority and the replica set will not be able to satisfy majority
// index create/drop later.
assert.commandWorked(primary.adminCommand(
    {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}}));

/**
 * Restart the the secondary with no data in order to provoke an initial sync from the primary.
 * Use startup setParameter to set failpoints to pause the initial sync before indexes are fetched.
 */

const fp = 'hangBeforeClonerStage';
let secondaryStartupParams = {};
secondaryStartupParams['failpoint.' + fp] = tojson({
    mode: 'alwaysOn',
    data: {cloner: "CollectionCloner", stage: "listIndexes", nss: primaryColl.getFullName()}
});

// Only try initial sync once, so any failure syncing indexes will be surfaced.
secondaryStartupParams['numInitialSyncAttempts'] = 1;

const startupOptions = {
    startClean: true,
    setParameter: secondaryStartupParams
};

jsTestLog(
    "Restarting the the secondary with no data in order to provoke an initial sync from the " +
    "primary. Using startup options: " + tojson(startupOptions));
secondary = replTest.restart(secondary, startupOptions);
secondaryDB = secondary.getDB(dbName);
secondaryColl = secondaryDB[collName];

jsTestLog("Waiting for secondary to reach failPoint '" + fp + "'");
assert.commandWorked(secondary.adminCommand(
    {waitForFailPoint: fp, timesEntered: 1, maxTimeMS: kDefaultWaitForFailPointTimeout}));

// Restarting the secondary may have resulted in an election.  Wait until the system stabilizes and
// reaches RS_STARTUP2 state.
replTest.getPrimary();
replTest.waitForState(secondary, ReplSetTest.State.STARTUP_2);

/**
 * Now that the secondary is hanging in initial sync, create, drop and recreate identical indexes to
 * ensure it is correctly handled by initial sync (when the failpoint is removed).
 */

jsTestLog("Creating index on the primary.");
assert.commandWorked(primaryColl.createIndex({a: 1}, {name: "a1"}));

jsTestLog("Dropping index on the primary.");
assert.commandWorked(primaryColl.dropIndex("a1"));

jsTestLog("Recreating index with same spec on the primary.");
assert.commandWorked(primaryColl.createIndex({a: 1}, {name: "a2"}));

jsTestLog("Allowing secondary initial sync to resume.");
assert.commandWorked(
    secondary.adminCommand({configureFailPoint: "hangBeforeClonerStage", mode: 'off'}));

jsTestLog("Waiting for initial sync to complete successfully.");
replTest.waitForState(secondary, ReplSetTest.State.SECONDARY);

replTest.stopSet();
})();